Skip to content
Snippets Groups Projects
Commit 060a721f authored by Per Lindgren's avatar Per Lindgren
Browse files

bare10 posished and tested

parent e76abd91
No related branches found
No related tags found
No related merge requests found
......@@ -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)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment