From b4221d75b87664485977d37df28f7319143411fc Mon Sep 17 00:00:00 2001 From: Ulf Lilleengen Date: Wed, 4 Sep 2024 14:09:17 +0200 Subject: Make tracing optional and use dedicated task --- embassy-net-nrf91/src/lib.rs | 90 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 71 insertions(+), 19 deletions(-) (limited to 'embassy-net-nrf91') diff --git a/embassy-net-nrf91/src/lib.rs b/embassy-net-nrf91/src/lib.rs index beed7c65a..673784cb2 100644 --- a/embassy-net-nrf91/src/lib.rs +++ b/embassy-net-nrf91/src/lib.rs @@ -19,12 +19,15 @@ use core::task::{Poll, Waker}; use embassy_net_driver_channel as ch; use embassy_sync::waitqueue::{AtomicWaker, WakerRegistration}; +use embassy_sync::blocking_mutex::raw::NoopRawMutex; use heapless::Vec; use nrf9160_pac as pac; use pac::NVIC; +use embassy_sync::pipe; const RX_SIZE: usize = 8 * 1024; const TRACE_SIZE: usize = 16 * 1024; +const TRACE_BUF: usize = 1024; const MTU: usize = 1500; /// Network driver. @@ -91,11 +94,30 @@ impl<'a> Allocator<'a> { } /// Create a new nRF91 embassy-net driver. -pub async fn new<'a, TW: embedded_io::Write>( +pub async fn new<'a>( state: &'a mut State, shmem: &'a mut [MaybeUninit], - trace_writer: TW, -) -> (NetDriver<'a>, Control<'a>, Runner<'a, TW>) { +) -> (NetDriver<'a>, Control<'a>, Runner<'a>) { + let (n, c, r, _) = new_internal(state, shmem, None).await; + (n, c, r) +} + +/// Create a new nRF91 embassy-net driver with trace. +pub async fn new_with_trace<'a>( + state: &'a mut State, + shmem: &'a mut [MaybeUninit], + trace_buffer: &'a mut TraceBuffer, +) -> (NetDriver<'a>, Control<'a>, Runner<'a>, TraceReader<'a>) { + let (n, c, r, t) = new_internal(state, shmem, Some(trace_buffer)).await; + (n, c, r, t.unwrap()) +} + +/// Create a new nRF91 embassy-net driver. +async fn new_internal<'a>( + state: &'a mut State, + shmem: &'a mut [MaybeUninit], + trace_buffer: Option<&'a mut TraceBuffer>, +) -> (NetDriver<'a>, Control<'a>, Runner<'a>, Option>) { let shmem_len = shmem.len(); let shmem_ptr = shmem.as_mut_ptr() as *mut u8; @@ -205,21 +227,49 @@ pub async fn new<'a, TW: embedded_io::Write>( let state_ch = ch_runner.state_runner(); state_ch.set_link_state(ch::driver::LinkState::Up); + let (trace_reader, trace_writer) = if let Some(trace) = trace_buffer { + let (r, w) = trace.trace.split(); + (Some(r), Some(w)) + } else { + (None, None) + }; + let runner = Runner { ch: ch_runner, state: state_inner, trace_writer, }; - (device, control, runner) + (device, control, runner, trace_reader) } -/// Shared state for the drivver. +/// State holding modem traces. +pub struct TraceBuffer { + trace: pipe::Pipe, +} + +/// Represents writer half of the trace buffer. +pub type TraceWriter<'a> = pipe::Writer<'a, NoopRawMutex, TRACE_BUF>; + +/// Represents the reader half of the trace buffer. +pub type TraceReader<'a> = pipe::Reader<'a, NoopRawMutex, TRACE_BUF>; + +impl TraceBuffer { + /// Create a new TraceBuffer. + pub const fn new() -> Self { + Self { + trace: pipe::Pipe::new(), + } + } +} + +/// Shared state for the driver. pub struct State { ch: ch::State, inner: MaybeUninit>, } + impl State { /// Create a new State. pub const fn new() -> Self { @@ -272,7 +322,7 @@ struct StateInner { } impl StateInner { - fn poll(&mut self, trace_writer: &mut impl embedded_io::Write, ch: &mut ch::Runner) { + fn poll(&mut self, trace_writer: &mut Option>, ch: &mut ch::Runner) { trace!("poll!"); let ipc = unsafe { &*pac::IPC_NS::ptr() }; @@ -399,15 +449,17 @@ impl StateInner { }); } - fn handle_trace(writer: &mut impl embedded_io::Write, id: u8, data: &[u8]) { - trace!("trace: {} {}", id, data.len()); - let mut header = [0u8; 5]; - header[0] = 0xEF; - header[1] = 0xBE; - header[2..4].copy_from_slice(&(data.len() as u16).to_le_bytes()); - header[4] = id; - writer.write_all(&header).unwrap(); - writer.write_all(data).unwrap(); + fn handle_trace(writer: &mut Option>, id: u8, data: &[u8]) { + if let Some(writer) = writer { + trace!("trace: {} {}", id, data.len()); + let mut header = [0u8; 5]; + header[0] = 0xEF; + header[1] = 0xBE; + header[2..4].copy_from_slice(&(data.len() as u16).to_le_bytes()); + header[4] = id; + writer.try_write(&header).ok(); + writer.try_write(data).ok(); + } } fn process(&mut self, list: *mut List, is_control: bool, ch: &mut ch::Runner) -> bool { @@ -794,7 +846,7 @@ impl<'a> Control<'a> { /// Open the raw socket used for sending/receiving IP packets. /// /// This must be done after `AT+CFUN=1` (?) - pub async fn open_raw_socket(&self) { + async fn open_raw_socket(&self) { let mut msg: Message = unsafe { mem::zeroed() }; msg.channel = 2; // data msg.id = 0x7001_0004; // open socket @@ -822,13 +874,13 @@ impl<'a> Control<'a> { } /// Background runner for the driver. -pub struct Runner<'a, TW: embedded_io::Write> { +pub struct Runner<'a> { ch: ch::Runner<'a, MTU>, state: &'a RefCell, - trace_writer: TW, + trace_writer: Option>, } -impl<'a, TW: embedded_io::Write> Runner<'a, TW> { +impl<'a> Runner<'a> { /// Run the driver operation in the background. /// /// You must run this in a background task, concurrently with all network operations. -- cgit