esp-hosted: nicer names for shared state struct.

This commit is contained in:
Dario Nieuwenhuis 2023-06-21 18:55:29 +02:00
parent ec2c095a76
commit 082f1ab494
3 changed files with 53 additions and 72 deletions

View file

@ -3,7 +3,7 @@ use defmt::Debug2Format;
use embassy_net_driver_channel as ch; use embassy_net_driver_channel as ch;
use heapless::String; use heapless::String;
use crate::ioctl::IoctlState; use crate::ioctl::Shared;
use crate::proto::{self, CtrlMsg}; use crate::proto::{self, CtrlMsg};
#[derive(Debug)] #[derive(Debug)]
@ -13,7 +13,7 @@ pub struct Error {
pub struct Control<'a> { pub struct Control<'a> {
state_ch: ch::StateRunner<'a>, state_ch: ch::StateRunner<'a>,
ioctl_state: &'a IoctlState, shared: &'a Shared,
} }
enum WifiMode { enum WifiMode {
@ -24,8 +24,8 @@ enum WifiMode {
} }
impl<'a> Control<'a> { impl<'a> Control<'a> {
pub(crate) fn new(state_ch: ch::StateRunner<'a>, ioctl_state: &'a IoctlState) -> Self { pub(crate) fn new(state_ch: ch::StateRunner<'a>, shared: &'a Shared) -> Self {
Self { state_ch, ioctl_state } Self { state_ch, shared }
} }
pub async fn init(&mut self) { pub async fn init(&mut self) {
@ -118,7 +118,7 @@ impl<'a> Control<'a> {
let req_len = noproto::write(&req, &mut buf).unwrap(); let req_len = noproto::write(&req, &mut buf).unwrap();
struct CancelOnDrop<'a>(&'a IoctlState); struct CancelOnDrop<'a>(&'a Shared);
impl CancelOnDrop<'_> { impl CancelOnDrop<'_> {
fn defuse(self) { fn defuse(self) {
@ -128,13 +128,13 @@ impl<'a> Control<'a> {
impl Drop for CancelOnDrop<'_> { impl Drop for CancelOnDrop<'_> {
fn drop(&mut self) { fn drop(&mut self) {
self.0.cancel_ioctl(); self.0.ioctl_cancel();
} }
} }
let ioctl = CancelOnDrop(self.ioctl_state); let ioctl = CancelOnDrop(self.shared);
let resp_len = ioctl.0.do_ioctl(&mut buf, req_len).await; let resp_len = ioctl.0.ioctl(&mut buf, req_len).await;
ioctl.defuse(); ioctl.defuse();

View file

@ -13,105 +13,86 @@ pub struct PendingIoctl {
} }
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
enum IoctlStateInner { enum IoctlState {
Pending(PendingIoctl), Pending(PendingIoctl),
Sent { buf: *mut [u8] }, Sent { buf: *mut [u8] },
Done { resp_len: usize }, Done { resp_len: usize },
} }
struct Wakers { pub struct Shared(RefCell<SharedInner>);
control: WakerRegistration,
runner: WakerRegistration, struct SharedInner {
ioctl: IoctlState,
control_waker: WakerRegistration,
runner_waker: WakerRegistration,
} }
impl Default for Wakers { impl Shared {
fn default() -> Self {
Self {
control: WakerRegistration::new(),
runner: WakerRegistration::new(),
}
}
}
pub struct IoctlState {
state: Cell<IoctlStateInner>,
wakers: RefCell<Wakers>,
}
impl IoctlState {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self(RefCell::new(SharedInner {
state: Cell::new(IoctlStateInner::Done { resp_len: 0 }), ioctl: IoctlState::Done { resp_len: 0 },
wakers: Default::default(), control_waker: WakerRegistration::new(),
} runner_waker: WakerRegistration::new(),
}))
} }
fn wake_control(&self) { pub async fn ioctl_wait_complete(&self) -> usize {
self.wakers.borrow_mut().control.wake();
}
fn register_control(&self, waker: &Waker) {
self.wakers.borrow_mut().control.register(waker);
}
fn wake_runner(&self) {
self.wakers.borrow_mut().runner.wake();
}
fn register_runner(&self, waker: &Waker) {
self.wakers.borrow_mut().runner.register(waker);
}
pub async fn wait_complete(&self) -> usize {
poll_fn(|cx| { poll_fn(|cx| {
if let IoctlStateInner::Done { resp_len } = self.state.get() { let mut this = self.0.borrow_mut();
if let IoctlState::Done { resp_len } = this.ioctl {
Poll::Ready(resp_len) Poll::Ready(resp_len)
} else { } else {
self.register_control(cx.waker()); this.control_waker.register(cx.waker());
Poll::Pending Poll::Pending
} }
}) })
.await .await
} }
pub async fn wait_pending(&self) -> PendingIoctl { pub async fn ioctl_wait_pending(&self) -> PendingIoctl {
let pending = poll_fn(|cx| { let pending = poll_fn(|cx| {
if let IoctlStateInner::Pending(pending) = self.state.get() { let mut this = self.0.borrow_mut();
if let IoctlState::Pending(pending) = this.ioctl {
Poll::Ready(pending) Poll::Ready(pending)
} else { } else {
self.register_runner(cx.waker()); this.runner_waker.register(cx.waker());
Poll::Pending Poll::Pending
} }
}) })
.await; .await;
self.state.set(IoctlStateInner::Sent { buf: pending.buf }); self.0.borrow_mut().ioctl = IoctlState::Sent { buf: pending.buf };
pending pending
} }
pub fn cancel_ioctl(&self) { pub fn ioctl_cancel(&self) {
self.state.set(IoctlStateInner::Done { resp_len: 0 }); self.0.borrow_mut().ioctl = IoctlState::Done { resp_len: 0 };
} }
pub async fn do_ioctl(&self, buf: &mut [u8], req_len: usize) -> usize { pub async fn ioctl(&self, buf: &mut [u8], req_len: usize) -> usize {
trace!("ioctl req bytes: {:02x}", Bytes(&buf[..req_len])); trace!("ioctl req bytes: {:02x}", Bytes(&buf[..req_len]));
self.state.set(IoctlStateInner::Pending(PendingIoctl { buf, req_len })); {
self.wake_runner(); let mut this = self.0.borrow_mut();
self.wait_complete().await this.ioctl = IoctlState::Pending(PendingIoctl { buf, req_len });
this.runner_waker.wake();
}
self.ioctl_wait_complete().await
} }
pub fn ioctl_done(&self, response: &[u8]) { pub fn ioctl_done(&self, response: &[u8]) {
if let IoctlStateInner::Sent { buf } = self.state.get() { let mut this = self.0.borrow_mut();
if let IoctlState::Sent { buf } = this.ioctl {
trace!("ioctl resp bytes: {:02x}", Bytes(response)); trace!("ioctl resp bytes: {:02x}", Bytes(response));
// TODO fix this // TODO fix this
(unsafe { &mut *buf }[..response.len()]).copy_from_slice(response); (unsafe { &mut *buf }[..response.len()]).copy_from_slice(response);
self.state.set(IoctlStateInner::Done { this.ioctl = IoctlState::Done {
resp_len: response.len(), resp_len: response.len(),
}); };
self.wake_control(); this.control_waker.wake();
} else { } else {
warn!("IOCTL Response but no pending Ioctl"); warn!("IOCTL Response but no pending Ioctl");
} }

View file

@ -7,7 +7,7 @@ use embassy_time::{Duration, Instant, Timer};
use embedded_hal::digital::{InputPin, OutputPin}; use embedded_hal::digital::{InputPin, OutputPin};
use embedded_hal_async::digital::Wait; use embedded_hal_async::digital::Wait;
use embedded_hal_async::spi::SpiDevice; use embedded_hal_async::spi::SpiDevice;
use ioctl::IoctlState; use ioctl::Shared;
use proto::CtrlMsg; use proto::CtrlMsg;
use crate::ioctl::PendingIoctl; use crate::ioctl::PendingIoctl;
@ -95,14 +95,14 @@ enum InterfaceType {
const MAX_SPI_BUFFER_SIZE: usize = 1600; const MAX_SPI_BUFFER_SIZE: usize = 1600;
pub struct State { pub struct State {
ioctl_state: IoctlState, shared: Shared,
ch: ch::State<MTU, 4, 4>, ch: ch::State<MTU, 4, 4>,
} }
impl State { impl State {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
ioctl_state: IoctlState::new(), shared: Shared::new(),
ch: ch::State::new(), ch: ch::State::new(),
} }
} }
@ -127,7 +127,7 @@ where
let mut runner = Runner { let mut runner = Runner {
ch: ch_runner, ch: ch_runner,
ioctl_state: &state.ioctl_state, shared: &state.shared,
next_seq: 1, next_seq: 1,
handshake, handshake,
ready, ready,
@ -136,12 +136,12 @@ where
}; };
runner.init().await; runner.init().await;
(device, Control::new(state_ch, &state.ioctl_state), runner) (device, Control::new(state_ch, &state.shared), runner)
} }
pub struct Runner<'a, SPI, IN, OUT> { pub struct Runner<'a, SPI, IN, OUT> {
ch: ch::Runner<'a, MTU>, ch: ch::Runner<'a, MTU>,
ioctl_state: &'a IoctlState, shared: &'a Shared,
next_seq: u16, next_seq: u16,
@ -172,7 +172,7 @@ where
loop { loop {
self.handshake.wait_for_high().await.unwrap(); self.handshake.wait_for_high().await.unwrap();
let ioctl = self.ioctl_state.wait_pending(); let ioctl = self.shared.ioctl_wait_pending();
let tx = self.ch.tx_buf(); let tx = self.ch.tx_buf();
let ev = async { self.ready.wait_for_high().await.unwrap() }; let ev = async { self.ready.wait_for_high().await.unwrap() };
@ -294,7 +294,7 @@ where
if isEvent { if isEvent {
self.handle_event(data); self.handle_event(data);
} else { } else {
self.ioctl_state.ioctl_done(data); self.shared.ioctl_done(data);
} }
} }
_ => warn!("unknown iftype {}", if_type_and_num), _ => warn!("unknown iftype {}", if_type_and_num),