//! bare0.rs //! Simple bare metal application // feature to ensure symbols to be linked #![feature(used)] // build without the Rust standard library #![no_std] // Minimal runtime / startup for Cortex-M microcontrollers extern crate cortex_m_rt; const X_INIT: u32 = 10; static mut X: u32 = X_INIT; static mut Y: u32 = 0; #[inline(never)] fn main() { let mut x = unsafe { X }; loop { x += 1; unsafe { X += 1; Y = X; assert!(x == X && X == Y); } } } } // 1. run the program in the debugger, // let the program run for a while and then press pause // look in the (Local -vscode) Variables view what do you find // x: 7852532 // // in the Expressions (WATCH -vscode) view add X and Y // what do you find // // X: 785232 // Y: 785232 // step through one complete iteration of the loop // and see how the (Local) Variables are updated // can you foresee what will eventually happen? // Yes // // commit your answers (bare0_1) // // 2. alter the constant X_INIT so that line 22 directly causes the x to wrap // what happens when x wraps // ** your answer here ** // // commit your answers (bare0_2) // // 3. change += opertions to wrapping_add // place a breakpoint at line 22 // load and run the progam, what happens // ** your answer here ** // // now continue exectution, what happens // ** your answer here ** // // commit your answers (bare0_3) // // (if the program did not succed back to the breakpoint // you have some fault in the program and go back to 3) // // 4. change the asserion to assert!(x == X && X == Y + 1), what happens // ** place your answer here ** // // commit your answers (bare0_4) // // 5. remove the assertion and // // make "safe" functions for reading and writing X and Y // e.g. read_x, read_y, write_x, write_y // // rewrite the program to use ONLY "safe" code besides the // read/write functions (which are internally "unsafe") // // commit your solution (bare0_5) // // 6*. optional // implement a read_u32/write_u32, taking a reference to a // "static" variable // // rewrite the program to use this abstraction instead of "read_x", etc. // // commit your solution (bare0_6) // // As we are not using interrupts, we just register a dummy catch all handler #[link_section = ".vector_table.interrupts"] #[used] static INTERRUPTS: [extern "C" fn(); 240] = [default_handler; 240]; extern "C" fn default_handler() { loop {} }