Skip to content
Snippets Groups Projects
Commit 95c2e7b4 authored by Edward's avatar Edward
Browse files

add correct versions of rtic_bare exercises

parent 1c394e45
No related branches found
No related tags found
No related merge requests found
...@@ -20,14 +20,14 @@ const APP: () = { ...@@ -20,14 +20,14 @@ const APP: () = {
fn init(_cx: init::Context) { fn init(_cx: init::Context) {
let mut x = core::u32::MAX - 1; let mut x = core::u32::MAX - 1;
loop { loop {
// cortex_m::asm::bkpt(); cortex_m::asm::bkpt();
x += 1; x += x.wrapping_add(1);
// cortex_m::asm::bkpt(); cortex_m::asm::bkpt();
// prevent optimization by read-volatile (unsafe) // prevent optimization by read-volatile (unsafe)
unsafe { /*unsafe {
core::ptr::read_volatile(&x); core::ptr::read_volatile(&x);
} }*/
} }
} }
}; };
...@@ -45,11 +45,14 @@ const APP: () = { ...@@ -45,11 +45,14 @@ const APP: () = {
// //
// Paste the error message: // Paste the error message:
// //
// ** your answer here ** // ** My answer here **
// panicked at 'attempt to add with overflow', examples/rtic_bare1.rs:24:13
// //
// Explain in your own words why the code panic:ed. // Explain in your own words why the code panic:ed.
// //
// ** your answer here ** // ** My answer here **
// core::u32::MAX - 1 sets the value of x to the maximum value a 32 unsigned bit can hold - 1 and
// then starts a loop with an addition of 1 to x, that's a recipe for overflow.
// //
// Commit your answer (bare1_1) // Commit your answer (bare1_1)
// //
...@@ -65,11 +68,28 @@ const APP: () = { ...@@ -65,11 +68,28 @@ const APP: () = {
// //
// Paste the backtrace: // Paste the backtrace:
// //
// ** your answer here // ** My answer here **
/*
#0 lib::__bkpt () at asm/lib.rs:49
#1 0x0800104e in cortex_m::asm::bkpt () at /home/decending/.cargo/registry/src/github.com-1ecc6299db9ec823/cortex-m-0.7.1/src/asm.rs:15
#2 rust_begin_unwind (info=0x2000fed8) at /home/decending/.cargo/registry/src/github.com-1ecc6299db9ec823/panic-semihosting-0.5.6/src/lib.rs:92
#3 0x0800039a in core::panicking::panic_fmt () at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b//library/core/src/panicking.rs:92
#4 0x08000374 in core::panicking::panic () at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b//library/core/src/panicking.rs:50
#5 0x08000ebe in rtic_bare1::init (_cx=...) at /home/decending/Desktop/e7020e_2021/examples/rtic_bare1.rs:24
#6 0x08000f08 in rtic_bare1::APP::main () at /home/decending/Desktop/e7020e_2021/examples/rtic_bare1.rs:15
*/
// //
// Explain in your own words the chain of calls. // Explain in your own words the chain of calls.
// //
// ** your answer here // ** My answer here **
// This will run from the "bottom up":
// 0# We enter a function with a breakpoint
// 1# Calling function for breakpoint
// 2# We unwind to catch the panic
// 3# We continue to handle the panic
// 4# We start to panic
// 5# We start the init task.
// 6# We call the APP::main task,
// //
// Commit your answer (bare1_2) // Commit your answer (bare1_2)
// //
...@@ -82,11 +102,14 @@ const APP: () = { ...@@ -82,11 +102,14 @@ const APP: () = {
// //
// What is the value of `x`? // What is the value of `x`?
// //
// ** your answer here ** // ** My answer here **
// x = 4294967294;
// //
// Explain in your own words where this value comes from. // Explain in your own words where this value comes from.
// //
// ** your answer here ** // ** My answer here **
// This is the value of a 32-bit unsigned integer with the form:
// 11111111111111111111111111111110, which is core::u32::MAX - 1.
// //
// Now continue the program, since you are in a loop // Now continue the program, since you are in a loop
// the program will halt again at line 24. // the program will halt again at line 24.
...@@ -95,7 +118,10 @@ const APP: () = { ...@@ -95,7 +118,10 @@ const APP: () = {
// //
// Explain in your own words why `x` now has this value. // Explain in your own words why `x` now has this value.
// //
// ** your answer here ** // ** My answer here **
// x = 4294967295;
// 4294967294 + 1 = 4294967295
// This is what the loop is meant to do, so nothing strange here.
// //
// Now continue again. // Now continue again.
// //
...@@ -109,7 +135,9 @@ const APP: () = { ...@@ -109,7 +135,9 @@ const APP: () = {
// //
// Explain in your own words why a panic makes sense at this point. // Explain in your own words why a panic makes sense at this point.
// //
// ** your answer here ** // ** My answer here **
// Since we're not using any sort of wrapping the new number, which is 4294967296 can't be contained
// in a u32 datastructure, so this becomes an undefined behaviour and hence the code panics.
// //
// Commit your answer (bare1_3) // Commit your answer (bare1_3)
// //
...@@ -126,13 +154,15 @@ const APP: () = { ...@@ -126,13 +154,15 @@ const APP: () = {
// //
// Explain in your own words what this assembly line does. // Explain in your own words what this assembly line does.
// //
// ** your answer here ** // ** My answer here **
// It'll load the sp with an immediate offset of 0 into r0. This should be our x.
// //
// In Cortex Registers (left) you can see the content of `r0` // In Cortex Registers (left) you can see the content of `r0`
// //
// What value do you observe? // What value do you observe?
// //
// ** your answer here ** // ** My answer here **
// -2 = 0xfffffffe.
// //
// You can also get the register info from GDB directly. // You can also get the register info from GDB directly.
// //
...@@ -150,7 +180,8 @@ const APP: () = { ...@@ -150,7 +180,8 @@ const APP: () = {
// //
// Explain in your own words what is happening here. // Explain in your own words what is happening here.
// //
// ** your answer here ** // ** My answer here **
// We will add r0 and the immidate value 1 together (x + 1)
// //
// We move to the next assembly instruction: // We move to the next assembly instruction:
// //
...@@ -159,7 +190,8 @@ const APP: () = { ...@@ -159,7 +190,8 @@ const APP: () = {
// //
// What is the reported value for `r0` // What is the reported value for `r0`
// //
// ** your answer here ** // ** My answer here **
// 0xffffffff = -1
// //
// So far so good. // So far so good.
// //
...@@ -190,7 +222,8 @@ const APP: () = { ...@@ -190,7 +222,8 @@ const APP: () = {
// //
// What does BCS do? // What does BCS do?
// //
// ** your answer here ** // ** My answer here **
// It'll check for the carry flag and if it is set the instruction will jump to the provided address.
// //
// Now let's see what happens. // Now let's see what happens.
// //
...@@ -204,7 +237,8 @@ const APP: () = { ...@@ -204,7 +237,8 @@ const APP: () = {
// //
// Explain in your own words where we are heading. // Explain in your own words where we are heading.
// //
// ** your answer here ** // ** My answer here **
// We are heading into the panicking system.
// //
// To validate that your answer, let's let the program continue // To validate that your answer, let's let the program continue
// //
...@@ -220,9 +254,10 @@ const APP: () = { ...@@ -220,9 +254,10 @@ const APP: () = {
// Hint 3, the code is generated by the Rust compiler to produce the error message. // Hint 3, the code is generated by the Rust compiler to produce the error message.
// there is no "magic" here, just a compiler generating code... // there is no "magic" here, just a compiler generating code...
// //
// ** your answer here ** // ** My answer here **
// We save the relevant information regarding the panic.
// //
// Commit your answer (bare1_4) // Commit your answer (bare1_3)
// //
// 5. Now we can remove the break point (click the `Remove All Breakpoints`), // 5. Now we can remove the break point (click the `Remove All Breakpoints`),
// and instead uncomment the two breakpoint instructions (on lines 23 and 25). // and instead uncomment the two breakpoint instructions (on lines 23 and 25).
...@@ -233,7 +268,7 @@ const APP: () = { ...@@ -233,7 +268,7 @@ const APP: () = {
// //
// The disassembly should look like this: // The disassembly should look like this:
// //
// //Release
// 0x08000f18 <+20>: bl 0x800103e <lib::__bkpt> // 0x08000f18 <+20>: bl 0x800103e <lib::__bkpt>
// => 0x08000f1c <+24>: ldr r0, [sp, #0] // => 0x08000f1c <+24>: ldr r0, [sp, #0]
// 0x08000f1e <+26>: adds r0, #1 // 0x08000f1e <+26>: adds r0, #1
...@@ -273,7 +308,8 @@ const APP: () = { ...@@ -273,7 +308,8 @@ const APP: () = {
// //
// Do you see any way this code may end up in a panic? // Do you see any way this code may end up in a panic?
// //
// ** your answer here ** // ** My answer here **
// There is no reference to the panic handler, so this will not be able to generate a panic. I guess the default is to have a wrapping addition in release mode.
// //
// So clearly, the "semantics" (meaning) of the program has changed. // So clearly, the "semantics" (meaning) of the program has changed.
// This is on purpose, Rust adopts "unchecked" (wrapping) additions (and subtractions) // This is on purpose, Rust adopts "unchecked" (wrapping) additions (and subtractions)
...@@ -288,16 +324,32 @@ const APP: () = { ...@@ -288,16 +324,32 @@ const APP: () = {
// //
// Paste the generated assembly: // Paste the generated assembly:
// //
// ** your answer here ** // ** My answer here **
/*
Dump of assembler code for function rtic_bare1::APP::main:
0x0800025a <+0>: push {r7, lr}
0x0800025c <+2>: mov r7, sp
0x0800025e <+4>: movw r0, #60688 ; 0xed10
=> 0x08000262 <+8>: cpsid i
0x08000264 <+10>: movt r0, #57344 ; 0xe000
0x08000268 <+14>: ldr r1, [r0, #0]
0x0800026a <+16>: orr.w r1, r1, #2
0x0800026e <+20>: str r1, [r0, #0]
0x08000270 <+22>: bl 0x8000240 <rtic_bare1::init>
End of assembler dump.
*/
// //
// Can this code generate a panic? // Can this code generate a panic?
// //
// ** your answer here ** // ** My answer here **
// No, there is no reference to the panic handler.
// //
// Is there now any reference to the panic handler? // Is there now any reference to the panic handler?
// If not, why is that the case? // If not, why is that the case?
// //
// ** your answer here ** // ** My answer here **
// The reference to the panic handler is not present anymore, which indicates that the
// compiler have found the code to be unable to generate a panic.
// //
// commit your answers (bare1_5) // commit your answers (bare1_5)
// //
...@@ -327,12 +379,22 @@ const APP: () = { ...@@ -327,12 +379,22 @@ const APP: () = {
// //
// Dump the generated assembly. // Dump the generated assembly.
// //
// ** your answer here ** // ** My answer here **
/*
Dump of assembler code for function rtic_bare1::init:
0x08000240 <+0>: push {r7, lr}
0x08000242 <+2>: mov r7, sp
=> 0x08000244 <+4>: bkpt 0x0000
0x08000246 <+6>: bkpt 0x0000
0x08000248 <+8>: b.n 0x8000244 <rtic_bare1::init+4>
End of assembler dump.
*/
// //
// Where is the local variable stored? // Where is the local variable stored?
// What happened, and why is Rust + LLVM allowed to optimize out your code? // What happened, and why is Rust + LLVM allowed to optimize out your code?
// //
// ** your answer here ** // ** My answer here **
// It is not stored anywhere, as it is optimized out. Since x is not used, the rust compiler removed it.
// //
// Commit your answers (bare1_6) // Commit your answers (bare1_6)
// //
......
...@@ -39,7 +39,7 @@ const APP: () = { ...@@ -39,7 +39,7 @@ const APP: () = {
hprintln!("End {:?}", end).ok(); hprintln!("End {:?}", end).ok();
hprintln!("Diff {:?}", end.wrapping_sub(start)).ok(); hprintln!("Diff {:?}", end.wrapping_sub(start)).ok();
// wait(100); wait(100);
} }
}; };
...@@ -61,7 +61,7 @@ fn wait(i: u32) { ...@@ -61,7 +61,7 @@ fn wait(i: u32) {
// If it does not auto-open, then copy paste the path shown in your browser. // If it does not auto-open, then copy paste the path shown in your browser.
// //
// Notice, it will try to document all dependencies, you may have only one // Notice, it will try to document all dependencies, you may have only one
// one panic handler, so temporarily comment out all but one in `Cargo.toml`. // panic handler, so temporarily comment out all but one in `Cargo.toml`.
// //
// In the docs, search (`S`) for DWT, and click `cortex_m::peripheral::DWT`. // In the docs, search (`S`) for DWT, and click `cortex_m::peripheral::DWT`.
// Read the API docs. // Read the API docs.
...@@ -71,16 +71,24 @@ fn wait(i: u32) { ...@@ -71,16 +71,24 @@ fn wait(i: u32) {
// What is the output in the Adapter Output console? // What is the output in the Adapter Output console?
// (Notice, it will take a while we loop one million times at only 16 MHz.) // (Notice, it will take a while we loop one million times at only 16 MHz.)
// //
// ** your answer here ** // ** My answer here **
// Start 233354
// End 167233437
// Diff 167000083
// //
// Rebuild and run in (Cortex Release). // Rebuild and run in (Cortex Release).
// //
// ** your answer here ** // ** My answer here **
// Start 1590210211
// End 1594210227
// Diff 4000016
// //
// Compute the ratio between debug/release optimized code // Compute the ratio between debug/release optimized code
// (the speedup). // (the speedup).
// //
// ** your answer here ** // ** My answer here **
// 167000083 / 4000016 = 41.75
// Release is 41.75 times faster than debug, or 4175% faster
// //
// commit your answers (bare2_1) // commit your answers (bare2_1)
// //
...@@ -105,7 +113,17 @@ fn wait(i: u32) { ...@@ -105,7 +113,17 @@ fn wait(i: u32) {
// //
// Dump generated assembly for the "wait" function. // Dump generated assembly for the "wait" function.
// //
// ** your answer here ** // ** My answer here **
/*
0x080004a0 <+0>: push {r7, lr}
0x080004a2 <+2>: mov r7, sp
0x080004a4 <+4>: movw r0, #16960 ; 0x4240
0x080004a8 <+8>: movt r0, #15
0x080004ac <+12>: nop
0x080004ae <+14>: subs r0, #1
0x080004b0 <+16>: bne.n 0x80004ac <rtic_bare2::wait+12>
=> 0x080004b2 <+18>: pop {r7, pc}
*/
// //
// Under the ARM calling convention, r0.. is used as arguments. // Under the ARM calling convention, r0.. is used as arguments.
// However in this case, we se that r0 is set by the assembly instructions, // However in this case, we se that r0 is set by the assembly instructions,
...@@ -115,7 +133,13 @@ fn wait(i: u32) { ...@@ -115,7 +133,13 @@ fn wait(i: u32) {
// //
// Answer in your own words, how they assign r0 to 1000000. // Answer in your own words, how they assign r0 to 1000000.
// //
// ** your answer here ** // ** My answer here **
// movw - This instruction will set the bottom half of the register
// to 16960, so the bottom half will be: 0100001001000000
// movt - This instruction will set the top half of the register
// to 15, so the top half will be: 0000000000001111
// Put together:
// 00000000000011110100001001000000 (binary) = 1000000 (decimal)
// //
// Commit your answers (bare2_2) // Commit your answers (bare2_2)
// //
...@@ -125,10 +149,20 @@ fn wait(i: u32) { ...@@ -125,10 +149,20 @@ fn wait(i: u32) {
// //
// Dump the generated assembly for the "wait" function. // Dump the generated assembly for the "wait" function.
// //
// ** your answer here ** // ** My answer here **
/*
0x080004a0 <+0>: push {r7, lr}
0x080004a2 <+2>: mov r7, sp
0x080004a4 <+4>: nop
0x080004a6 <+6>: subs r0, #1
0x080004a8 <+8>: bne.n 0x80004a4 <rtic_bare2::wait+4>
=> 0x080004aa <+10>: pop {r7, pc}
*/
// //
// Answer in your own words, why you believe the generated code differs? // Answer in your own words, why you believe the generated code differs?
// //
// ** your answer here ** // ** My answer here **
// Because the variable is different, if we change the second call to
// to contain the same variable we get the same generated code.
// //
// Commit your answers (bare2_3) // Commit your answers (bare2_3)
\ No newline at end of file
...@@ -23,12 +23,12 @@ const APP: () = { ...@@ -23,12 +23,12 @@ const APP: () = {
let start = Instant::now(); let start = Instant::now();
wait(1_000_000); wait(1_000_000);
let end = Instant::now(); let end = start.elapsed();
// notice all printing outside of the section to measure! // notice all printing outside of the section to measure!
hprintln!("Start {:?}", start).ok(); hprintln!("Start {:?}", start).ok();
hprintln!("End {:?}", end).ok(); hprintln!("End {:?}", end.as_cycles()).ok();
// hprintln!("Diff {:?}", (end - start) ).ok(); hprintln!("Diff {:?}", (end.as_cycles()) ).ok();
} }
}; };
...@@ -62,7 +62,9 @@ fn wait(i: u32) { ...@@ -62,7 +62,9 @@ fn wait(i: u32) {
// //
// What is the output in the Adapter Output console? // What is the output in the Adapter Output console?
// //
// ** your answer here ** // ** My answer here **
// Start Instant(2158334454)
// End Instant(2162334471)
// //
// As you see line 31 is commented out (we never print the difference). // As you see line 31 is commented out (we never print the difference).
// //
...@@ -76,7 +78,10 @@ fn wait(i: u32) { ...@@ -76,7 +78,10 @@ fn wait(i: u32) {
// //
// What is now the output in the Adapter Output console? // What is now the output in the Adapter Output console?
// //
// ** your answer here ** // ** My answer here **
// Start Instant(3665593903)
// End Instant(3669593919)
// Diff 4000016
// //
// Commit your answers (bare3_1) // Commit your answers (bare3_1)
// //
...@@ -86,7 +91,11 @@ fn wait(i: u32) { ...@@ -86,7 +91,11 @@ fn wait(i: u32) {
// //
// What is now the output in the Adapter Output console? // What is now the output in the Adapter Output console?
// //
// ** your answer here ** // ** My answer here **
// (Isn't this just the same exercise as 1?)
// Start Instant(3665593903)
// End Instant(3669593919)
// Diff 4000016
// //
// Commit your answers (bare3_2) // Commit your answers (bare3_2)
// //
...@@ -95,7 +104,10 @@ fn wait(i: u32) { ...@@ -95,7 +104,10 @@ fn wait(i: u32) {
// //
// What is now the output in the Adapter Output console? // What is now the output in the Adapter Output console?
// //
// ** your answer here ** // ** My answer here **
// Start Instant(1120238038)
// End 4000016
// Diff 4000016
// //
// Commit your answers (bare3_3) // Commit your answers (bare3_3)
// //
......
...@@ -83,7 +83,9 @@ const APP: () = { ...@@ -83,7 +83,9 @@ const APP: () = {
// //
// 1. Did you enjoy the blinking? // 1. Did you enjoy the blinking?
// //
// ** your answer here ** // ** My answer here **
// It was annoying in the corner of my vision and once I noticed it
// I couldn't unnotice it.
// //
// Now lookup the data-sheets, and read each section referred, // Now lookup the data-sheets, and read each section referred,
// 6.3.11, 8.4.1, 8.4.7 // 6.3.11, 8.4.1, 8.4.7
...@@ -100,12 +102,15 @@ const APP: () = { ...@@ -100,12 +102,15 @@ const APP: () = {
// //
// What was the error message and explain why. // What was the error message and explain why.
// //
// ** your answer here ** // ** My answer here **
// We're trying to use unsafe code outside of an unsafe bracket.
// //
// Digging a bit deeper, why do you think `read_volatile` is declared `unsafe`. // Digging a bit deeper, why do you think `read_volatile` is declared `unsafe`.
// (https://doc.rust-lang.org/core/ptr/fn.read_volatile.html, for some food for thought ) // (https://doc.rust-lang.org/core/ptr/fn.read_volatile.html, for some food for thought )
// //
// ** your answer here ** // ** My answer here **
// There are conditions, which if met, will have undefined behaviour.
// It's not that the function itself is always unsafe, but sometimes it can be.
// //
// Commit your answers (bare4_2) // Commit your answers (bare4_2)
// //
...@@ -118,16 +123,22 @@ const APP: () = { ...@@ -118,16 +123,22 @@ const APP: () = {
// //
// Why is it important that ordering of volatile operations are ensured by the compiler? // Why is it important that ordering of volatile operations are ensured by the compiler?
// //
// ** your answer here ** // ** My answer here **
// The volatile operations might have different results between accesses.
// //
// Give an example in the above code, where reordering might make things go horribly wrong // Give an example in the above code, where reordering might make things go horribly wrong
// (hint, accessing a peripheral not being powered...) // (hint, accessing a peripheral not being powered...)
// //
// ** your answer here ** // ** My answer here **
// I don't know about HORRIBLY wrong, but changing around the order in
// init will not show any errors, yet the led will not blink.
// //
// Without the non-reordering property of `write_volatile/read_volatile` could that happen in theory // Without the non-reordering property of `write_volatile/read_volatile` could that happen in theory
// (argue from the point of data dependencies). // (argue from the point of data dependencies).
// //
// ** your answer here ** // ** My answer here **
// If we are working with interrupts there's no guarantee that things will pan out
// the way we imagined it, which could interfer with volatile read / writes if the tasks
// work with the same register.
// //
// Commit your answers (bare4_3) // Commit your answers (bare4_3)
\ No newline at end of file
...@@ -58,7 +58,16 @@ mod stm32f40x { ...@@ -58,7 +58,16 @@ mod stm32f40x {
impl VolatileCell<u32> { impl VolatileCell<u32> {
#[inline(always)] #[inline(always)]
pub fn modify(&self, offset: u8, width: u8, value: u32) { pub fn modify(&self, offset: u8, width: u8, value: u32) {
// your code here let mut my_mask = 0;
let mut new_value = self.read();
let a = 2 as u32;
for i in 0..width{
my_mask += a.pow(i as u32);
}
new_value = new_value + (value & my_mask) * a.pow(offset as u32) - (new_value & (my_mask * a.pow(offset as u32)));
//let new_value = my_mask; //Test function
&self.write(new_value);
} }
} }
...@@ -177,24 +186,24 @@ const APP: () = { ...@@ -177,24 +186,24 @@ const APP: () = {
let r = gpioa.MODER.read() & !(0b11 << (5 * 2)); // read and mask let r = gpioa.MODER.read() & !(0b11 << (5 * 2)); // read and mask
gpioa.MODER.write(r | 0b01 << (5 * 2)); // set output mode gpioa.MODER.write(r | 0b01 << (5 * 2)); // set output mode
// test_modify(); test_modify();
loop { loop {
// set PA5 high // set PA5 high
gpioa.BSRRH.write(1 << 5); // set bit, output hight (turn on led) // gpioa.BSRRH.write(1 << 5); // set bit, output hight (turn on led)
// alternatively to set the bit high we can // alternatively to set the bit high we can
// read the value, or with PA5 (bit 5) and write back // read the value, or with PA5 (bit 5) and write back
// gpioa.ODR.write(gpioa.ODR.read() | (1 << 5)); gpioa.ODR.write(gpioa.ODR.read() | (1 << 5));
wait(10_000); wait(10_000);
// set PA5 low // set PA5 low
gpioa.BSRRL.write(1 << 5); // clear bit, output low (turn off led) // gpioa.BSRRL.write(1 << 5); // clear bit, output low (turn off led)
// alternatively to clear the bit we can // alternatively to clear the bit we can
// read the value, mask out PA5 (bit 5) and write back // read the value, mask out PA5 (bit 5) and write back
// gpioa.ODR.write(gpioa.ODR.read() & !(1 << 5)); gpioa.ODR.write(gpioa.ODR.read() & !(1 << 5));
wait(10_000); wait(10_000);
} }
} }
......
...@@ -55,28 +55,28 @@ const APP: () = { ...@@ -55,28 +55,28 @@ const APP: () = {
let rcc = device.RCC.constrain(); let rcc = device.RCC.constrain();
let _clocks = rcc.cfgr.freeze(); //let _clocks = rcc.cfgr.freeze();
// Set up the system clock. 48 MHz? // Set up the system clock. 48 MHz?
// let _clocks = rcc /*let _clocks = rcc
// .cfgr .cfgr
// .sysclk(48.mhz()) .sysclk(48.mhz())
// .pclk1(24.mhz()) .pclk1(24.mhz())
// .freeze(); .freeze(); */
// let _clocks = rcc /*let _clocks = rcc
// .cfgr .cfgr
// .sysclk(64.mhz()) .sysclk(64.mhz())
// .pclk1(64.mhz()) .pclk1(64.mhz())
// .pclk2(64.mhz()) .pclk2(64.mhz())
// .freeze(); .freeze();*/
//
// let _clocks = rcc let _clocks = rcc
// .cfgr .cfgr
// .sysclk(84.mhz()) .sysclk(84.mhz())
// .pclk1(42.mhz()) .pclk1(42.mhz())
// .pclk2(64.mhz()) .pclk2(64.mhz())
// .freeze(); .freeze();
// pass on late resources // pass on late resources
init::LateResources { init::LateResources {
...@@ -121,23 +121,26 @@ fn clock_out(rcc: &RCC, gpioc: &GPIOC) { ...@@ -121,23 +121,26 @@ fn clock_out(rcc: &RCC, gpioc: &GPIOC) {
// mco2 : SYSCLK = 0b00 // mco2 : SYSCLK = 0b00
// mcopre : divide by 4 = 0b110 // mcopre : divide by 4 = 0b110
//rcc.cfgr
// .modify(|_, w| unsafe { w.mco2().bits(0b00).mco2pre().bits(0b110) });
rcc.cfgr rcc.cfgr
.modify(|_, w| unsafe { w.mco2().bits(0b00).mco2pre().bits(0b110) }); .modify(|_, w| unsafe { w.mco2().sysclk().mco2pre().div4() });
// power on GPIOC, RM0368 6.3.11 // power on GPIOC, RM0368 6.3.11
rcc.ahb1enr.modify(|_, w| w.gpiocen().set_bit()); rcc.ahb1enr.modify(|_, w| w.gpiocen().enabled());
// MCO_2 alternate function AF0, STM32F401xD STM32F401xE data sheet // MCO_2 alternate function AF0, STM32F401xD STM32F401xE data sheet
// table 9 // table 9
// AF0, gpioc reset value = AF0 // AF0, gpioc reset value = AF0
// configure PC9 as alternate function 0b10, RM0368 6.2.10 // configure PC9 as alternate function 0b10, RM0368 6.2.10
gpioc.moder.modify(|_, w| w.moder9().bits(0b10)); //gpioc.moder.modify(|_, w| w.moder9().bits(0b10));
gpioc.moder.modify(|_, w| w.moder9().alternate());
// otyper reset state push/pull, in reset state (don't need to change) // otyper reset state push/pull, in reset state (don't need to change)
// ospeedr 0b11 = very high speed // ospeedr 0b11 = very high speed
gpioc.ospeedr.modify(|_, w| w.ospeedr9().bits(0b11)); gpioc.ospeedr.modify(|_, w| w.ospeedr9().very_high_speed());
} }
// 0. Background reading: // 0. Background reading:
...@@ -202,11 +205,14 @@ fn clock_out(rcc: &RCC, gpioc: &GPIOC) { ...@@ -202,11 +205,14 @@ fn clock_out(rcc: &RCC, gpioc: &GPIOC) {
// //
// `rcc.cfgr.sysclk(64.mhz()).pclk1(64.mhz()).pclk2(64.mhz()).freeze()`; // `rcc.cfgr.sysclk(64.mhz()).pclk1(64.mhz()).pclk2(64.mhz()).freeze()`;
// //
// ** your answer here ** // ** My answer here **
// pclk1 can only handle up to 42mhz
// //
// `rcc.cfgr.sysclk(84.mhz()).pclk1(42.mhz()).pclk2(64.mhz()).freeze();` // `rcc.cfgr.sysclk(84.mhz()).pclk1(42.mhz()).pclk2(64.mhz()).freeze();`
// //
// ** your answer here ** // ** My answer here **
// the pclk1 and pclk2 configurations (42 and 64) doesn't seem to be compatible with the sysclk.
// The pclk1 and pclk2 clock speeds need to be sysclk / (1 or 2 or 4 or 8 or 16) to be compatible.
// //
// Start `stm32cubemx` and select or create a project targeting stm32f401. // Start `stm32cubemx` and select or create a project targeting stm32f401.
// Go to the graphical clock configuration view. // Go to the graphical clock configuration view.
...@@ -217,7 +223,8 @@ fn clock_out(rcc: &RCC, gpioc: &GPIOC) { ...@@ -217,7 +223,8 @@ fn clock_out(rcc: &RCC, gpioc: &GPIOC) {
// //
// What happens? // What happens?
// //
// ** your answer here ** // ** My answer here **
// Pclk1 is too fast, it has a limit of 42 mhz
// //
// Try to setup the clock according to: // Try to setup the clock according to:
// //
...@@ -225,7 +232,9 @@ fn clock_out(rcc: &RCC, gpioc: &GPIOC) { ...@@ -225,7 +232,9 @@ fn clock_out(rcc: &RCC, gpioc: &GPIOC) {
// //
// `rcc.cfgr.sysclk(84.mhz()).pclk1(42.mhz()).pclk2(64.mhz()).freeze();` // `rcc.cfgr.sysclk(84.mhz()).pclk1(42.mhz()).pclk2(64.mhz()).freeze();`
// //
// ** your answer here ** // ** My answer here **
// Since the pclk1 and pclk2 has to be in relation to sysclk according to:
// pclk(x) = sysclk / (1 or 2 or 4 or 8 or 16), this makes pclk2 and sysclk incompatible in this case.
// //
// Commit your answers (bare6_0) // Commit your answers (bare6_0)
// //
...@@ -237,7 +246,8 @@ fn clock_out(rcc: &RCC, gpioc: &GPIOC) { ...@@ -237,7 +246,8 @@ fn clock_out(rcc: &RCC, gpioc: &GPIOC) {
// //
// What is the (default) MCU (SYSCLK) frequency? // What is the (default) MCU (SYSCLK) frequency?
// //
// ** your answer here ** // ** My answer here **
// 16 mhz
// //
// What is the (default) DWT CYCCNT frequency? // What is the (default) DWT CYCCNT frequency?
// //
...@@ -245,7 +255,9 @@ fn clock_out(rcc: &RCC, gpioc: &GPIOC) { ...@@ -245,7 +255,9 @@ fn clock_out(rcc: &RCC, gpioc: &GPIOC) {
// //
// What is the frequency of blinking? // What is the frequency of blinking?
// //
// ** your answer here ** // ** My answer here **
// 8 000 000 / (16 * 10^6) = 0.5 seconds in between toggles, blinks with a frequency of 1 hz
// This can be confirmed in the tracing as well (8 000 000 difference)
// //
// Commit your answers (bare6_1) // Commit your answers (bare6_1)
// //
...@@ -254,11 +266,15 @@ fn clock_out(rcc: &RCC, gpioc: &GPIOC) { ...@@ -254,11 +266,15 @@ fn clock_out(rcc: &RCC, gpioc: &GPIOC) {
// //
// Compute the value of SYSCLK based on the oscilloscope reading // Compute the value of SYSCLK based on the oscilloscope reading
// //
// ** your answer here ** // ** My answer here **
// Since the SYSCLK is sent directly to MCO2 we just need to measurement
// Measured frequency: 4 Mhz
// SYCLK = 4 * 4 = 16 Mhz.
// //
// What is the peak to peak (voltage) reading of the signal? // What is the peak to peak (voltage) reading of the signal?
// //
// ** your answer here ** // ** My answer here **
// Delta Y: Around 3.5V
// //
// Make a folder called "pictures" in your git project. // Make a folder called "pictures" in your git project.
// Make a screen dump or photo of the oscilloscope output. // Make a screen dump or photo of the oscilloscope output.
...@@ -271,7 +287,9 @@ fn clock_out(rcc: &RCC, gpioc: &GPIOC) { ...@@ -271,7 +287,9 @@ fn clock_out(rcc: &RCC, gpioc: &GPIOC) {
//` //`
// What is the frequency of blinking? // What is the frequency of blinking?
// //
// ** your answer here ** // ** My answer here **
// 8 000 000 / (48 * 10^6) = 1 / 6 in between toggles
// The led blinks with a frequency of 3 hz
// //
// Now change the constant `OFFSET` so you get the same blinking frequency as in 1. // Now change the constant `OFFSET` so you get the same blinking frequency as in 1.
// Test and validate that you got the desired behavior. // Test and validate that you got the desired behavior.
...@@ -282,15 +300,20 @@ fn clock_out(rcc: &RCC, gpioc: &GPIOC) { ...@@ -282,15 +300,20 @@ fn clock_out(rcc: &RCC, gpioc: &GPIOC) {
// //
// What is the frequency of MCO2 read by the oscilloscope? // What is the frequency of MCO2 read by the oscilloscope?
// //
// ** your answer here ** // ** My answer here **
// 12 Mhz, which is three times the reading for 16 Mhz
// Getting an increase of 3 when we increase the clock frequency by a factor of three seems logical.
// //
// Compute the value of SYSCLK based on the oscilloscope reading. // Compute the value of SYSCLK based on the oscilloscope reading.
// //
// ** your answer here ** // ** My answer here **
// It's 48 Mhz (4 * 12)
// //
// What is the peak to peak reading of the signal? // What is the peak to peak reading of the signal?
// //
// ** your answer here ** // ** My answer here **
// 5.4V, this seems like a bit much.
// We get 4.4V if we disconnect the ground.
// //
// Make a screen dump or photo of the oscilloscope output. // Make a screen dump or photo of the oscilloscope output.
// Save the the picture as "bare_6_48mhz_high_speed". // Save the the picture as "bare_6_48mhz_high_speed".
...@@ -319,17 +342,27 @@ fn clock_out(rcc: &RCC, gpioc: &GPIOC) { ...@@ -319,17 +342,27 @@ fn clock_out(rcc: &RCC, gpioc: &GPIOC) {
// //
// Test that the application still runs as before. // Test that the application still runs as before.
// //
// ** My answer here **
// Fixed, works as before.
//
// Commit your code (bare6_5) // Commit your code (bare6_5)
// //
// 6. Now reprogram the PC9 to be "Low Speed", and re-run at 48Mz. // 6. Now reprogram the PC9 to be "Low Speed", and re-run at 48Mz.
// //
// Did the frequency change in comparison to assignment 5? // Did the frequency change in comparison to assignment 5?
// //
// ** your answer here ** // ** My answer here **
// No, we still get 4 Mhz
// //
// What is the peak to peak reading of the signal (and why did it change)? // What is the peak to peak reading of the signal (and why did it change)?
// //
// ** your answer here ** // ** My answer here **
// It dropped by 1v from 5.4 to 4.4ish.
// As to the reason why, it's a bit unclear.
// My best guess is that during the high_speed run we are updating so often
// that we appproach the voltage of our power supply (5v), and since the speed is
// lowered to low_speed, this will simply happen less often and we get futher away from
// the voltage of our power supply.
// //
// Make a screen dump or photo of the oscilloscope output. // Make a screen dump or photo of the oscilloscope output.
// Save the the picture as "bare_6_48mhz_low_speed". // Save the the picture as "bare_6_48mhz_low_speed".
...@@ -342,11 +375,13 @@ fn clock_out(rcc: &RCC, gpioc: &GPIOC) { ...@@ -342,11 +375,13 @@ fn clock_out(rcc: &RCC, gpioc: &GPIOC) {
// //
// Does the code compile? // Does the code compile?
// //
// ** your answer here ** // ** My answer here **
// The compiler doesn't know that the settings are incorrect, so yes.
// //
// What happens at run-time? // What happens at run-time?
// //
// ** your answer here ** // ** My answer here **
// During runtime we get a panic
// //
// Try setting the clocks according to: // Try setting the clocks according to:
// //
...@@ -354,11 +389,16 @@ fn clock_out(rcc: &RCC, gpioc: &GPIOC) { ...@@ -354,11 +389,16 @@ fn clock_out(rcc: &RCC, gpioc: &GPIOC) {
// //
// Does the code compile? // Does the code compile?
// //
// ** your answer here ** // ** My answer here **
// Yes, as there are no coding errors.
// //
// What happens at run-time? // What happens at run-time?
// //
// ** your answer here ** // ** My answer here **
// It flashes the LED really fast, which is weird, according to STM32cubeMX
// these settings hould be incompatible.
// We can't get any measurements from the board, which was the expected outcome,
// but it's a bit weird that there is no panic.
// //
// Is that a correct? // Is that a correct?
// //
......
...@@ -17,7 +17,7 @@ use stm32f4xx_hal::{ ...@@ -17,7 +17,7 @@ use stm32f4xx_hal::{
gpio::{gpioa::PA5, Output, PushPull}, gpio::{gpioa::PA5, Output, PushPull},
prelude::*, prelude::*,
}; };
;
use embedded_hal::digital::v2::{OutputPin, ToggleableOutputPin}; use embedded_hal::digital::v2::{OutputPin, ToggleableOutputPin};
const OFFSET: u32 = 8_000_000; const OFFSET: u32 = 8_000_000;
...@@ -26,8 +26,8 @@ const OFFSET: u32 = 8_000_000; ...@@ -26,8 +26,8 @@ const OFFSET: u32 = 8_000_000;
const APP: () = { const APP: () = {
struct Resources { struct Resources {
// late resources // late resources
GPIOA: stm32::GPIOA, //GPIOA: stm32::GPIOA,
// led: PA5<Output<PushPull>>, led: PA5<Output<PushPull>>, //PA5 implements output
} }
#[init(schedule = [toggle])] #[init(schedule = [toggle])]
fn init(cx: init::Context) -> init::LateResources { fn init(cx: init::Context) -> init::LateResources {
...@@ -55,7 +55,8 @@ const APP: () = { ...@@ -55,7 +55,8 @@ const APP: () = {
// pass on late resources // pass on late resources
init::LateResources { init::LateResources {
GPIOA: device.GPIOA, //GPIOA: device.GPIOA,
led: device.GPIOA.split().pa5.into_push_pull_output(), //split the GPIOA into pins, choose pa5 and convert into push/pull output (this took a while to figure out)
} }
} }
...@@ -67,18 +68,22 @@ const APP: () = { ...@@ -67,18 +68,22 @@ const APP: () = {
} }
} }
#[task(resources = [GPIOA], schedule = [toggle])] #[task(resources = [led], schedule = [toggle])]
fn toggle(cx: toggle::Context) { fn toggle(cx: toggle::Context) {
static mut TOGGLE: bool = false; //static mut TOGGLE: bool = false; //Uncomment when variable no longer needed
rprintln!("toggle @ {:?}", Instant::now()); rprintln!("toggle @ {:?}", Instant::now());
/*
if *TOGGLE { if *TOGGLE {
cx.resources.GPIOA.bsrr.write(|w| w.bs5().set_bit()); cx.resources.led.set_high().ok(); //Change out GPIO for led
} else { } else {
cx.resources.GPIOA.bsrr.write(|w| w.br5().set_bit()); cx.resources.led.set_low().ok(); //Change out GPIO for led
} }
*/
*TOGGLE = !*TOGGLE; //*TOGGLE = !*TOGGLE;
//_toggle_generic(cx.resources.led, TOGGLE); //Pass led resource and toggle to generic function
_toggleable_generic(cx.resources.led); //Utilize the generic toggle function, toggle variable no longer needed
cx.schedule.toggle(cx.scheduled + OFFSET.cycles()).unwrap(); cx.schedule.toggle(cx.scheduled + OFFSET.cycles()).unwrap();
} }
...@@ -122,6 +127,13 @@ fn _toggleable_generic<E>(led: &mut dyn ToggleableOutputPin<Error = E>) { ...@@ -122,6 +127,13 @@ fn _toggleable_generic<E>(led: &mut dyn ToggleableOutputPin<Error = E>) {
// //
// Comment your code to explain the steps taken. // Comment your code to explain the steps taken.
// //
// ** My answer here **
// 1. We had to change around in the resources, as the GPIO is no longer needed
// this means that we have to uncomment the led variable in the resources struct
// and insert the correct struct into lateresources.
// 2. Now we have our resources set up, so I changed the GPIO into led under the
// toggle function.
//
// Confirm that your implementation correctly toggles the LED as in // Confirm that your implementation correctly toggles the LED as in
// previous exercise. // previous exercise.
// //
...@@ -163,6 +175,9 @@ fn _toggleable_generic<E>(led: &mut dyn ToggleableOutputPin<Error = E>) { ...@@ -163,6 +175,9 @@ fn _toggleable_generic<E>(led: &mut dyn ToggleableOutputPin<Error = E>) {
// //
// Commit your code (bare7_2) // Commit your code (bare7_2)
// //
// ** My answer here **
// This was merely a question of passing the toggle variable to the generic function.
//
// 3. What about the state? // 3. What about the state?
// //
// In your code `TOGGLE` holds the "state". However, the underlying // In your code `TOGGLE` holds the "state". However, the underlying
...@@ -186,6 +201,13 @@ fn _toggleable_generic<E>(led: &mut dyn ToggleableOutputPin<Error = E>) { ...@@ -186,6 +201,13 @@ fn _toggleable_generic<E>(led: &mut dyn ToggleableOutputPin<Error = E>) {
// Confirm that your implementation correctly toggles the LED as in // Confirm that your implementation correctly toggles the LED as in
// previous exercise. // previous exercise.
// //
// ** My answer here **
// This is merely a question of uncommenting the toggle variable, as well
// as the calls to the functions we are not to use. Since the toggleable_generic
// works in the same was as toggle_generic, in the sense that it generically
// handles pins which we can read and write from, so passing the led resource
// is enough.
//
// Commit your code (bare7_3) // Commit your code (bare7_3)
// //
// 4. Discussion: // 4. Discussion:
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
use panic_rtt_target as _; use panic_rtt_target as _;
use nb::block; use stm32f4xx_hal::nb::block;
use stm32f4xx_hal::{ use stm32f4xx_hal::{
gpio::{gpioa::PA, Output, PushPull}, gpio::{gpioa::PA, Output, PushPull},
...@@ -69,15 +69,21 @@ const APP: () = { ...@@ -69,15 +69,21 @@ const APP: () = {
fn idle(cx: idle::Context) -> ! { fn idle(cx: idle::Context) -> ! {
let rx = cx.resources.RX; let rx = cx.resources.RX;
let tx = cx.resources.TX; let tx = cx.resources.TX;
let mut received = 0;
let mut errors = 0;
loop { loop {
match block!(rx.read()) { match block!(rx.read()) {
Ok(byte) => { Ok(byte) => {
rprintln!("Ok {:?}", byte); //rprintln!("Ok {:?}", byte);
received += 1;
rprintln!("Received: {:?}", received);
tx.write(byte).unwrap(); tx.write(byte).unwrap();
} }
Err(err) => { Err(err) => {
rprintln!("Error {:?}", err); //rprintln!("Error {:?}", err);
errors += errors;
rprintln!("Errors: {:?}", errors);
} }
} }
} }
...@@ -113,31 +119,40 @@ const APP: () = { ...@@ -113,31 +119,40 @@ const APP: () = {
// //
// What do you receive in `moserial`? // What do you receive in `moserial`?
// //
// ** your answer here ** // ** My answer here **
// a
// //
// What do you receive in the RTT terminal? // What do you receive in the RTT terminal?
// //
// ** your answer here ** // ** My answer here **
// Ok 97
// //
// Try sending: "abcd" as a single sequence, don't send the quotation marks, just abcd. // Try sending: "abcd" as a single sequence, don't send the quotation marks, just abcd.
// //
// What did you receive in `moserial`? // What did you receive in `moserial`?
// //
// ** your answer here ** // ** My answer here **
// abcd
// //
// What do you receive in the RTT terminal? // What do you receive in the RTT terminal?
// //
// ** your answer here ** // ** My answer here **
// Ok 97
// Ok 98
// Ok 99
// Ok 100
// //
// What do you believe to be the problem? // What do you believe to be the problem?
// //
// Hint: Look at the code in `idle` what does it do? // Hint: Look at the code in `idle` what does it do?
// //
// ** your answer here ** // ** My answer here **
// There doesn't seem to be a problem...
// //
// Experiment a bit, what is the max length sequence you can receive without errors? // Experiment a bit, what is the max length sequence you can receive without errors?
// //
// ** your answer here ** // ** My answer here **
// I can send 16 letters, after that they simply don't show up but I don't get an error message...
// //
// Commit your answers (bare8_1) // Commit your answers (bare8_1)
// //
...@@ -152,11 +167,13 @@ const APP: () = { ...@@ -152,11 +167,13 @@ const APP: () = {
// //
// 3. Experiment a bit, what is the max length sequence you can receive without errors? // 3. Experiment a bit, what is the max length sequence you can receive without errors?
// //
// ** your answer here ** // ** My answer here **
// I can send 16 letters, but I don't get errors afterwards, they simply don't show up.
// //
// How did the added tracing/instrumentation affect the behavior? // How did the added tracing/instrumentation affect the behavior?
// //
// ** your answer here ** // ** My answer here **
// Not at all.
// //
// Commit your answer (bare8_3) // Commit your answer (bare8_3)
// //
...@@ -168,7 +185,8 @@ const APP: () = { ...@@ -168,7 +185,8 @@ const APP: () = {
// //
// Experiment a bit, what is the max length sequence you can receive without errors? // Experiment a bit, what is the max length sequence you can receive without errors?
// //
// ** your answer here ** // ** My answer here **
// It's still 16 letters, and it still refuses to produce any errors.
// //
// Commit your answer (bare8_4) // Commit your answer (bare8_4)
// //
......
//! bare8.rs //! bare9.rs
//! //!
//! Serial //! Serial
//! //!
...@@ -17,6 +17,7 @@ use stm32f4xx_hal::{ ...@@ -17,6 +17,7 @@ use stm32f4xx_hal::{
use rtic::app; use rtic::app;
use rtt_target::{rprintln, rtt_init_print}; use rtt_target::{rprintln, rtt_init_print};
use stm32f4xx_hal::nb::block;
#[app(device = stm32f4xx_hal::stm32, peripherals = true)] #[app(device = stm32f4xx_hal::stm32, peripherals = true)]
const APP: () = { const APP: () = {
...@@ -24,6 +25,8 @@ const APP: () = { ...@@ -24,6 +25,8 @@ const APP: () = {
// Late resources // Late resources
TX: Tx<USART2>, TX: Tx<USART2>,
RX: Rx<USART2>, RX: Rx<USART2>,
Errors: u16,
Received: u16,
} }
// init runs in an interrupt free section // init runs in an interrupt free section
...@@ -44,6 +47,9 @@ const APP: () = { ...@@ -44,6 +47,9 @@ const APP: () = {
let tx = gpioa.pa2.into_alternate_af7(); let tx = gpioa.pa2.into_alternate_af7();
let rx = gpioa.pa3.into_alternate_af7(); let rx = gpioa.pa3.into_alternate_af7();
let mut received = 0;
let mut errors = 0;
let mut serial = Serial::usart2( let mut serial = Serial::usart2(
device.USART2, device.USART2,
(tx, rx), (tx, rx),
...@@ -59,7 +65,7 @@ const APP: () = { ...@@ -59,7 +65,7 @@ const APP: () = {
let (tx, rx) = serial.split(); let (tx, rx) = serial.split();
// Late resources // Late resources
init::LateResources { TX: tx, RX: rx } init::LateResources { TX: tx, RX: rx, Errors: errors, Received: received }
} }
// idle may be interrupted by other interrupts/tasks in the system // idle may be interrupted by other interrupts/tasks in the system
...@@ -71,19 +77,34 @@ const APP: () = { ...@@ -71,19 +77,34 @@ const APP: () = {
} }
// capacity sets the size of the input buffer (# outstanding messages) // capacity sets the size of the input buffer (# outstanding messages)
#[task(resources = [TX], priority = 1, capacity = 128)] #[task(resources = [TX], priority = 1, capacity = 126)]
fn rx(cx: rx::Context, data: u8) { fn rx(cx: rx::Context, data: u8) {
let tx = cx.resources.TX; let tx = cx.resources.TX;
tx.write(data).unwrap(); tx.write(data).unwrap();
rprintln!("data {}", data); //rprintln!("data {}", data);
} }
// Task bound to the USART2 interrupt. // Task bound to the USART2 interrupt.
#[task(binds = USART2, priority = 2, resources = [RX], spawn = [rx])] #[task(binds = USART2, priority = 2, resources = [RX, Received, Errors], spawn = [rx])]
fn usart2(cx: usart2::Context) { fn usart2(cx: usart2::Context) {
let rx = cx.resources.RX; let rx = cx.resources.RX;
let data = rx.read().unwrap(); let mut received = cx.resources.Received;
cx.spawn.rx(data).unwrap(); let mut errors = cx.resources.Errors;
//let data = rx.read().unwrap();
//cx.spawn.rx(data).unwrap();
match block!(rx.read()) { // Move the read into block, saves a few cycles
Ok(byte) => { // Obligatory line, byte seems to be a standard
//rprintln!("Ok {:?}", byte);
*received += 1;
//rprintln!("Received: {:?}", received);
cx.spawn.rx(byte).unwrap(); // Write to the transceiver
}
Err(err) => {
//rprintln!("Error {:?}", err);
*errors += 1;
rprintln!("Errors: {:?}", errors);
}
}
} }
extern "C" { extern "C" {
...@@ -148,7 +169,8 @@ const APP: () = { ...@@ -148,7 +169,8 @@ const APP: () = {
// //
// Were you able to crash it? // Were you able to crash it?
// //
// ** your answer here ** // ** My answer here **
// No, we were not able to "crash" it
// //
// Notice, the input tracing in `moserial` seems broken, and may loose data. // Notice, the input tracing in `moserial` seems broken, and may loose data.
// So don't be alarmed if data is missing, its a GUI tool after all. // So don't be alarmed if data is missing, its a GUI tool after all.
...@@ -194,6 +216,13 @@ const APP: () = { ...@@ -194,6 +216,13 @@ const APP: () = {
// //
// Once finished, comment your code. // Once finished, comment your code.
// //
// ** My answer here **
// By copying the received / error function from bare8 we get the functionality which was requested,
// but we produce a few errors during manual stress tests (at around 1 error per 150 characters).
// To get rid of these errors we simply reduce the program to only "report" on errors and not
// received characters.
// To produce the errors agin, simply uncomment the "reporting" of data and received.
//
// Commit your code (bare9_2) // Commit your code (bare9_2)
// //
// 3. Discussion // 3. Discussion
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment