diff --git a/examples/bare10.rs b/examples/bare10.rs index 5d3882e8dbfceb0a8babcc4218f30e3872f5dc54..f0aa1cb5136e24fe9a2eb532766f6710f51857e0 100644 --- a/examples/bare10.rs +++ b/examples/bare10.rs @@ -27,16 +27,20 @@ pub enum Error { UsartReceiveOverflow, } -#[app(device = hal::stm32)] +#[app(device = hal::stm32, peripherals = true)] const APP: () = { - // Late resources - static mut TX: Tx<hal::stm32::USART2> = (); - static mut RX: Rx<hal::stm32::USART2> = (); - static mut ITM: ITM = (); - + struct Resources { + // Late resources + TX: Tx<hal::stm32::USART2>, + RX: Rx<hal::stm32::USART2>, + ITM: ITM, + } // init runs in an interrupt free section> #[init] - fn init() { + fn init(cx: init::Context) -> init::LateResources { + let mut core = cx.core; + let device = cx.device; + let stim = &mut core.ITM.stim[0]; iprintln!(stim, "bare10"); @@ -63,60 +67,63 @@ const APP: () = { // Separate out the sender and receiver of the serial port let (tx, rx) = serial.split(); - // Our split serial - TX = tx; - RX = rx; + // Late resources + init::LateResources { + // Our split serial + TX: tx, + RX: rx, - // For debugging - ITM = core.ITM; + // For debugging + ITM: core.ITM, + } } // idle may be interrupted by other interrupt/tasks in the system #[idle] - fn idle() -> ! { + fn idle(_cx: idle::Context) -> ! { loop { asm::wfi(); } } #[task(priority = 1, resources = [ITM])] - fn trace_data(byte: u8) { - let stim = &mut resources.ITM.stim[0]; + fn trace_data(cx: trace_data::Context, byte: u8) { + let stim = &mut cx.resources.ITM.stim[0]; iprintln!(stim, "data {}", byte); // for _ in 0..10000 { // asm::nop(); // } } + #[task(priority = 1, resources = [ITM])] - fn trace_error(error: Error) { - let stim = &mut resources.ITM.stim[0]; + fn trace_error(cx: trace_error::Context, error: Error) { + let stim = &mut cx.resources.ITM.stim[0]; iprintln!(stim, "{:?}", error); } #[task(priority = 2, resources = [TX], spawn = [trace_error])] - fn echo(byte: u8) { - let tx = resources.TX; + fn echo(cx: echo::Context, byte: u8) { + let tx = cx.resources.TX; if block!(tx.write(byte)).is_err() { - let _ = spawn.trace_error(Error::UsartSendOverflow); + let _ = cx.spawn.trace_error(Error::UsartSendOverflow); } - } - #[interrupt(priority = 3, resources = [RX], spawn = [trace_data, trace_error, echo])] - fn USART2() { - let rx = resources.RX; + #[task(binds = USART2, priority = 3, resources = [RX], spawn = [trace_data, trace_error, echo])] + fn usart2(cx:usart2::Context) { + let rx = cx.resources.RX; match rx.read() { Ok(byte) => { - let _ = spawn.echo(byte); - if spawn.trace_data(byte).is_err() { - let _ = spawn.trace_error(Error::RingBufferOverflow); + let _ = cx.spawn.echo(byte); + if cx.spawn.trace_data(byte).is_err() { + let _ = cx.spawn.trace_error(Error::RingBufferOverflow); } } Err(_err) => { - let _ = spawn.trace_error(Error::UsartReceiveOverflow); + let _ = cx.spawn.trace_error(Error::UsartReceiveOverflow); } } } @@ -129,18 +136,19 @@ const APP: () = { } }; +// Optional // 0. Compile and run the project at 16MHz in release mode // make sure its running (not paused). // -// > cargo build --example bare9 --features "hal rtfm" --release +// > cargo build --example bare9 --features "rtfm" --release // (or use the vscode build task) // // Connect a terminal program. // Verify that it works as bare9. -// +// // 1. Now, comment out the loop in `trace_data`. // The loop is just there to simulate some workload... -// +// // Try now to send a sequence `abcd` // // Did you loose any data (was the data correctly echoed)? @@ -153,12 +161,12 @@ const APP: () = { // // Why did you loose trace information? // -// ** your asnwer here ** +// ** your answer here ** // // Commit your answers (bare10_1) // // 2. Read the RTFM manual (book). -// Figure out a way to accomdate for 4 outstanding messages to the `trace_data` task. +// Figure out a way to accomodate for 4 outstanding messages to the `trace_data` task. // // Verify that you can now correctly trace sequences of 4 characters sent. // @@ -168,25 +176,25 @@ const APP: () = { // What information would you need? // // ** your answer here ** -// +// // Commit your answers (bare10_2) // // 3. Implement a command line interpreter as a new task. -// It should: +// It should: // - have priority 1. // - take a byte as an argument (passed from the USART2 interrupt). // - have a local buffer B of 10 characters -// - have sufficent capacity to recieve 10 charactes sent in a sequence +// - have sufficient capacity to receive 10 characters sent in a sequence // - analyse the input buffer B checking the commands // set <int> <RETURN> // to set blinking frequency // on <RETURN> // to enable the led blinking // of <RETURN> // to disable the led blinking -// +// // <int> should be decoded to an integer value T, and <RETURN> accept either <CR> or <LF>. // -// The set value should blink the LED in according the set value in Herz, +// The set value should blink the LED in according the set value in Hertz, // (so `set 1 <RETURN>` should blink with 1Hz) -// +// // Tips: // Create two tasks, (`on', that turns the led on, and a task `off` that turns the led off). // `on` calls `off` with a timer offset (check the RTFM manual). @@ -194,17 +202,17 @@ const APP: () = { // // The timing offset can implemented as a shared resource T between the command line interpreter and // the 'on/off ' tasks. From `init` you can give an initial timing offset T, and send an -// initial message to `on` triggering the periodic behavior. +// initial message to `on` triggering the periodic behavior. // -// The 'on/off ' tasks can have a high priority 4, and use locking (in the low prio task) +// The 'on/off ' tasks can have a high priority 4, and use locking (in the low priority task) // parsing the input. This way, the led will have a very low jitter. // // (You can even use an atomic data structure, which allows for lock free access.) -// -// -// The on/off is easiest impemented by having another shared variable used as a condition +// +// +// The on/off is easiest implemented by having another shared variable used as a condition // for the `on` task to set the GPIO. Other solutions could be to stop the sequence (i.e.) -// contiditionally call the `off` task instead. Then the command interpreted would +// conditionally call the `off` task instead. Then the command interpreted would // trigger a new sequence when an "on" command is detected. (Should you allow multiple, overlapping) // sequences? Why not, could be cool ;) // The main advantage of the stopping approach is that the system will be truly idle @@ -215,4 +223,4 @@ const APP: () = { // You can come up with various extensions to this application, setting the // the duty cycle (on/off ratio in %), etc. // -// Commit your solution (bare10_3) \ No newline at end of file +// Commit your solution (bare10_3)