fix: eliminate panics, validate config, handle all errors in radio/USB tasks
Radio task: - Remove all .unwrap() — start_rx/rx_once now take &RadioConfig directly - Validate RadioConfig on SetConfig and Transmit (freq, SF, CR, power) - Notify host when RX restart fails (was silently going Idle) - Clamp payload length with warning instead of silent truncation - Extract modulation_params() helper, eliminating 3x duplication - Name all magic numbers (PREAMBLE_LEN, CRC_ON, etc.) - Add comprehensive module documentation USB task: - Log serialization and write failures instead of silently dropping - Break chunk loop on write error - Add compile-time buffer size assertion Protocol: - Add RadioConfig::validate() with SX1262 hardware limits - Document all field ranges
This commit is contained in:
3 files changed
+212
-77
No files matched your search
+20
-3
@@ -1,3 +1,4 @@
|
||||
use defmt::warn;
|
||||
use embassy_executor::task;
|
||||
use embassy_futures::join::join;
|
||||
use embassy_usb::class::cdc_acm::{CdcAcmClass, Receiver, Sender, State};
|
||||
@@ -14,6 +15,14 @@ use crate::protocol::{Command, ErrorCode, Response};
|
||||
const MAX_FRAME: usize = 512;
|
||||
const MAX_PACKET: usize = 64;
|
||||
|
||||
// Ensure MAX_FRAME can hold the largest possible COBS-encoded response.
|
||||
// Worst case: RxPacket with MAX_PAYLOAD bytes. Postcard overhead ~8 bytes,
|
||||
// COBS adds ceil(n/254)+1 bytes. 256+8+3 = 267. 512 is comfortably sufficient.
|
||||
const _: () = assert!(
|
||||
MAX_FRAME >= crate::protocol::MAX_PAYLOAD + 64,
|
||||
"MAX_FRAME too small for max payload + COBS overhead"
|
||||
);
|
||||
|
||||
#[task]
|
||||
pub async fn usb_task(
|
||||
parts: UsbParts,
|
||||
@@ -117,9 +126,17 @@ async fn protocol_loop<'d, D: embassy_usb_driver::Driver<'d>>(
|
||||
}
|
||||
}
|
||||
Either3::Second(response) => {
|
||||
if let Ok(buf) = postcard::to_slice_cobs(&response, &mut write_buf) {
|
||||
for chunk in buf.chunks(MAX_PACKET) {
|
||||
let _ = sender.write_packet(chunk).await;
|
||||
match postcard::to_slice_cobs(&response, &mut write_buf) {
|
||||
Ok(buf) => {
|
||||
for chunk in buf.chunks(MAX_PACKET) {
|
||||
if sender.write_packet(chunk).await.is_err() {
|
||||
warn!("USB write failed, response dropped");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(_) => {
|
||||
warn!("response serialization failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user