aboutsummaryrefslogtreecommitdiff
path: root/examples/src/bin/multiprio.rs
diff options
context:
space:
mode:
Diffstat (limited to 'examples/src/bin/multiprio.rs')
-rw-r--r--examples/src/bin/multiprio.rs176
1 files changed, 0 insertions, 176 deletions
diff --git a/examples/src/bin/multiprio.rs b/examples/src/bin/multiprio.rs
deleted file mode 100644
index c821e3dba..000000000
--- a/examples/src/bin/multiprio.rs
+++ /dev/null
@@ -1,176 +0,0 @@
1//! This example showcases how to create multiple Executor instances to run tasks at
2//! different priority levels.
3//!
4//! Low priority executor runs in thread mode (not interrupt), and uses `sev` for signaling
5//! there's work in the queue, and `wfe` for waiting for work.
6//!
7//! Medium and high priority executors run in two interrupts with different priorities.
8//! Signaling work is done by pending the interrupt. No "waiting" needs to be done explicitly, since
9//! when there's work the interrupt will trigger and run the executor.
10//!
11//! Sample output below. Note that high priority ticks can interrupt everything else, and
12//! medium priority computations can interrupt low priority computations, making them to appear
13//! to take significantly longer time.
14//!
15//! ```not_rust
16//! [med] Starting long computation
17//! [med] done in 992 ms
18//! [high] tick!
19//! [low] Starting long computation
20//! [med] Starting long computation
21//! [high] tick!
22//! [high] tick!
23//! [med] done in 993 ms
24//! [med] Starting long computation
25//! [high] tick!
26//! [high] tick!
27//! [med] done in 993 ms
28//! [low] done in 3972 ms
29//! [med] Starting long computation
30//! [high] tick!
31//! [high] tick!
32//! [med] done in 993 ms
33//! ```
34//!
35//! For comparison, try changing the code so all 3 tasks get spawned on the low priority executor.
36//! You will get an output like the following. Note that no computation is ever interrupted.
37//!
38//! ```not_rust
39//! [high] tick!
40//! [med] Starting long computation
41//! [med] done in 496 ms
42//! [low] Starting long computation
43//! [low] done in 992 ms
44//! [med] Starting long computation
45//! [med] done in 496 ms
46//! [high] tick!
47//! [low] Starting long computation
48//! [low] done in 992 ms
49//! [high] tick!
50//! [med] Starting long computation
51//! [med] done in 496 ms
52//! [high] tick!
53//! ```
54//!
55
56#![no_std]
57#![no_main]
58#![feature(type_alias_impl_trait)]
59
60#[path = "../example_common.rs"]
61mod example_common;
62use example_common::*;
63
64use cortex_m::peripheral::NVIC;
65use cortex_m_rt::entry;
66use defmt::panic;
67use nrf52840_hal::clocks;
68
69use embassy::executor::{task, Executor};
70use embassy::time::{Duration, Instant, Timer};
71use embassy::util::Forever;
72use embassy_nrf::{interrupt, pac, rtc};
73
74#[task]
75async fn run_high() {
76 loop {
77 info!(" [high] tick!");
78 Timer::after(Duration::from_ticks(27374)).await;
79 }
80}
81
82#[task]
83async fn run_med() {
84 loop {
85 let start = Instant::now();
86 info!(" [med] Starting long computation");
87
88 // Spin-wait to simulate a long CPU computation
89 cortex_m::asm::delay(32_000_000); // ~1 second
90
91 let end = Instant::now();
92 let ms = end.duration_since(start).as_ticks() / 33;
93 info!(" [med] done in {:u64} ms", ms);
94
95 Timer::after(Duration::from_ticks(23421)).await;
96 }
97}
98
99#[task]
100async fn run_low() {
101 loop {
102 let start = Instant::now();
103 info!("[low] Starting long computation");
104
105 // Spin-wait to simulate a long CPU computation
106 cortex_m::asm::delay(64_000_000); // ~2 seconds
107
108 let end = Instant::now();
109 let ms = end.duration_since(start).as_ticks() / 33;
110 info!("[low] done in {:u64} ms", ms);
111
112 Timer::after(Duration::from_ticks(32983)).await;
113 }
114}
115
116static RTC: Forever<rtc::RTC<pac::RTC1>> = Forever::new();
117static ALARM_LOW: Forever<rtc::Alarm<pac::RTC1>> = Forever::new();
118static EXECUTOR_LOW: Forever<Executor> = Forever::new();
119static ALARM_MED: Forever<rtc::Alarm<pac::RTC1>> = Forever::new();
120static EXECUTOR_MED: Forever<Executor> = Forever::new();
121static ALARM_HIGH: Forever<rtc::Alarm<pac::RTC1>> = Forever::new();
122static EXECUTOR_HIGH: Forever<Executor> = Forever::new();
123
124#[entry]
125fn main() -> ! {
126 info!("Hello World!");
127
128 let p = unwrap!(embassy_nrf::pac::Peripherals::take());
129
130 clocks::Clocks::new(p.CLOCK)
131 .enable_ext_hfosc()
132 .set_lfclk_src_external(clocks::LfOscConfiguration::NoExternalNoBypass)
133 .start_lfclk();
134
135 let rtc = RTC.put(rtc::RTC::new(p.RTC1, interrupt::take!(RTC1)));
136 rtc.start();
137 unsafe { embassy::time::set_clock(rtc) };
138
139 let alarm_low = ALARM_LOW.put(rtc.alarm0());
140 let executor_low = EXECUTOR_LOW.put(Executor::new_with_alarm(alarm_low, cortex_m::asm::sev));
141 let alarm_med = ALARM_MED.put(rtc.alarm1());
142 let executor_med = EXECUTOR_MED.put(Executor::new_with_alarm(alarm_med, || {
143 NVIC::pend(interrupt::SWI0_EGU0)
144 }));
145 let alarm_high = ALARM_HIGH.put(rtc.alarm2());
146 let executor_high = EXECUTOR_HIGH.put(Executor::new_with_alarm(alarm_high, || {
147 NVIC::pend(interrupt::SWI1_EGU1)
148 }));
149
150 unsafe {
151 let mut nvic: NVIC = core::mem::transmute(());
152 nvic.set_priority(interrupt::SWI0_EGU0, 7 << 5);
153 nvic.set_priority(interrupt::SWI1_EGU1, 6 << 5);
154 NVIC::unmask(interrupt::SWI0_EGU0);
155 NVIC::unmask(interrupt::SWI1_EGU1);
156 }
157
158 unwrap!(executor_low.spawn(run_low()));
159 unwrap!(executor_med.spawn(run_med()));
160 unwrap!(executor_high.spawn(run_high()));
161
162 loop {
163 executor_low.run();
164 cortex_m::asm::wfe();
165 }
166}
167
168#[interrupt]
169unsafe fn SWI0_EGU0() {
170 EXECUTOR_MED.steal().run()
171}
172
173#[interrupt]
174unsafe fn SWI1_EGU1() {
175 EXECUTOR_HIGH.steal().run()
176}