Select Git revision
rtic_bare8.rs
Forked from
Per Lindgren / e7020e_2021
Source project has a limited visibility.
rtic_bare8.rs 5.25 KiB
//! bare8.rs
//!
//! Serial
//!
//! What it covers:
//! - serial communication
//! - bad design
#![no_main]
#![no_std]
use panic_rtt_target as _;
use stm32f4xx_hal::{
gpio::{gpioa::PA, Output, PushPull},
prelude::*,
serial::{config::Config, Rx, Serial, Tx},
stm32::USART2,
nb::block,
};
use rtic::app;
use rtt_target::{rprintln, rtt_init_print};
#[app(device = stm32f4xx_hal::stm32, peripherals = true)]
const APP: () = {
struct Resources {
// Late resources
TX: Tx<USART2>,
RX: Rx<USART2>,
}
// init runs in an interrupt free section
#[init]
fn init(cx: init::Context) -> init::LateResources {
rtt_init_print!();
rprintln!("init");
let device = cx.device;
let rcc = device.RCC.constrain();
// 16 MHz (default, all clocks)
let clocks = rcc.cfgr.freeze();
let gpioa = device.GPIOA.split();
let tx = gpioa.pa2.into_alternate_af7();
let rx = gpioa.pa3.into_alternate_af7();
let serial = Serial::usart2(
device.USART2,
(tx, rx),
Config::default().baudrate(115_200.bps()),
clocks,
)
.unwrap();
// Separate out the sender and receiver of the serial port
let (tx, rx) = serial.split();
// Late resources
init::LateResources { TX: tx, RX: rx }
}
// idle may be interrupted by other interrupts/tasks in the system
#[idle(resources = [RX, TX])]
fn idle(cx: idle::Context) -> ! {
let rx = cx.resources.RX;
let tx = cx.resources.TX;
let mut received = 0;
let mut errors = 0;
loop {
match block!(rx.read()) {
Ok(byte) => {
rprintln!("Ok {:?}", byte);
tx.write(byte).unwrap();
received +=1;
}
Err(err) => {
rprintln!("Error {:?}", err);
let test:u8 = 13;
tx.write(test).unwrap();
errors +=1;
}
}
rprintln!("Numbers of received: {:?}", received);
rprintln!("Numbers of errors: {:?}", errors);
}
}
};
// 0. Background
//
// The Nucleo st-link programmer provides a Virtual Com Port (VCP).
// It is connected to the PA2(TX)/PA3(RX) pins of the stm32f401/411.
// On the host, the VCP is presented under `/dev/ttyACMx`, where
// `x` is an enumerated number (ff 0 is busy it will pick 1, etc.)
//
// 1. In this example we use RTT.
//
// > cargo run --example rtic_bare8
//
// Start a terminal program, e.g., `moserial`.
// Connect to the port
//
// Device /dev/ttyACM0
// Baude Rate 115200
// Data Bits 8
// Stop Bits 1
// Parity None
//
// This setting is typically abbreviated as 115200 8N1.
//
// Send a single character (byte), (set the option `No end` in `moserial`).
// Verify that sent bytes are echoed back, and that RTT tracing is working.
//
// Try sending "a", don't send the quotation marks, just a.
//
// What do you receive in `moserial`?
//
// I can't run moserial (Windows). But PuTTY seems to get a.
//
// What do you receive in the RTT terminal?
//
// OK 97
//
// Try sending: "abcd" as a single sequence, don't send the quotation marks, just abcd.
//
// What did you receive in `moserial`?
//
// ad (Running PuTTY. Not moserial)
//
// What do you receive in the RTT terminal?
//
// Ok 97
// Error Overrun
// Ok 100
//
// What do you believe to be the problem?
//
// Hint: Look at the code in `idle` what does it do?
//
// The buffer have not been read from and has not been cleared.
//
// Experiment a bit, what is the max length sequence you can receive without errors?
//
// 8 bits or 1 byte.
//
// Commit your answers (bare8_1)
//
// 2. Add a local variable `received` that counts the number of bytes received.
// Add a local variable `errors` that counts the number of errors.
//
// Adjust the RTT trace to print the added information inside the loop.
//
// Compile/run reconnect, and verify that it works as intended.
//
// Commit your development (bare8_2)
//
// 3. Experiment a bit, what is the max length sequence you can receive without errors?
//
// 1
//
// How did the added tracing/instrumentation affect the behavior?
//
// I now only receive a back.
//
// Commit your answer (bare8_3)
//
// 4. Now try compile and run the same experiment 3 but in --release mode.
//
// > cargo run --example rtic_bare8 --release
//
// Reconnect your `moserial` terminal.
//
// Experiment a bit, what is the max length sequence you can receive without errors?
//
// Now I receive "ad" again
//
// Commit your answer (bare8_4)
//
// 5. Discussion
//
// (If you ever used Arduino, you might feel at home with the `loop` and poll design.)
//
// Typically, this is what you can expect from a polling approach, if you
// are not very careful what you are doing. This exemplifies a bad design.
//
// Loss of data might be Ok for some applications but this typically NOT what we want.
//
// (With that said, Arduino gets away with some simple examples as their drivers do
// internal magic - buffering data etc.)