diff --git a/Cargo.toml b/Cargo.toml index 28c0958..09a424c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,6 +3,11 @@ name = "picorom-rs" version = "0.1.0" edition = "2024" +[lints.clippy] +pedantic = "warn" +nursery = "warn" +future-not-send = { level = "allow", priority = 10 } + [[bin]] name = "picorom-rs" test = false diff --git a/src/main.rs b/src/main.rs index 6fddfbe..9738ac5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,7 +11,7 @@ mod serial; use core::{ - mem::{MaybeUninit, transmute}, + mem::MaybeUninit, sync::atomic::{AtomicU8, Ordering}, task::Poll, }; @@ -342,12 +342,22 @@ async fn pio_task( fn store_rom( flash: &mut Flash<'_, FLASH, impl flash::Mode, FLASH_SIZE>, ) -> Result<(), flash::Error> { - let offset = - unsafe { (INIT_ROM_DATA.as_ptr() as *const u32).offset_from_unsigned(FLASH_BASE) as u32 }; + let offset = unsafe { + u32::try_from( + INIT_ROM_DATA + .as_ptr() + .cast::() + .offset_from_unsigned(FLASH_BASE.cast::()), + ) + .map_err(|_| flash::Error::OutOfBounds)? + }; let len = size_of_val(&INIT_ROM_DATA).min(ROM_DATA.len()); defmt::info!("Erasing flash at offset {:#x} with size {:#x}", offset, len); - flash.blocking_erase(offset, offset + len as u32)?; - let rom_buffer = unsafe { transmute::<&[AtomicU8], &[u8]>(&ROM_DATA[..len]) }; + flash.blocking_erase( + offset, + offset + u32::try_from(len).map_err(|_| flash::Error::OutOfBounds)?, + )?; + let rom_buffer = unsafe { &*(&raw const ROM_DATA[..len] as *const [u8]) }; defmt::info!("Programming flash with buffer at {}", rom_buffer.as_ptr()); flash.blocking_write(offset, rom_buffer)?; defmt::info!("Successfully commited rom to flash"); @@ -357,12 +367,22 @@ fn store_rom( fn load_rom( flash: &mut Flash<'_, FLASH, impl flash::Mode, FLASH_SIZE>, ) -> Result<(), flash::Error> { - let offset = - unsafe { (INIT_ROM_DATA.as_ptr() as *const u32).offset_from_unsigned(FLASH_BASE) as u32 }; + let offset = unsafe { + u32::try_from( + INIT_ROM_DATA + .as_ptr() + .cast::() + .offset_from_unsigned(FLASH_BASE.cast::()), + ) + .map_err(|_| flash::Error::OutOfBounds)? + }; let len = size_of_val(&INIT_ROM_DATA).min(ROM_DATA.len()); for (i, rom) in ROM_DATA.iter().enumerate().take(len) { let mut init = [0u8]; - flash.blocking_read(offset + i as u32, &mut init)?; + flash.blocking_read( + offset + u32::try_from(i).map_err(|_| flash::Error::OutOfBounds)?, + &mut init, + )?; let init = init[0]; rom.store(init, Ordering::SeqCst); } diff --git a/src/serial.rs b/src/serial.rs index 0892674..ba0b33a 100644 --- a/src/serial.rs +++ b/src/serial.rs @@ -197,91 +197,8 @@ impl Link { } None } - Kind::ParameterGet => match &packet.payload[..] { - b"name\0" => Some(Packet { - kind: Kind::Parameter, - payload: self.name.clone().into_bytes(), - }), - b"addr_mask\0" => Some(Packet { - kind: Kind::Parameter, - payload: Vec::from_array(*b"0x7fff"), - }), - b"rom_name\0" => Some(Packet { - kind: Kind::Parameter, - payload: self.rom_name.clone().into_bytes(), - }), - payload => { - if let Ok(name) = str::from_utf8(payload) { - defmt::warn!("Got unknonwn parameter request: {}", name); - } else { - defmt::warn!("Got unknonw parameter request: {}", payload); - } - Some(Packet { - kind: Kind::ParameterError, - payload: Vec::new(), - }) - } - }, - Kind::ParameterSet => { - let mut parts = packet.payload.split(|b| *b == b','); - let Some(name) = parts.next() else { - return Some(Packet { - kind: Kind::ParameterError, - payload: Vec::new(), - }); - }; - let Some(value) = parts.next() else { - return Some(Packet { - kind: Kind::ParameterError, - payload: Vec::new(), - }); - }; - match name { - b"name" => { - let Ok(value) = str::from_utf8(value) else { - return Some(Packet { - kind: Kind::ParameterError, - payload: Vec::new(), - }); - }; - self.name.clear(); - let _ = self.name.push_str(value); - Some(Packet { - kind: Kind::Parameter, - payload: self.name.clone().into_bytes(), - }) - } - b"addr_mask" => Some(Packet { - kind: Kind::Parameter, - payload: Vec::from_array(*b"0x7fff"), - }), - b"rom_name" => { - let Ok(value) = str::from_utf8(value) else { - return Some(Packet { - kind: Kind::ParameterError, - payload: Vec::new(), - }); - }; - self.rom_name.clear(); - let _ = self.rom_name.push_str(value); - Some(Packet { - kind: Kind::Parameter, - payload: self.rom_name.clone().into_bytes(), - }) - } - payload => { - if let Ok(name) = str::from_utf8(payload) { - defmt::warn!("Got unknonwn parameter request: {}", name); - } else { - defmt::warn!("Got unknonw parameter request: {}", payload); - } - Some(Packet { - kind: Kind::ParameterError, - payload: Vec::new(), - }) - } - } - } + Kind::ParameterGet => Some(self.get_parameter(packet)), + Kind::ParameterSet => Some(self.set_parameter(packet)), Kind::CommitFlash => { if let Err(e) = store_rom(flash) { defmt::error!("Unable to commit rom to flash: {}", e); @@ -296,4 +213,93 @@ impl Link { _ => Some(Packet::error(b"Unrecognized packet")), } } + + fn set_parameter(&mut self, packet: &Packet) -> Packet { + let mut parts = packet.payload.split(|b| *b == b','); + let Some(name) = parts.next() else { + return Packet { + kind: Kind::ParameterError, + payload: Vec::new(), + }; + }; + let Some(value) = parts.next() else { + return Packet { + kind: Kind::ParameterError, + payload: Vec::new(), + }; + }; + match name { + b"name" => { + let Ok(value) = str::from_utf8(value) else { + return Packet { + kind: Kind::ParameterError, + payload: Vec::new(), + }; + }; + self.name.clear(); + let _ = self.name.push_str(value); + Packet { + kind: Kind::Parameter, + payload: self.name.clone().into_bytes(), + } + } + b"addr_mask" => Packet { + kind: Kind::Parameter, + payload: Vec::from_array(*b"0x7fff"), + }, + b"rom_name" => { + let Ok(value) = str::from_utf8(value) else { + return Packet { + kind: Kind::ParameterError, + payload: Vec::new(), + }; + }; + self.rom_name.clear(); + let _ = self.rom_name.push_str(value); + Packet { + kind: Kind::Parameter, + payload: self.rom_name.clone().into_bytes(), + } + } + payload => { + if let Ok(name) = str::from_utf8(payload) { + defmt::warn!("Got unknonwn parameter request: {}", name); + } else { + defmt::warn!("Got unknonw parameter request: {}", payload); + } + Packet { + kind: Kind::ParameterError, + payload: Vec::new(), + } + } + } + } + + fn get_parameter(&self, packet: &Packet) -> Packet { + match &packet.payload[..] { + b"name\0" => Packet { + kind: Kind::Parameter, + payload: self.name.clone().into_bytes(), + }, + b"addr_mask\0" => Packet { + kind: Kind::Parameter, + payload: Vec::from_array(*b"0x7fff"), + }, + b"rom_name\0" => Packet { + kind: Kind::Parameter, + payload: self.rom_name.clone().into_bytes(), + }, + payload => { + if let Ok(name) = str::from_utf8(payload) { + defmt::warn!("Got unknonwn parameter request: {}", name); + } else { + defmt::warn!("Got unknonw parameter request: {}", payload); + } + Packet { + kind: Kind::ParameterError, + payload: Vec::new(), + } + } + } + } }