How to make an access volatile without std library?

Ideally, you should never create references to volatile memory, and always use raw pointers. It's best to do something like this:

#[repr(C)]
struct UartMmapRegs {
   txdata: u32, /*  Transmit data */
   rxdata: u32, /* Receive data  */
   txctrl: u32, /* Tx control */
   rxctrl: u32, /* Rx Control */
   ie: u32, /* Interrupt enable */
   ip: u32, /* Interrupt pending */
   div: u32, /* Divisor */
}

pub struct UartMmapRegsPtr {
    ptr: *mut UartMmapRegs,
}

impl UartMmapRegsPtr {
    pub fn receive(&self) -> u32 {
        unsafe {
            let ptr = self.ptr;
            let field_ptr = core::ptr::addr_of!(ptr.rxdata);
            core::ptr::read_volatile(field_ptr) & DATA_SEG_BMASK
        }
    }
}

This uses a wrapper struct to avoid creating a &UartMmapRegs as &self when calling the method, and uses addr_of! to convert the struct ptr into a field ptr without an intermediate reference.

6 Likes