In embedded programming, a memory-mapped peripheral can be accessed through a structure placed at the correct address. How do I ensure memory accesses to the peripheral are indeed performed on the bus in Rust? In C, this would be done by making the variable or fields volatile
.
Consider this example:
#[repr(C)]
struct Periph {
sr: u32, /* Status */
cr: u32, /* Control */
dr: u32, /* Data */
}
const PERIPH1: *mut Periph = 0x10001200 as *mut Periph;
const PERIPH2: *mut Periph = 0x10001400 as *mut Periph;
fn useperiph(p: &mut Periph) -> i32 {
p.cr = CR_CONSTANT;
if p.cr != CR_CONSTANT {
/* Peripheral was not enabled */
return -1;
}
/* Loop a few micro seconds until ready */
while p.sr != SR_CONSTANT {}
/* Write values to hardware FIFO */
p.dr = DATA1;
p.dr = DATA2;
p.dr = DATA3;
0
}
I need to ensure that the compiler won't remove the check on the control register, will leave all loads of the status register, and won't collapse the three stores to the data register. How do I do that?