I'm trying to make "Blinky" for STM32F1xx in Rust. I know that there are libs for it, but I want to make my own "lib" for learning purposes.
I can access STM32's "registers" by their addresses like this in C:
*(uint32_t*)(0x40021000 + 0x018) |= 0x10;
*(uint32_t*)(0x40011000 + 0x004) |= 0x33;
*(uint32_t*)(0x40011000 + 0x004) &= ~0xCC;
*(uint32_t*)(0x40011000 + 0x10) |= 0x300;
while(1) {}
This writes some bits to the RCC_APB2ENR
register to enable clocking of port C, configures pins and enables LEDs on my Discovery.
I need to re-write this it in Rust, to make consts, fns and start writing nice Rusty code. Is it possible in Rust without FFI calling C code? Can I achieve this with the asm!
macro?
In C you should declare your pointers as volatile
when accessing hardware registers, so that the compiler does the accesses exactly as you program them. Otherwise it could reorder them or eliminate duplicate accesses to the same register.
Since Rust 1.9 (thanks to this RFC) you can use core::ptr::read_volatile
and core::ptr::write_volatile
to read and write to such memory.
If you have an older version of Rust, these are available as volatile_read
and volatile_store
in core::intrinsics, which however are permanently unstable, and thus require a nightly version of Rust to access them.