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

View file

@ -13,105 +13,86 @@ pub struct PendingIoctl {
}
#[derive(Clone, Copy)]
enum IoctlStateInner {
enum IoctlState {
Pending(PendingIoctl),
Sent { buf: *mut [u8] },
Done { resp_len: usize },
}
struct Wakers {
control: WakerRegistration,
runner: WakerRegistration,
pub struct Shared(RefCell<SharedInner>);
struct SharedInner {
ioctl: IoctlState,
control_waker: WakerRegistration,
runner_waker: WakerRegistration,
}
impl Default for Wakers {
fn default() -> Self {
Self {
control: WakerRegistration::new(),
runner: WakerRegistration::new(),
}
}
}
pub struct IoctlState {
state: Cell<IoctlStateInner>,
wakers: RefCell<Wakers>,
}
impl IoctlState {
impl Shared {
pub fn new() -> Self {
Self {
state: Cell::new(IoctlStateInner::Done { resp_len: 0 }),
wakers: Default::default(),
}
Self(RefCell::new(SharedInner {
ioctl: IoctlState::Done { resp_len: 0 },
control_waker: WakerRegistration::new(),
runner_waker: WakerRegistration::new(),
}))
}
fn wake_control(&self) {
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 {
pub async fn ioctl_wait_complete(&self) -> usize {
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)
} else {
self.register_control(cx.waker());
this.control_waker.register(cx.waker());
Poll::Pending
}
})
.await
}
pub async fn wait_pending(&self) -> PendingIoctl {
pub async fn ioctl_wait_pending(&self) -> PendingIoctl {
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)
} else {
self.register_runner(cx.waker());
this.runner_waker.register(cx.waker());
Poll::Pending
}
})
.await;
self.state.set(IoctlStateInner::Sent { buf: pending.buf });
self.0.borrow_mut().ioctl = IoctlState::Sent { buf: pending.buf };
pending
}
pub fn cancel_ioctl(&self) {
self.state.set(IoctlStateInner::Done { resp_len: 0 });
pub fn ioctl_cancel(&self) {
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]));
self.state.set(IoctlStateInner::Pending(PendingIoctl { buf, req_len }));
self.wake_runner();
self.wait_complete().await
{
let mut this = self.0.borrow_mut();
this.ioctl = IoctlState::Pending(PendingIoctl { buf, req_len });
this.runner_waker.wake();
}
self.ioctl_wait_complete().await
}
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));
// TODO fix this
(unsafe { &mut *buf }[..response.len()]).copy_from_slice(response);
self.state.set(IoctlStateInner::Done {
this.ioctl = IoctlState::Done {
resp_len: response.len(),
});
self.wake_control();
};
this.control_waker.wake();
} else {
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_async::digital::Wait;
use embedded_hal_async::spi::SpiDevice;
use ioctl::IoctlState;
use ioctl::Shared;
use proto::CtrlMsg;
use crate::ioctl::PendingIoctl;
@ -95,14 +95,14 @@ enum InterfaceType {
const MAX_SPI_BUFFER_SIZE: usize = 1600;
pub struct State {
ioctl_state: IoctlState,
shared: Shared,
ch: ch::State<MTU, 4, 4>,
}
impl State {
pub fn new() -> Self {
Self {
ioctl_state: IoctlState::new(),
shared: Shared::new(),
ch: ch::State::new(),
}
}
@ -127,7 +127,7 @@ where
let mut runner = Runner {
ch: ch_runner,
ioctl_state: &state.ioctl_state,
shared: &state.shared,
next_seq: 1,
handshake,
ready,
@ -136,12 +136,12 @@ where
};
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> {
ch: ch::Runner<'a, MTU>,
ioctl_state: &'a IoctlState,
shared: &'a Shared,
next_seq: u16,
@ -172,7 +172,7 @@ where
loop {
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 ev = async { self.ready.wait_for_high().await.unwrap() };
@ -294,7 +294,7 @@ where
if isEvent {
self.handle_event(data);
} else {
self.ioctl_state.ioctl_done(data);
self.shared.ioctl_done(data);
}
}
_ => warn!("unknown iftype {}", if_type_and_num),