Multiple registers
We can use a struct to represent the memory layout of the UART’s registers.
#[repr(C, align(4))]struct Registers {dr: u16,_reserved0: [u8; 2],rsr: ReceiveStatus,_reserved1: [u8; 19],fr: Flags,_reserved2: [u8; 6],ilpr: u8,_reserved3: [u8; 3],ibrd: u16,_reserved4: [u8; 2],fbrd: u8,_reserved5: [u8; 3],lcr_h: u8,_reserved6: [u8; 3],cr: u16,_reserved7: [u8; 3],ifls: u8,_reserved8: [u8; 3],imsc: u16,_reserved9: [u8; 2],ris: u16,_reserved10: [u8; 2],mis: u16,_reserved11: [u8; 2],icr: u16,_reserved12: [u8; 2],dmacr: u8,_reserved13: [u8; 3],}
- #[repr(C)] tells the compiler to lay the struct fields out in order, following the same rules as C. This is necessary for our struct to have a predictable layout, as default Rust representation allows the compiler to (among other things) reorder fields however it sees fit.