···1818use mcp9808::reg_conf::{Configuration, ShutdownMode};
1919use mcp9808::reg_res::ResolutionVal;
2020use mcp9808::reg_temp_generic::ReadableTempRegister;
2121+use once_cell::sync::OnceCell;
2122use portable_atomic::{AtomicBool, AtomicU128, AtomicU8};
2223use portable_atomic::Ordering;
2324use usb_device::bus::UsbBusAllocator;
···5960static mut GLOBAL_USB_BUS: Option<UsbBusAllocator<hal::usb::UsbBus>> = None;
6061static mut GLOBAL_USB_SERIAL: Option<SerialPort<hal::usb::UsbBus>> = None;
61626262-static mut SERIAL_NUMBER: [u8; 16] = [b'X'; 16];
6363+static SERIAL_NUMBER: OnceCell<[u8; 16]> = OnceCell::new();
63646465static TOUCH_EVENT_BUFFER: Mutex<RefCell<TouchEventBuffer>> = Mutex::new(RefCell::new(TouchEventBuffer::new()));
6566static TOUCH_ENABLED: AtomicBool = AtomicBool::new(false);
···8990 }
9091}
91929292-// Safety: The only time a mutable reference to SERIAL_NUMBER is created is right
9393-// at the start of the program when the serial number is read from the flash. This
9494-// function must never be called before then.
9595-#[allow(static_mut_refs)]
9693extern "C" fn serial_number() -> &'static [u8; 16] {
9797- unsafe { &SERIAL_NUMBER }
9494+ SERIAL_NUMBER.get().unwrap()
9895}
999610097struct TouchEventBuffer<const SIZE: usize = 32> {
···177174 let mut id = [0u8; 8];
178175 unsafe { rp2040_flash::flash::flash_unique_id(&mut id, true) };
179176 let mut id = u64::from_be_bytes(id);
180180- unsafe {
181181- // Safety: This is the only place we modify SERIAL_NUMBER, and this is before any
182182- // shared references are created
183183- #[allow(static_mut_refs)]
184184- for c in SERIAL_NUMBER.iter_mut().rev() {
185185- let nibble = (id & 0x0f) as u8;
186186- *c = match nibble {
187187- 0x0..=0x9 => b'0' + nibble,
188188- 0xa..=0xf => b'A' + nibble - 0xa,
189189- _ => unreachable!(),
190190- };
191191- id >>= 4;
192192- }
177177+ let mut serial = [0u8; 16];
178178+ for c in serial.iter_mut().rev() {
179179+ let nibble = (id & 0x0f) as u8;
180180+ *c = match nibble {
181181+ 0x0..=0x9 => b'0' + nibble,
182182+ 0xa..=0xf => b'A' + nibble - 0xa,
183183+ _ => unreachable!(),
184184+ };
185185+ id >>= 4;
193186 }
187187+ SERIAL_NUMBER.set(serial).unwrap();
194188 unsafe { cortex_m::interrupt::enable() };
195189196190 info!("Framework 16 EPD firmware version {}, serial no. {}", env!("CARGO_PKG_VERSION"), unsafe { core::str::from_utf8_unchecked(serial_number()) });