Skip to content

Commit 96357e0

Browse files
update lecture async (#675)
1 parent f083778 commit 96357e0

3 files changed

Lines changed: 177 additions & 23 deletions

File tree

slides/lectures/resources/communication/slides.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ safely share data between tasks
6767

6868
no `.await` allowed while the mutex is held
6969

70-
```rust{all|1|3-5|7-14|10-14}
70+
```rust{1|3-5|7-14|10-14|all}
7171
use embassy_sync::blocking_mutex::Mutex;
7272
7373
struct Data {/* ... */ }
@@ -85,13 +85,12 @@ async fn task1() {
8585
}
8686
```
8787

88-
89-
---
9088
---
89+
9190
# Async Mutex
9291
`.await` is allowed while the Mutex is held, it will release the Mutex while `await`ing
9392

94-
```rust{all|1|3-5|7-14|10-14}
93+
```rust{1|3-5|7-14|10-14|all}
9594
use embassy_sync::mutex::Mutex;
9695
9796
struct Data {/* ... */ }

slides/lectures/resources/executor/slides.md

Lines changed: 137 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,57 @@ async fn main(spawner: Spawner) {
114114
---
115115
layout: two-cols
116116
---
117+
# Priority Tasks
117118

118-
## Priority Tasks
119+
<style>
120+
.two-columns {
121+
grid-template-columns: 3fr 5fr;
122+
}
123+
</style>
124+
125+
<v-clicks>
126+
127+
- the tasks run in separate *executors*
128+
- triggered from **interrupts**
129+
- will **interrupt any task** running in the **main executor**
130+
131+
</v-clicks>
132+
133+
<br>
134+
135+
<v-after>
136+
137+
> ⚠️ Tasks that share data between executors require synchronization.
138+
139+
<br>
140+
141+
</v-after>
142+
143+
<v-click>
144+
145+
### RP2
146+
- use `SWI_IRQ_01` and `SWI_IRQ_01`
147+
148+
</v-click>
149+
150+
<v-click>
151+
152+
### STM32U545RE
153+
- use any interrupt (`UART`, `SPI`, ...) not used anywhere else
154+
155+
</v-click>
156+
157+
:: right ::
158+
159+
<div align="center">
160+
<img src="./isr_executor.svg" class="rounded">
161+
</div>
162+
163+
---
164+
layout: two-cols
165+
---
166+
167+
# Priority Tasks
119168

120169
<style>
121170
.two-columns {
@@ -127,22 +176,71 @@ layout: two-cols
127176
<img src="./isr_executor.svg" class="rounded">
128177
</div>
129178

179+
<v-switch>
180+
181+
<template #3>
182+
130183
```rust {*}{lines: false}
131184
#[interrupt]
132185
unsafe fn SWI_IRQ_1() {
133186
EXECUTOR_HIGH.on_interrupt()
134187
}
188+
```
189+
190+
</template>
191+
192+
<template #4>
193+
194+
```rust {*}{lines: false}
135195
#[interrupt]
136196
unsafe fn SWI_IRQ_0() {
137-
EXECUTOR_MED.on_interrupt()
197+
EXECUTOR_MEDIUM.on_interrupt()
138198
}
139199
```
140200

201+
</template>
202+
203+
<template #5>
204+
205+
```rust {*}{lines: false}
206+
#[interrupt]
207+
unsafe fn SWI_IRQ_1() {
208+
EXECUTOR_HIGH.on_interrupt()
209+
}
210+
#[interrupt]
211+
unsafe fn SWI_IRQ_0() {
212+
EXECUTOR_MEDIUM.on_interrupt()
213+
}
214+
```
215+
216+
</template>
217+
218+
<template #6>
219+
220+
```rust {*}{lines: false}
221+
#[interrupt]
222+
unsafe fn UART4() {
223+
EXECUTOR_HIGH.on_interrupt()
224+
}
225+
#[interrupt]
226+
unsafe fn UART5() {
227+
EXECUTOR_MEDIUM.on_interrupt()
228+
}
229+
```
230+
231+
</template>
232+
233+
</v-switch>
234+
141235
:: right ::
142236

143-
```rust {5,6,22|1,7-10|2,12-15|3,17-21|all}
237+
````md magic-move {at: '1'}
238+
239+
```rust {none|7,8,24|5,7,8,19-23,24|3,9-12|4,14-17|all}
240+
// RP2
241+
144242
static EXECUTOR_HIGH: InterruptExecutor = InterruptExecutor::new();
145-
static EXECUTOR_MED: InterruptExecutor = InterruptExecutor::new();
243+
static EXECUTOR_MEDIUM: InterruptExecutor = InterruptExecutor::new();
146244
static EXECUTOR_LOW: StaticCell<Executor> = StaticCell::new();
147245

148246
#[entry]
@@ -154,7 +252,7 @@ fn main() -> ! {
154252

155253
// Medium-priority executor: SWI_IRQ_0, priority level 3
156254
interrupt::SWI_IRQ_0.set_priority(Priority::P3);
157-
let spawner = EXECUTOR_MED.start(interrupt::SWI_IRQ_0);
255+
let spawner = EXECUTOR_MEDIUM.start(interrupt::SWI_IRQ_0);
158256
spawner.spawn(run_med()).unwrap();
159257

160258
// Low priority executor: runs in thread mode, using WFE/SEV
@@ -165,4 +263,37 @@ fn main() -> ! {
165263
}
166264
```
167265

168-
priority executors run in ISRs, lower priority tasks are interrupted
266+
```rust
267+
// STM32U545RE
268+
269+
static EXECUTOR_HIGH: InterruptExecutor = InterruptExecutor::new();
270+
static EXECUTOR_MEDIUM: InterruptExecutor = InterruptExecutor::new();
271+
static EXECUTOR_LOW: StaticCell<Executor> = StaticCell::new();
272+
273+
#[entry]
274+
fn main() -> ! {
275+
// High-priority executor: UART4, priority level 2
276+
interrupt::SWI_IRQ_1.set_priority(Priority::P2);
277+
let spawner = EXECUTOR_HIGH.start(interrupt::UART4);
278+
spawner.spawn(run_high()).unwrap();
279+
280+
// Medium-priority executor: UART5, priority level 3
281+
interrupt::SWI_IRQ_0.set_priority(Priority::P3);
282+
let spawner = EXECUTOR_MEDIUM.start(interrupt::UART5);
283+
spawner.spawn(run_med()).unwrap();
284+
285+
// Low priority executor: runs in thread mode, using WFE/SEV
286+
let executor = EXECUTOR_LOW.init(Executor::new());
287+
executor.run(|spawner| {
288+
unwrap!(spawner.spawn(run_low()));
289+
});
290+
}
291+
```
292+
293+
````
294+
295+
<div v-click="3">
296+
297+
💡 priority executors run in ISRs, lower priority tasks are interrupted
298+
299+
</div>

slides/lectures/resources/future/slides.md

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ sequenceDiagram
7474

7575
<div grid="~ cols-2 gap-5">
7676

77-
```rust {1-4|6-9|11-18|all}
77+
```rust {1-4|6-9|11-18|all}{lines: false}
7878
enum SleepStatus {
7979
SetAlarm,
8080
WaitForAlarm,
@@ -97,6 +97,7 @@ impl Sleep {
9797

9898
<v-click>
9999

100+
````md magic-move
100101
```rust {1,20|1,2,20|4,19|5,18|6-10|11-17|11,12,13|11,14,15|all}{lines: false}
101102
impl Future for Sleep {
102103
type Output = ();
@@ -120,6 +121,32 @@ impl Future for Sleep {
120121
}
121122
```
122123

124+
```rust {*}{lines: false}
125+
impl Future for Sleep {
126+
type Output = ();
127+
128+
fn poll(&mut self) -> Poll<Self::Output> {
129+
loop {
130+
match self.status {
131+
SleepStatus::SetAlarm => {
132+
ALARM.set_alarm(self.timeout);
133+
self.status = SleepStatus::WaitForAlarm;
134+
}
135+
SleepStatus::WaitForAlarm => {
136+
if ALARM.expired() {
137+
return Poll::Ready(());
138+
} else {
139+
return Poll::Pending
140+
}
141+
}
142+
}
143+
}
144+
}
145+
}
146+
```
147+
148+
````
149+
123150
</v-click>
124151

125152
</div>
@@ -130,22 +157,19 @@ impl Future for Sleep {
130157

131158
<div grid="~ cols-2 gap-5">
132159

133-
```rust {1,20|1,2,20|4,19|5,18|6-10|11-17|11,12,13|11,14,15|all}{lines: false}
134-
impl Future for Sleep {
135-
type Output = ();
136-
137-
fn poll(&mut self) -> Poll<Self::Output> {
160+
```rust {1,17|2,16|3,15|4-7|2,16|3,15|8-14|8,9,10|1,17|8,11,12|all}{lines: false}
161+
fn poll(&mut self) -> Poll<Self::Output> {
162+
loop {
138163
match self.status {
139164
SleepStatus::SetAlarm => {
140165
ALARM.set_alarm(self.timeout);
141166
self.status = SleepStatus::WaitForAlarm;
142-
Poll::Pending
143167
}
144168
SleepStatus::WaitForAlarm => {
145169
if ALARM.expired() {
146-
Poll::Ready(())
170+
return Poll::Ready(());
147171
} else {
148-
Poll::Pending
172+
return Poll::Pending;
149173
}
150174
}
151175
}
@@ -191,7 +215,7 @@ async fn blink(mut led: Output<'static, PIN_X>) {
191215
led.off();
192216
}
193217
```
194-
<v-click>
218+
<div v-click="1">
195219
Rust rewrites
196220

197221
```rust {1-7|1-3,7|1,4-7|8-12|13-15|all}{lines: false}
@@ -212,11 +236,11 @@ fn blink(led: Output<'static, PIN_X>) -> Blink {
212236
}
213237
```
214238

215-
</v-click>
239+
</div>
216240

217241
:: right ::
218242

219-
<v-click>
243+
<div v-click="6">
220244

221245
```rust {4-23|5-22|5,6-10,22|5,11-17,22|12-14|5,11-17,22|12,14,15,16|5,18-21,22|all}{lines: false}
222246
impl Future for Blink {
@@ -246,7 +270,7 @@ impl Future for Blink {
246270
}
247271
```
248272

249-
</v-click>
273+
</div>
250274

251275

252276
---

0 commit comments

Comments
 (0)