Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • pmrust/pmrust.pages.upb.ro
  • genan.omer/pmrust.pages.upb.ro
  • vladut.chintoiu/pmrust.pages.upb.ro
  • petru.nania/website-pmrust-fork
  • sofia.huzan/pmrust.pages.upb.ro
  • ionut.pruteanu2308/arcade-game
  • luana.militaru/pong-game
  • sebastian.scrob/project
  • matei.bejinaru/website-bejinaru-matei
  • adragomir2806/website-dragomir-alexandru
  • fatemehsadat/pmrust.pages.upb.ro
  • razvan.costea2205/pmrust.pages.upb.ro
  • darius_gabriel.iuga/pm-website
  • andrei.neagu1910/pmrust.pages.upb.ro
  • irina.chiorean/pmrust.pages.upb.ro
  • adrian_costin.lungu/pmrust.pages.upb.ro
  • andrei.salavastru/pmrust.pages.upb.ro
  • maria_elena.tudor/pmrust.pages.upb.ro
  • vlad.preda2503/electric-piano
  • delia_alexa.dragan/website-music-player
  • francisc.niss/automatic-guitar-tuner
  • mihnea.sandulache/pmrust.pages.upb.ro
  • dragos_andrei.rosu/pmrust.pages.upb.ro
  • armin.shafiei/the-tone-corrector
  • vladyslav.kiselar/pmrust.pages.upb.ro
  • carla_maria.rusu/pmrust.pages.upb.ro
  • razvan.beldie/pmrust.pages.upb.ro
27 results
Show changes
website/lab/04/images/board_buzzer.png

191 KiB

website/lab/04/images/buzzer.png

107 KiB

website/lab/04/images/potentiometer_pins.png

62.3 KiB

---
description: Asynchronous Programming with Embassy
slug: /lab/04
unlisted: true
---
# 04 - Asynchronous Development
......@@ -14,23 +13,61 @@ This lab will teach you the principles of asynchronous programming, and its appl
1. **Bert Peters**, *[How does async Rust work](https://bertptrs.nl/2023/04/27/how-does-async-rust-work.html)*
2. **Omar Hiari**, *[Sharing Data Among Tasks in Rust Embassy: Synchronization Primitives](https://dev.to/apollolabsbin/sharing-data-among-tasks-in-rust-embassy-synchronization-primitives-59hk)*
## Asynchronous functions
## Asynchronous functions and Tasks
Up to now, during the labs, we've seen that, in order to be able to do multiple different actions "at once", we would use *tasks*. We would let the `main` function run, while also doing another action seemingly "in parallel" inside of another task.
Let's take the following example: if we want to blink an LED every second while also waiting for a button press to do something else, we would need to spawn a new task in which we would wait for the button press, while blinking the LED in the `main` function.
Until now you've only worked with simple (almost) serial programs. However, not all programs can be designed to run serially/sequentially. Handling multiple I/O events concurrently usually requires separate parallel tasks.
Example: Reading a button press while blinking an LED. A single loop would block the button reading event while waiting for the timer to finish.
```mermaid
sequenceDiagram
participant Button as Button
participant Timer as Timer
participant Task as Main Task (LED + Button)
participant LED as LED Control
loop
%% LED starts blinking
Task->>LED: Turn LED ON
Timer->>+Task: Delay 1 sec (Blocks everything)
%% Button presses button during delay
Button-->>Task: Button Press Sent (but microcontroller is busy)
Task->>-Task: Continue with next instruction
%% LED continues
Task->>LED: Turn LED OFF
Timer->>+Task: Delay 1 sec (Blocks everything)
Button-->>Task:Button Press Sent (but microcontroller is busy)
Task->>-Task: Continue with next instruction
%% Now the task checks the button, but it's too late
Task->>Button: Check if button is pressed
Button-->>Task: No press detected (press was missed)
end
Note over Button, Button: User pressed button, but MCU was busy!
Note over Task: Button check happens too late.
When thinking of how exactly this works, you would probably think that the task is running on a separate *thread* than the `main` function. Usually this would be the case when developing a normal computer application. Multithreading is possible, but requires a preemptive operating system. Without one, only one thread can independently run per processor core and that means that, since we are using only one core of the RP2040 (which actually has only 2), we would only be able to run **one thread at a time**. So how exactly does the task wait for the button press in parallel with the LED blinking?
Short answer is: it doesn't. In reality, both functions run asynchronously.
### Tasks
```
To address this issue, we would need to spawn a new task in which we would wait for the button press, while blinking the LED in the `main` function.
When thinking of how exactly this works, you would probably think that the task is running on a separate *thread* than the `main` function. Usually this would be the case when developing a normal computer application. Multithreading is possible, but requires a preemptive operating system. Without one, only one thread can independently run per processor core and that means that, since we are using only one core of the RP2350 (which actually has only 2), we would only be able to run **one thread at a time**. So how exactly does the task wait for the button press in parallel with the LED blinking?
Short answer is: it doesn't. In reality, both functions run asynchronously.
A task in Embassy is represented by an *asynchronous function*. Asynchronous functions are different from normal functions, in the sense that they allow asynchronous code execution. Let's take an example from the previous lab:
```rust
#[embassy_executor::task]
async fn button_pressed(mut led: Output<'static, PIN_X>, mut button: Input<'static, PIN_X>) {
async fn button_pressed(mut led: Output<'static>, mut button: Input<'static>) {
loop {
info!("waiting for button press");
button.wait_for_falling_edge().await;
led.toggle();
}
}
......@@ -38,7 +75,7 @@ async fn button_pressed(mut led: Output<'static, PIN_X>, mut button: Input<'stat
async fn main(spawner: Spawner) {
let peripherals = embassy_rp::init(Default::default());
let button = Input::new(peripherals.PIN_X, Pull::Up);
let button = Input::new(peripherals.PIN_X, Pull::None);
let led2 = Output::new(peripherals.PIN_X, Level::Low);
spawner.spawn(button_pressed(led2, button)).unwrap();
......@@ -196,7 +233,7 @@ let (res1, res2) = join(button.wait_for_falling_edge(), Timer::after_secs(5)).aw
`join` returns a tuple containing the results of both `Future`s.
## Channels
## Channel
Up to this point, to be able to share peripherals or data across multiple tasks, we have been using global `Mutex`s or passing them directly as parameters to the tasks. But there are other, more convenient ways to send data to and from tasks. Instead of having to make global, static variables that are shared by tasks, we could choose to only send the information that we need from one task to another. To achieve this, we can use *channels*.
......@@ -248,107 +285,169 @@ that the value cannot be modified concurrently by two different tasks, or use ch
To better understand the concepts of ownership and borrowing in Rust, take a look at [chapter 4](https://doc.rust-lang.org/book/ch04-00-understanding-ownership.html) of the Rust Book.
:::
## Potentiometer
### `Signal`
A potentiometer is a three-terminal resistor with a sliding or rotating contact that forms an adjustable voltage divider. If only two terminals are used, one end and the wiper, it acts as a variable resistor or rheostat. A volume knob on a speaker is a potentiometer, for instance.
This is similar to a `Channel` with a buffer size of 1, except “sending” to it (calling `Signal::signal`) when full will overwrite the previous value instead of waiting for the receiver to pop the previous value.
![Potentiometer](images/potentiometer_pins.png)
It is useful for sending data between tasks when the receiver only cares about the latest data, and therefore it's fine to “lose” messages. This is often the case for “state” updates.
## Exercises
![Pico Explorer Pinout](../images/explorer_pins.jpg)
```rust
1. Connect an LED to GP0, an RGB LED to GP1, GP2, GP5 and a potentiometer to ADC0. Use Kicad to draw the schematic. (**1p**)
2. Change the monochromatic LED's intensity, using button A (SW_A) and button B(SW_B) on the Pico Explorer. Button A will increase the intensity, and button B will decrease it. (**2p**)
use embassy_sync::signal::Signal;
:::tip
- Use PWM to control the intensity.
- Create two tasks, one for button A, one for button B. Use a channel to send commands from each button task to the main task.
:::
static SIG: Signal<CriticalSectionRawMutex, ()> = Signal::new();
3. Control the RGB LED's color with buttons A, B, X and Y on the Pico Explorer. (**2p**)
- Button A -> RGB = Red
- Button B -> RGB = Green
- Button X -> RGB = Blue
- Button Y -> RGB = Led Off
:::tip
Use a separate task for each button. When a button press is detected, a command will be sent to the main task, and the main task will set the RGB LED's color according to that command.
#[embassy_executor::task]
async fn waiter() {
SIG.wait().await; // Wait until signaled
defmt::info!("Signal received!");
}
#[embassy_executor::task]
async fn trigger() {
SIG.signal(()); // Notify the waiting task
}
:::warning
When building Rust software in *debug mode*, which is what `cargo build` does, Rust will panic if mathematical operations underflow or overflow. This means that:
```rust
let v = 10u8;
v -= 12;
```
will panic. To avoid this, you can use the [`wrapping_`](https://doc.rust-lang.org/std/primitive.u8.html#method.wrapping_add) and [`saturating_`](https://doc.rust-lang.org/std/primitive.u8.html#method.saturating_add) functions:
### `PubSubChannel`
```rust
let v = 10u8;
// this will store 0 in v
v = v.saturating_sub(12);
```
:::
This is a type of channel where any published message can be read by all subscribers. A publisher can choose how it sends its message.
```mermaid
sequenceDiagram
autonumber
note right of TaskBtnA: waits for button A press
note right of TaskBtnB: waits for button B press
note right of TaskBtnX: waits for button X press
note right of TaskBtnY: waits for button Y press
note right of TaskMain: waits for LED command
Hardware-->>TaskBtnA: button A press
TaskBtnA-->>TaskMain: LedCommand(LedColor::Red)
note right of TaskMain: sets PWM configuration
TaskMain-->>Hardware: sets RGB LED color RED
Hardware-->>TaskBtnX: button X press
TaskBtnX-->>TaskMain: LedCommand(LedColor::Blue)
note right of TaskMain: sets PWM configuration
TaskMain-->>Hardware: sets RGB LED color BLUE
```
:::
- With Pub::publish() the publisher has to wait until there is space in the internal message queue.
- With Pub::publish_immediate() the publisher doesn't await and instead lets the oldest message in the queue drop if necessary. This will cause any Subscriber that missed the message to receive an error to indicate that it has lagged.
4. In addition to the four buttons, control the RGB LED's intensity with the potentiometer. (**3p**)
Example:
:::tip
You will need another task in which you sample the ADC and send the values over a channel.
You could do this in one of two ways:
1. Use a single channel for both changing the color and the intensity of the LED. Button tasks and the potentiometer task will send over the same channel. For this, you will need to change the type of data that is sent over the channel to encapsulate both types of commands. For example, you could use an enum like this:
```rust
enum LedCommand {
ChangeColor(Option<LedColor>),
ChangeIntensity(u16)
use embassy_sync::pubsub::PubSubChannel;
static PUB: PubSubChannel<CriticalSectionRawMutex, &'static str, 4, 2> = PubSubChannel::new();
#[embassy_executor::task]
async fn publisher() {
PUB.publisher().publish("Hello").await;
}
```
2. Use two separate channels, one for sending the color command (which contains the LedColor), and one for sending the intensity. You can `await` both channel `receive()` futures inside of a `select` to see which command is received first, and handle it.
Example:
```rust
let select = select(COLOR_CHANNEL.receive(), INTENSITY_CHANNEL.receive()).await;
match select {
First(color) => {
// ...
},
Second(intensity) => {
// ...
}
#[embassy_executor::task]
async fn subscriber1() {
let mut sub = PUB.subscriber().unwrap();
let msg = sub.next_message().await;
defmt::info!("Sub 1 got: {}", msg);
}
#[embassy_executor::task]
async fn subscriber2() {
let mut sub = PUB.subscriber().unwrap();
let msg = sub.next_message().await;
defmt::info!("Sub 2 got: {}", msg);
}
```
:::
5. Print to the screen of the Pico Explorer the color of the RGB LED and its intensity. Use the SPI screen driver provided in the lab skeleton. (**2p**)
## Buzzer
A buzzer is a hardware device that emits sound. There are two types of buzzers:
- *active buzzer* - connected to VCC and GND, with a resistance - emits a constant frequency
- *passive buzzer* - connected to a GPIO pin and GND, with a resistance - frequency can be controlled through the pin with PWM
![Buzzer](images/buzzer.png)
:::tip
To write to the screen, use this example:
```rust
let mut text = String::<64>::new();
write!(text, "Screen print: ", led_color).unwrap(); // led_color must be defined first
To control the buzzer, all you need to do is to set the `top` value of the PWM config to match the frequency you want!
:::
#### How to wire an RGB LED
The buzzer on the development board is connected to a pin in the J9 block.
![board_buzzer](./images/board_buzzer.png)
## Exercises
Text::new(&text, Point::new(40, 110), style)
.draw(&mut display)
.unwrap();
1. Use two separate tasks to make the RED LED and BLUE LED blink 1 time per second. Instead of using `Timer::after_millis(time_interval).await` use *busy waiting* by starting a timer using `Instant::now();` and checking the elapsed time in a `while` loop using
// Small delay for yielding
Timer::after_millis(1).await;
```rust
while start_time.elapsed().as_millis() < time_interval {}
```
You should notice that one of the tasks is not running. Why? (**1p**)
:::tip
Use a different task instance for each LED. You can spawn multiple instances of the same task, however you need to specify the pool size with `#[embassy_executor::task(pool_size = 2)]`. Take a look at [task-arena](https://docs.embassy.dev/embassy-executor/git/std/index.html#task-arena) for more info.
Use [`AnyPin`](https://docs.embassy.dev/embassy-rp/git/rp2040/gpio/struct.AnyPin.html) and blinking frequency parameters for the task.
:::
2. Fix the usage of busy waiting from exercise 1 and make the 4 LEDs (YELLOW, RED, GREEN, BLUE) blink at different frequencies. (**1p**)
Blink:
| LED | frequency |
|-|-|
| YELLOW | 3 Hz |
| RED | 4 Hz |
| GREEN | 5 Hz |
| BLUE | 1 Hz |
:::tip
1 Hz means once per second.
:::
3. Write a firmware that changes the RED LED's intensity, using switch **SW_4** and switch **SW_5**. Switch **SW_4** will increase the intensity, and switch **SW_5** will decrease it. You will implement this in three ways: (**3p**)
1. Use three tasks : `main` to control the LED and another two for each button (one for switch **SW_4**, one for switch **SW_5**). Use a [`Channel`](#channel) to send commands from each button task to the main task.
:::tip
Use an `enum` to define the LED Intensity change command for point i.
:::
2. Use a single task (`main`). Use [`select`](#select) to check which of the buttons were pressed and change the LED intensity accordingly.
3. Use two tasks: `main` to control the LED and another one for both buttons. Use a [`Signal`](#signal) channel to transmit from the buttons task, the new value of the intensity which the LED will be set to. The `main` will wait for a new value on the `Signal` channel and change the intensity accordingly.
:::tip
Instead of sending commands over the channel like you did at point i, send the intensity value as a number.
:::
4. Simulates a traffic light using the GREEN, YELLOW and RED LEDs on the board. Normally the traffic light goes from one state based on the time elapsed (Green -> 5s , Yellow Blink (4 times) -> 1s , Red -> 2s ).
However if the switch **SW4** is pressed the state of traffic light changes immediately as shown in the diagram bellow.(**2p**)
```mermaid
flowchart LR
green(GREEN) -- Button pressed --> yellow(Yellow)
green(GREEN) -- 5s --> yellow(Yellow)
yellow(YELLOW - Blink 4 times/second) -- Button pressed --> red(RED)
yellow(YELLOW - Blink 4 times/second) -- 1s --> red(RED)
red(RED) -- Button pressed --> red(RED)
red(RED) -- 2s --> green(GREEN)
classDef red fill:#ff0000,stroke:#000000,color: #ffffff
classDef yellow fill:#efa200,stroke:#000000
classDef green fill:#00ce54,stroke:#000000
class red red
class yellow yellow
class green green
```
:::tip
For this exercise you only need one task. Define an `enum` to save the traffic light state (`Green`, `Yellow`,`Red`). Use `match` to check the current state of the traffic light. Then you need to wait for two futures, since the traffic light changes its color either because some time has elapsed or because the button was pressed. Use `select` to check which future completes first (`Timer` or button press).
:::
5. Continue exercise 4: this time, if switch **SW4** and switch **SW7** are pressed consecutively, change the state of the traffic light. Use `join` to check that both switches were pressed. (**1p**)
:::note
The switches don't need to be pressed at the same time, but one after the other. The order does not matter.
:::
6. Continue exercise 5:
- add a new task to control the buzzer. The buzzer should make a continuous low frequency (200Hz) sound while the traffic light is green or yellow and should start beeping (at 400Hz) on and off while the traffic light is red (Use the [formula from Lab03](./03#calculating-the-top-value) to calculate the frequency) . (**1p**)
- add a new task for a servo motor. Set the motor position at 180° when the light is green, 90° the light is yellow, and 0° if its red. (**1p**)
:::tip
Use a `PubSubChannel` to transmit the state of the traffic light from the LEDs task to both the buzzer and the servo motor tasks.
:::
......@@ -4,35 +4,89 @@ sidebar_position: 1
# Description
The purpose of the project is to build a hardware device that runs software written in Rust.
The goal of the project is to showcase the knowledge gained throughout the semester by creating functional hardware that runs software written in Rust.
## Deliverables
All the deliverables will be published in a GitHub repository that each student will be assigned to.
The repository contains:
- documentation - the reposiotry's `README.md` file
- short description of functionality
- requirements (hardware and software)
- hardware design - use [KiCad EDA](https://www.kicad.org/) or a similar tool for the schematics
The deliverables will be stored in two places:
- the *source code* will be stored on [Github](https://github.com/UPB-PMRust-Students)
- the project documentation will be stored on [Gitlab](https://gitlab.cs.pub.ro/pmrust/pmrust.pages.upb.ro), by creating a fork of the course's website
The **documentation repository** should contain:
- the full documentation of the project, in the `index.md` file
- a description of the functionality
- the motivation for choosing the project
- the architecture
- a description of all components and how they interconnect
- a diagram drawn in [diagrams.net](https://app.diagrams.net/) or similar
- a weekly log of the project status
- hardware design
- a description of the hardware used
- a schematic drawn in [KiCad EDA](https://www.kicad.org/) or similar
- photos of the device
- software design
- detail design
- detailed design
- functional diagram
- bill of materials (hardware and software)
- the photos and other files required by the index.md file
:::warning
You need to work in a fork of this website's Gitlab repository and not in a blank one, in order to create a _merge request_, as described below.
:::
The **source code repository** should contain:
- a brief documentation - the repository's `README.md` file
- short description of the functionality
- requirements (hardware and software)
- brief hardware and software design, including diagrams
- software source code
Students will have to build and showcase the hardware with the running software at PM Fair.
The repositories will be checked by the lab assistant at during lab reserved for the project. Uploading code on the last day of the software milestone is not allowed. **The assistant** will check that students have **submitted regular commits** to the repository.
Students will have to build and showcase the hardware with the running software at PM Fair. On the presentation day, **students will upload the source code to the hardware** and the demo will be done live in front of the committee.
## How to create a page for your project?
1. Please login with your UPB login to [Gitlab](https://gitlab.cs.pub.ro)
2. You will have to add an SSH Key to your Gitlab account. This will allow you to push code without entering you username and password every time. For this, run the following command in the Windows/Linux/macOS's console: `ssh-keygen -t rsa -b 2048`. Press press ENTER until you exit the respective command prompts.
- If your command prompt `Overwrite (y/n)?` press `n` and run the above command again, changing the destination of the key.
- If the key was generated successfully, you will have the keys generated in the location indicated by the command `Enter file in which to save the key (C:\Users\"NAME"/.ssh/id_rsa):`
- Read the content of the file `id_rsa.pub` or the name you gave to the file and transfer it to Github.
- Login to [Gitlab](https://gitlab.cs.pub.ro/) and go to: [SSH Keys](https://gitlab.cs.pub.ro/-/user_settings/ssh_keys).
- Click on *Add new key* and insert into the *Key* textbox your key from `id_rsa.pub`.
- Be very careful about the expiration date of the ssh key, change the expiration date otherwise it is set to 30 days.
3. [Download Git](https://git-scm.com) from the official website and access it in the command line using `git -v` to check if it was installed correctly. You might have to use *Git Bash*.
4. Navigate to the [website's Gitlab repository](https://gitlab.cs.pub.ro/pmrust/pmrust.pages.upb.ro) and create a public fork by clicking on the button in the top right corner.
5. Clone the newly created repository by running `git clone git@gitlab.cs.pub.ro:<gitlab_username>/pmrust.pages.upb.ro.git`, where `<gitlab_username>` is replaced by your gitlab username.
6. Now you have your own clone. You need to create a new branch. For this, follow the steps:
- Run the command: `git fetch` followed by the `git pull` command
- The branches have the following naming convention: `project/your_curs.upb.ro_username`. Example: `project/andrei_paul.zamfir`
- To create a new branch:
- `git checkout -b <branch_name>`
- `git push --set-upstream origin project/your_curs.upb.ro_username`
7. To start creating your page for the project, go to `website/versioned_docs/version-acs_cc/project/2025` and create a new directory with your curs.upb.ro username. Example: `andrei_paul.zamfir`.
8. In that directory you must create a file named `index.md` which will be your project page. You can take a look at the [Markdown](https://www.markdownguide.org/cheat-sheet/) syntax. You can look at [last year's projects and template](https://gitlab.cs.pub.ro/pmrust/pmrust.pages.upb.ro/-/tree/main/website/versioned_docs/version-fils_en/project/2024)
9. After finishing the project, make a _merge request_ to the [upstream repository](https://gitlab.cs.pub.ro/pmrust/pmrust.pages.upb.ro)
## Hardware Rules
1. Projects have to use a microcontroller (MCU) that is capable of running Rust code. Examples of MCUs are *nRF52*, *RP2040*, *ESP32* (RISC-V version).
2. Usage of a development board is encouraged, but not required, a custom PCB can be built. Example of development boards are:
- [Raspberry Pi Pico](https://www.raspberrypi.com/documentation/microcontrollers/raspberry-pi-pico.html) (RP2040) or [Raspberry Pi Pico W](https://www.raspberrypi.com/documentation/microcontrollers/raspberry-pi-pico.html) for WiFi
- [Raspberry Pi Pico 2](https://www.raspberrypi.com/documentation/microcontrollers/raspberry-pi-pico.html) (RP2350) or [Raspberry Pi Pico 2W](https://www.raspberrypi.com/documentation/microcontrollers/raspberry-pi-pico.html) for WiFi (The version of Pico is not important, but we encourage the use of version 2.)
- [Adafruit Trinkey QT2040](https://www.adafruit.com/product/5056) (RP2040)
- [Arduino Nano RP2040 Connect](https://store.arduino.cc/products/arduino-nano-rp2040-connect) (RP2040) - ⚠️ [^arduino_nano_rp2040_connect]
- [micro:bit v2](https://microbit.org/) (nRF52833)
- [nRF52 DK](https://www.nordicsemi.com/Products/Development-hardware/nrf52-dk) (nRF52810)
- [STM32 NUCLEO-F401RE](https://ro.mouser.com/ProductDetail/STMicroelectronics/NUCLEO-F401RE?qs=sGAEpiMZZMuqBwn8WqcFUv%2FX0DKhApUpi46qP7WpjrffIid8Wo1rTg%3D%3D)
- [ESP32-C3-DevKit-RUST-1](https://www.espressif.com/en/dev-board/esp32-c3-devkit-rust-1-en) (ESP32-C3) - ⚠️ [^esp32_riscv]
3. The hardware part may be designed either using a breadboard and jumper wires, a prototype board (solder breadboard) or a PCB.
3. The hardware part may be designed either using a breadboard and jumper wires, a prototype board (solder breadboard) or a PCB. If you want to use prototyping boards, ask the lab coordinator for help with soldering during lab hours.
## Software Rules
It has to run software written in Rust. Students can use:
......@@ -45,19 +99,24 @@ It has to run software written in Rust. Students can use:
## Project Rules
1. Copying schematics or source code from the Internet is not allowed.
2. Each project is considered individual work, students can ask the lab assistant (lab) about implementation details during the development period.
3. Students are strongly encouraged to ask the lab assistant questions about the project.
4. The presentation of all the milestones is mandatory.
1. Copying schematics or source code from the Internet is not allowed. Any attempt to copy the project will be accompanied by the corresponding repercussions.
2. The project is individual, any attempt at collaborative work will be sanctioned, students can also carry out projects that interact, but the work must be separate.
3. Any problem or blockage you have will be discussed with the lab assistant during project work hours.
4. Students are strongly encouraged to ask the lab assistant questions about the project.
5. The presentation of all the milestones is mandatory.
6. The project topic must be established in week 4 and approved by the lab coordinator by week 6. After week 6, the topic cannot be changed.
7. The laboratory supervisor may modify the topic or propose another topic if it is not complex enough for this project.
8. We encourage you not to use prebuilt kits, you may get less points for the hardware part.
## Requirements
1. *Complexity:* use knowledge of at least 3 labs, **excluding** [00 - Rust](https://embedded-rust-101.wyliodrin.com/docs/lab/00), [01 - Hardware Introduction](https://embedded-rust-101.wyliodrin.com/docs/lab/01) and [02 - Setting up the Raspberry Pi Pico + GPIO](https://embedded-rust-101.wyliodrin.com/docs/lab/02)
1. *Complexity:* The project must reflect at least 40 hours of work and contain elements learned during the year.
2. *Documentation:* Complete documentation of the implementation for both hardware and software.
3. *Functionality:* the hardware device has to be fully functional.
3. *Functionality:* The hardware device has to be fully functional.
## Example Projects
### Examples of projects from past years
1. [Projects from 2024](/docs/fils_en/category/projects-2024)
1. https://ocw.cs.pub.ro/courses/pm/prj2022
2. https://ocw.cs.pub.ro/courses/pm/prj2023
......@@ -71,11 +130,11 @@ It has to run software written in Rust. Students can use:
| Part | Deadline | Points |
|--------|--------|--------|
| Documentation Milestone | Lab 9 | 1p |
| Hardware Milestone | Lab 11 | 1p |
| Software Milestone | Lab 12 | 1p |
| PM Faire | TBD | 2p |
| **Total** | | **5p** |
| Documentation Milestone | Lab 9 | 0.4p |
| Hardware Milestone | Lab 11 | 0.8p |
| Software Milestone | Lab 12 | 0.8p |
| PM Fair | TBD | 1p |
| **Total** | | **3p** |
## F.A.Q
**Q:** Can I use another programming language, not Rust?\
......
......@@ -117,7 +117,7 @@ alexagungureanu@gmail.com
| Part | Description | Points |
|--------|-------------|--------|
| [Lecture](./category/lecture) tests | You will have a test every few classes with subjects from the previous class (will pe anounced). | 2p |
| [Lecture](./category/lecture) tests | You will have a test every few classes with subjects from the previous class (will be anounced). | 2p |
| [Lab](./category/lab) | Your work at every lab will be graded. | 1p |
| [Lab](./category/lab) | Final Lab Assigment (Final Lab Test) | 1p |
| [Project](./project) | You will have to design and implement a hardware device. Grading will be done for the documentation, hardware design and software development. | 3p |
......
---
sidebar_position: 4
description: Asynchronous Development, Futures, Executors and Sharing Data between Tasks
unlisted: true
---
# 04 - Asynchronous Development
......
......@@ -4,35 +4,89 @@ sidebar_position: 1
# Description
The purpose of the project is to build a hardware device that runs software written in Rust.
The goal of the project is to showcase the knowledge gained throughout the semester by creating functional hardware that runs software written in Rust.
## Deliverables
All the deliverables will be published in a GitHub repository that each student will be assigned to.
The repository contains:
- documentation - the reposiotry's `README.md` file
- short description of functionality
- requirements (hardware and software)
- hardware design - use [KiCad EDA](https://www.kicad.org/) or a similar tool for the schematics
The deliverables will be stored in two places:
- the *source code* will be stored on [Github](https://github.com/UPB-PMRust-Students)
- the project documentation will be stored on [Gitlab](https://gitlab.cs.pub.ro/pmrust/pmrust.pages.upb.ro), by creating a fork of the course's website
The **documentation repository** should contain:
- the full documentation of the project, in the `index.md` file
- a description of the functionality
- the motivation for choosing the project
- the architecture
- a description of all components and how they interconnect
- a diagram drawn in [diagrams.net](https://app.diagrams.net/) or similar
- a weekly log of the project status
- hardware design
- a description of the hardware used
- a schematic drawn in [KiCad EDA](https://www.kicad.org/) or similar
- photos of the device
- software design
- detail design
- detailed design
- functional diagram
- bill of materials (hardware and software)
- the photos and other files required by the index.md file
:::warning
You need to work in a fork of this website's Gitlab repository and not in a blank one, in order to create a _merge request_, as described below.
:::
The **source code repository** should contain:
- a brief documentation - the repository's `README.md` file
- short description of the functionality
- requirements (hardware and software)
- brief hardware and software design, including diagrams
- software source code
Students will have to build and showcase the hardware with the running software at PM Fair.
The repositories will be checked by the lab assistant at during lab reserved for the project. Uploading code on the last day of the software milestone is not allowed. **The assistant** will check that students have **submitted regular commits** to the repository.
Students will have to build and showcase the hardware with the running software at PM Fair. On the presentation day, **students will upload the source code to the hardware** and the demo will be done live in front of the committee.
## How to create a page for your project?
1. Please login with your UPB login to [Gitlab](https://gitlab.cs.pub.ro)
2. You will have to add an SSH Key to your Gitlab account. This will allow you to push code without entering you username and password every time. For this, run the following command in the Windows/Linux/macOS's console: `ssh-keygen -t rsa -b 2048`. Press press ENTER until you exit the respective command prompts.
- If your command prompt `Overwrite (y/n)?` press `n` and run the above command again, changing the destination of the key.
- If the key was generated successfully, you will have the keys generated in the location indicated by the command `Enter file in which to save the key (C:\Users\"NAME"/.ssh/id_rsa):`
- Read the content of the file `id_rsa.pub` or the name you gave to the file and transfer it to Github.
- Login to [Gitlab](https://gitlab.cs.pub.ro/) and go to: [SSH Keys](https://gitlab.cs.pub.ro/-/user_settings/ssh_keys).
- Click on *Add new key* and insert into the *Key* textbox your key from `id_rsa.pub`.
- Be very careful about the expiration date of the ssh key, change the expiration date otherwise it is set to 30 days.
3. [Download Git](https://git-scm.com) from the official website and access it in the command line using `git -v` to check if it was installed correctly. You might have to use *Git Bash*.
4. Navigate to the [website's Gitlab repository](https://gitlab.cs.pub.ro/pmrust/pmrust.pages.upb.ro) and create a public fork by clicking on the button in the top right corner.
5. Clone the newly created repository by running `git clone git@gitlab.cs.pub.ro:<gitlab_username>/pmrust.pages.upb.ro.git`, where `<gitlab_username>` is replaced by your gitlab username.
6. Now you have your own clone. You need to create a new branch. For this, follow the steps:
- Run the command: `git fetch` followed by the `git pull` command
- The branches have the following naming convention: `project/your_curs.upb.ro_username`. Example: `project/andrei_paul.zamfir`
- To create a new branch:
- `git checkout -b <branch_name>`
- `git push --set-upstream origin project/your_curs.upb.ro_username`
7. To start creating your page for the project, go to `website/versioned_docs/version-acs_cc/project/2025` and create a new directory with your curs.upb.ro username. Example: `andrei_paul.zamfir`.
8. In that directory you must create a file named `index.md` which will be your project page. You can take a look at the [Markdown](https://www.markdownguide.org/cheat-sheet/) syntax. You can look at [last year's projects and template](https://gitlab.cs.pub.ro/pmrust/pmrust.pages.upb.ro/-/tree/main/website/versioned_docs/version-fils_en/project/2024)
9. After finishing the project, make a _merge request_ to the [upstream repository](https://gitlab.cs.pub.ro/pmrust/pmrust.pages.upb.ro)
## Hardware Rules
1. Projects have to use a microcontroller (MCU) that is capable of running Rust code. Examples of MCUs are *nRF52*, *RP2040*, *ESP32* (RISC-V version).
2. Usage of a development board is encouraged, but not required, a custom PCB can be built. Example of development boards are:
- [Raspberry Pi Pico](https://www.raspberrypi.com/documentation/microcontrollers/raspberry-pi-pico.html) (RP2040) or [Raspberry Pi Pico W](https://www.raspberrypi.com/documentation/microcontrollers/raspberry-pi-pico.html) for WiFi
- [Raspberry Pi Pico 2](https://www.raspberrypi.com/documentation/microcontrollers/raspberry-pi-pico.html) (RP2350) or [Raspberry Pi Pico 2W](https://www.raspberrypi.com/documentation/microcontrollers/raspberry-pi-pico.html) for WiFi (The version of Pico is not important, but we encourage the use of version 2.)
- [Adafruit Trinkey QT2040](https://www.adafruit.com/product/5056) (RP2040)
- [Arduino Nano RP2040 Connect](https://store.arduino.cc/products/arduino-nano-rp2040-connect) (RP2040) - ⚠️ [^arduino_nano_rp2040_connect]
- [micro:bit v2](https://microbit.org/) (nRF52833)
- [nRF52 DK](https://www.nordicsemi.com/Products/Development-hardware/nrf52-dk) (nRF52810)
- [STM32 NUCLEO-F401RE](https://ro.mouser.com/ProductDetail/STMicroelectronics/NUCLEO-F401RE?qs=sGAEpiMZZMuqBwn8WqcFUv%2FX0DKhApUpi46qP7WpjrffIid8Wo1rTg%3D%3D)
- [ESP32-C3-DevKit-RUST-1](https://www.espressif.com/en/dev-board/esp32-c3-devkit-rust-1-en) (ESP32-C3) - ⚠️ [^esp32_riscv]
3. The hardware part may be designed either using a breadboard and jumper wires, a prototype board (solder breadboard) or a PCB.
3. The hardware part may be designed either using a breadboard and jumper wires, a prototype board (solder breadboard) or a PCB. If you want to use prototyping boards, ask the lab coordinator for help with soldering during lab hours.
## Software Rules
It has to run software written in Rust. Students can use:
......@@ -45,19 +99,26 @@ It has to run software written in Rust. Students can use:
## Project Rules
1. Copying schematics or source code from the Internet is not allowed.
2. Each project is considered individual work, students can ask the lab assistant (lab) about implementation details during the development period.
3. Students are strongly encouraged to ask the lab assistant questions about the project.
4. The presentation of all the milestones is mandatory.
1. Copying schematics or source code from the Internet is not allowed. Any attempt to copy the project will be accompanied by the corresponding repercussions.
2. The project is individual, any attempt at collaborative work will be sanctioned, students can also carry out projects that interact, but the work must be separate.
3. Any problem or blockage you have will be discussed with the lab assistant during project work hours.
4. Students are strongly encouraged to ask the lab assistant questions about the project.
5. The presentation of all the milestones is mandatory.
6. The project topic must be established in week 4 and approved by the lab coordinator by week 6. After week 6, the topic cannot be changed.
7. The laboratory supervisor may modify the topic or propose another topic if it is not complex enough for this project.
8. We encourage you not to use prebuilt kits, you may get less points for the hardware part.
## Requirements
1. *Complexity:* use knowledge of at least 3 labs, **excluding** [00 - Rust](https://embedded-rust-101.wyliodrin.com/docs/lab/00), [01 - Hardware Introduction](https://embedded-rust-101.wyliodrin.com/docs/lab/01) and [02 - Setting up the Raspberry Pi Pico + GPIO](https://embedded-rust-101.wyliodrin.com/docs/lab/02)
1. *Complexity:* The project must reflect at least 40 hours of work and contain elements learned during the year.
2. *Documentation:* Complete documentation of the implementation for both hardware and software.
3. *Functionality:* the hardware device has to be fully functional.
3. *Functionality:* The hardware device has to be fully functional.
The **IoT** stream has to use the networking (**WiFi**, **Bluetooth** or **Ethernet**).
## Example Projects
### Examples of projects from past years
1. [Projects from 2024](/docs/fils_en/category/projects-2024)
1. https://ocw.cs.pub.ro/courses/pm/prj2022
2. https://ocw.cs.pub.ro/courses/pm/prj2023
......@@ -71,11 +132,11 @@ It has to run software written in Rust. Students can use:
| Part | Deadline | Points |
|--------|--------|--------|
| Documentation Milestone | Lab 9 | 1p |
| Hardware Milestone | Lab 11 | 1p |
| Software Milestone | Lab 12 | 1p |
| PM Faire | TBD | 2p |
| **Total** | | **5p** |
| Documentation Milestone | Lab 9 | 0.5p |
| Hardware Milestone | Lab 11 | 0.5p |
| Software Milestone | Lab 12 | 0.5p |
| PM Fair | TBD | 1.5p |
| **Total** | | **3p** |
## F.A.Q
**Q:** Can I use another programming language, not Rust?\
......
......@@ -56,7 +56,7 @@ teodor.dicu@wyliodrin.com
![Danut Aldea](images/danut_aldea.jpg)
Lab Professor \
Responsible for software
Responsible for software \
GitHub: [danutaldea](https://github.com/danutaldea) \
danut.aldea@oxidos.io
</td>
......