mirror of
https://github.com/embassy-rs/embassy.git
synced 2024-11-25 16:23:10 +00:00
don't crash if tx buffers fill up.
This commit is contained in:
parent
160e1c38ce
commit
11652ff5c7
@ -1,6 +1,7 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
#![doc = include_str!("../README.md")]
|
#![doc = include_str!("../README.md")]
|
||||||
#![warn(missing_docs)]
|
#![warn(missing_docs)]
|
||||||
|
#![deny(unused_must_use)]
|
||||||
|
|
||||||
// must be first
|
// must be first
|
||||||
mod fmt;
|
mod fmt;
|
||||||
@ -244,6 +245,10 @@ struct PendingRequest {
|
|||||||
waker: Waker,
|
waker: Waker,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||||
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
|
struct NoFreeBufs;
|
||||||
|
|
||||||
struct StateInner {
|
struct StateInner {
|
||||||
init: bool,
|
init: bool,
|
||||||
init_waker: WakerRegistration,
|
init_waker: WakerRegistration,
|
||||||
@ -450,13 +455,13 @@ impl StateInner {
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_message(&mut self, msg: &mut Message, data: &[u8]) {
|
fn send_message(&mut self, msg: &mut Message, data: &[u8]) -> Result<(), NoFreeBufs> {
|
||||||
if data.is_empty() {
|
if data.is_empty() {
|
||||||
msg.data = ptr::null_mut();
|
msg.data = ptr::null_mut();
|
||||||
msg.data_len = 0;
|
msg.data_len = 0;
|
||||||
} else {
|
} else {
|
||||||
assert!(data.len() <= TX_BUF_SIZE);
|
assert!(data.len() <= TX_BUF_SIZE);
|
||||||
let buf_idx = self.find_free_tx_buf().unwrap(); // TODO handle out of bufs
|
let buf_idx = self.find_free_tx_buf().ok_or(NoFreeBufs)?;
|
||||||
let buf = unsafe { addr_of_mut!((*self.cb).tx_bufs[buf_idx]) } as *mut u8;
|
let buf = unsafe { addr_of_mut!((*self.cb).tx_bufs[buf_idx]) } as *mut u8;
|
||||||
unsafe { copy_nonoverlapping(data.as_ptr(), buf, data.len()) }
|
unsafe { copy_nonoverlapping(data.as_ptr(), buf, data.len()) }
|
||||||
msg.data = buf;
|
msg.data = buf;
|
||||||
@ -467,10 +472,10 @@ impl StateInner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO free data buf if send_message_raw fails.
|
// TODO free data buf if send_message_raw fails.
|
||||||
self.send_message_raw(msg);
|
self.send_message_raw(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_message_raw(&mut self, msg: &Message) {
|
fn send_message_raw(&mut self, msg: &Message) -> Result<(), NoFreeBufs> {
|
||||||
let (ch, ipc_ch) = match msg.channel {
|
let (ch, ipc_ch) = match msg.channel {
|
||||||
1 => (0, 1), // control
|
1 => (0, 1), // control
|
||||||
2 => (1, 3), // data
|
2 => (1, 3), // data
|
||||||
@ -478,7 +483,7 @@ impl StateInner {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// allocate a msg.
|
// allocate a msg.
|
||||||
let idx = self.find_free_message(ch).unwrap(); // TODO handle list full
|
let idx = self.find_free_message(ch).ok_or(NoFreeBufs)?;
|
||||||
|
|
||||||
debug!("tx seq {} msg: {:?}", self.tx_seq_no, msg);
|
debug!("tx seq {} msg: {:?}", self.tx_seq_no, msg);
|
||||||
|
|
||||||
@ -491,6 +496,7 @@ impl StateInner {
|
|||||||
|
|
||||||
let ipc = unsafe { &*pac::IPC_NS::ptr() };
|
let ipc = unsafe { &*pac::IPC_NS::ptr() };
|
||||||
ipc.tasks_send[ipc_ch].write(|w| unsafe { w.bits(1) });
|
ipc.tasks_send[ipc_ch].write(|w| unsafe { w.bits(1) });
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_control(&mut self, msg: &Message) {
|
fn handle_control(&mut self, msg: &Message) {
|
||||||
@ -626,7 +632,7 @@ impl StateInner {
|
|||||||
free_msg.data = msg.data;
|
free_msg.data = msg.data;
|
||||||
free_msg.data_len = msg.data_len;
|
free_msg.data_len = msg.data_len;
|
||||||
|
|
||||||
self.send_message_raw(&free_msg);
|
unwrap!(self.send_message_raw(&free_msg));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -702,7 +708,7 @@ impl<'a> Control<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
msg.param[0..4].copy_from_slice(&req_serial.to_le_bytes());
|
msg.param[0..4].copy_from_slice(&req_serial.to_le_bytes());
|
||||||
state.send_message(msg, req_data);
|
unwrap!(state.send_message(msg, req_data));
|
||||||
|
|
||||||
// Setup the pending request state.
|
// Setup the pending request state.
|
||||||
let (req_slot_idx, req_slot) = state
|
let (req_slot_idx, req_slot) = state
|
||||||
@ -838,7 +844,9 @@ impl<'a, TW: embedded_io::Write> Runner<'a, TW> {
|
|||||||
msg.id = 0x7006_0004; // IP send
|
msg.id = 0x7006_0004; // IP send
|
||||||
msg.param_len = 12;
|
msg.param_len = 12;
|
||||||
msg.param[4..8].copy_from_slice(&fd.to_le_bytes());
|
msg.param[4..8].copy_from_slice(&fd.to_le_bytes());
|
||||||
state.send_message(&mut msg, buf);
|
if let Err(e) = state.send_message(&mut msg, buf) {
|
||||||
|
warn!("tx failed: {:?}", e);
|
||||||
|
}
|
||||||
self.ch.tx_done();
|
self.ch.tx_done();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user