Replace some esp-wifi critical sections with locks (#2554)

* Replace some esp-wifi critical sections with locks

* Remove critical section from event handlers

* Fix doc warnings and accidentally hard-coded esp32s3

* Use Lock in wifi_int_disable/restore

* Replace critical_section in ConcurrentQueue

* Deduplicate wifi_int_disable
This commit is contained in:
Dániel Buga 2024-11-25 18:06:05 +01:00 committed by GitHub
parent aed0fac0eb
commit eec75c8f82
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 195 additions and 475 deletions

View File

@ -12,6 +12,7 @@ use esp_wifi_sys::include::malloc;
use super::malloc::free;
use crate::{
binary::c_types::{c_int, c_void},
hal::sync::Locked,
memory_fence::memory_fence,
preempt::current_task,
timer::yield_task,
@ -27,36 +28,34 @@ struct Mutex {
}
pub(crate) struct ConcurrentQueue {
raw_queue: critical_section::Mutex<RefCell<RawQueue>>,
raw_queue: Locked<RawQueue>,
}
impl ConcurrentQueue {
pub(crate) fn new(count: usize, item_size: usize) -> Self {
Self {
raw_queue: critical_section::Mutex::new(RefCell::new(RawQueue::new(count, item_size))),
raw_queue: Locked::new(RawQueue::new(count, item_size)),
}
}
fn release_storage(&mut self) {
critical_section::with(|cs| unsafe {
self.raw_queue.borrow_ref_mut(cs).release_storage();
})
self.raw_queue.with(|q| unsafe { q.release_storage() })
}
pub(crate) fn enqueue(&mut self, item: *mut c_void) -> i32 {
critical_section::with(|cs| unsafe { self.raw_queue.borrow_ref_mut(cs).enqueue(item) })
self.raw_queue.with(|q| unsafe { q.enqueue(item) })
}
pub(crate) fn try_dequeue(&mut self, item: *mut c_void) -> bool {
critical_section::with(|cs| unsafe { self.raw_queue.borrow_ref_mut(cs).try_dequeue(item) })
self.raw_queue.with(|q| unsafe { q.try_dequeue(item) })
}
pub(crate) fn remove(&mut self, item: *mut c_void) {
critical_section::with(|cs| unsafe { self.raw_queue.borrow_ref_mut(cs).remove(item) });
self.raw_queue.with(|q| unsafe { q.remove(item) })
}
pub(crate) fn count(&self) -> usize {
critical_section::with(|cs| unsafe { self.raw_queue.borrow_ref(cs).count() })
self.raw_queue.with(|q| unsafe { q.count() })
}
}

View File

@ -1,7 +1,6 @@
use alloc::boxed::Box;
use core::cell::RefCell;
use critical_section::Mutex;
use esp_hal::sync::Locked;
use crate::binary::{
c_types,
@ -138,7 +137,7 @@ impl TimerQueue {
unsafe impl Send for TimerQueue {}
pub(crate) static TIMERS: Mutex<RefCell<TimerQueue>> = Mutex::new(RefCell::new(TimerQueue::new()));
pub(crate) static TIMERS: Locked<TimerQueue> = Locked::new(TimerQueue::new());
pub(crate) fn compat_timer_arm(ets_timer: *mut ets_timer, tmout: u32, repeat: bool) {
compat_timer_arm_us(ets_timer, tmout * 1000, repeat);
@ -156,8 +155,8 @@ pub(crate) fn compat_timer_arm_us(ets_timer: *mut ets_timer, us: u32, repeat: bo
repeat
);
critical_section::with(|cs| {
if let Some(timer) = TIMERS.borrow_ref_mut(cs).find(ets_timer) {
TIMERS.with(|timers| {
if let Some(timer) = timers.find(ets_timer) {
timer.started = systick;
timer.timeout = ticks;
timer.active = true;
@ -170,8 +169,8 @@ pub(crate) fn compat_timer_arm_us(ets_timer: *mut ets_timer, us: u32, repeat: bo
pub fn compat_timer_disarm(ets_timer: *mut ets_timer) {
trace!("timer disarm");
critical_section::with(|cs| {
if let Some(timer) = TIMERS.borrow_ref_mut(cs).find(ets_timer) {
TIMERS.with(|timers| {
if let Some(timer) = timers.find(ets_timer) {
trace!("timer_disarm {:x}", timer.id());
timer.active = false;
} else {
@ -182,8 +181,7 @@ pub fn compat_timer_disarm(ets_timer: *mut ets_timer) {
pub fn compat_timer_done(ets_timer: *mut ets_timer) {
trace!("timer done");
critical_section::with(|cs| {
let mut timers = TIMERS.borrow_ref_mut(cs);
TIMERS.with(|timers| {
if let Some(timer) = timers.find(ets_timer) {
trace!("timer_done {:x}", timer.id());
timer.active = false;
@ -211,8 +209,7 @@ pub(crate) fn compat_timer_setfn(
pfunction,
parg
);
let set = critical_section::with(|cs| unsafe {
let mut timers = TIMERS.borrow_ref_mut(cs);
let set = TIMERS.with(|timers| unsafe {
if let Some(timer) = timers.find(ets_timer) {
timer.callback = TimerCallback::new(pfunction, parg);
timer.active = false;

View File

@ -22,16 +22,15 @@
//! ```toml
//! [dependencies.esp-wifi]
//! # A supported chip needs to be specified, as well as specific use-case features
//! features = ["esp32s3", "wifi", "esp-now"]
#![doc = concat!(r#"features = [""#, esp_hal::chip!(), r#"", "wifi", "esp-now"]"#)]
//! ```
//!
//!
//! ### Optimization Level
//!
//! It is necessary to build with optimization level 2 or 3 since otherwise, it
//! might not even be able to connect or advertise.
//!
//! To make it work also for your debug builds add this to your `Cargo.toml`
//!
//! ```toml
//! [profile.dev.package.esp-wifi]
//! opt-level = 3
@ -419,7 +418,7 @@ pub unsafe fn deinit_unchecked() -> Result<(), InitializationError> {
shutdown_timer_isr();
crate::preempt::delete_all_tasks();
critical_section::with(|cs| crate::timer::TIMER.borrow_ref_mut(cs).take());
crate::timer::TIMER.with(|timer| timer.take());
crate::flags::ESP_WIFI_INITIALIZED.store(false, Ordering::Release);

View File

@ -2,10 +2,10 @@
#[cfg_attr(target_arch = "xtensa", path = "preempt_xtensa.rs")]
pub mod arch_specific;
use core::{cell::RefCell, mem::size_of};
use core::mem::size_of;
use arch_specific::*;
use critical_section::Mutex;
use esp_hal::sync::Locked;
use esp_wifi_sys::include::malloc;
use crate::{compat::malloc::free, hal::trapframe::TrapFrame, memory_fence::memory_fence};
@ -15,14 +15,12 @@ struct ContextWrapper(*mut Context);
unsafe impl Send for ContextWrapper {}
static CTX_NOW: Mutex<RefCell<ContextWrapper>> =
Mutex::new(RefCell::new(ContextWrapper(core::ptr::null_mut())));
static CTX_NOW: Locked<ContextWrapper> = Locked::new(ContextWrapper(core::ptr::null_mut()));
static mut SCHEDULED_TASK_TO_DELETE: *mut Context = core::ptr::null_mut();
pub(crate) fn allocate_main_task() -> *mut Context {
critical_section::with(|cs| unsafe {
let mut ctx_now = CTX_NOW.borrow_ref_mut(cs);
CTX_NOW.with(|ctx_now| unsafe {
if !ctx_now.0.is_null() {
panic!("Tried to allocate main task multiple times");
}
@ -36,8 +34,7 @@ pub(crate) fn allocate_main_task() -> *mut Context {
}
fn allocate_task() -> *mut Context {
critical_section::with(|cs| unsafe {
let mut ctx_now = CTX_NOW.borrow_ref_mut(cs);
CTX_NOW.with(|ctx_now| unsafe {
if ctx_now.0.is_null() {
panic!("Called `allocate_task` before allocating main task");
}
@ -51,8 +48,7 @@ fn allocate_task() -> *mut Context {
}
fn next_task() {
critical_section::with(|cs| unsafe {
let mut ctx_now = CTX_NOW.borrow_ref_mut(cs);
CTX_NOW.with(|ctx_now| unsafe {
ctx_now.0 = (*ctx_now.0).next;
});
}
@ -61,8 +57,8 @@ fn next_task() {
///
/// This will also free the memory (stack and context) allocated for it.
pub(crate) fn delete_task(task: *mut Context) {
critical_section::with(|cs| unsafe {
let mut ptr = CTX_NOW.borrow_ref_mut(cs).0;
CTX_NOW.with(|ctx_now| unsafe {
let mut ptr = ctx_now.0;
let initial = ptr;
loop {
if (*ptr).next == task {
@ -85,9 +81,8 @@ pub(crate) fn delete_task(task: *mut Context) {
}
pub(crate) fn delete_all_tasks() {
critical_section::with(|cs| unsafe {
let mut ctx_now_ref = CTX_NOW.borrow_ref_mut(cs);
let current_task = ctx_now_ref.0;
CTX_NOW.with(|ctx_now| unsafe {
let current_task = ctx_now.0;
if current_task.is_null() {
return;
@ -108,14 +103,14 @@ pub(crate) fn delete_all_tasks() {
task_to_delete = next_task;
}
ctx_now_ref.0 = core::ptr::null_mut();
ctx_now.0 = core::ptr::null_mut();
memory_fence();
});
}
pub(crate) fn current_task() -> *mut Context {
critical_section::with(|cs| CTX_NOW.borrow_ref(cs).0)
CTX_NOW.with(|ctx_now| ctx_now.0)
}
pub(crate) fn schedule_task_deletion(task: *mut Context) {

View File

@ -18,21 +18,16 @@ pub(crate) fn init_tasks() {
pub(crate) extern "C" fn timer_task(_param: *mut esp_wifi_sys::c_types::c_void) {
loop {
let current_timestamp = systimer_count();
let to_run = critical_section::with(|cs| unsafe {
let mut timers = TIMERS.borrow_ref_mut(cs);
let to_run = timers.find_next_due(current_timestamp);
let to_run = TIMERS.with(|timers| {
let to_run = unsafe { timers.find_next_due(current_timestamp) }?;
if let Some(to_run) = to_run {
to_run.active = to_run.periodic;
to_run.active = to_run.periodic;
if to_run.periodic {
to_run.started = current_timestamp;
}
Some(to_run.callback)
} else {
None
if to_run.periodic {
to_run.started = current_timestamp;
}
Some(to_run.callback)
});
// run the due timer callback NOT in an interrupt free context

View File

@ -1,6 +1,4 @@
use core::cell::RefCell;
use critical_section::Mutex;
use esp_hal::sync::Locked;
#[cfg_attr(esp32, path = "timer_esp32.rs")]
#[cfg_attr(esp32c2, path = "timer_esp32c2.rs")]
@ -20,7 +18,7 @@ pub(crate) use chip_specific::*;
use crate::TimeBase;
pub(crate) static TIMER: Mutex<RefCell<Option<TimeBase>>> = Mutex::new(RefCell::new(None));
pub(crate) static TIMER: Locked<Option<TimeBase>> = Locked::new(None);
pub(crate) fn setup_timer_isr(timebase: TimeBase) {
setup_radio_isr();

View File

@ -30,16 +30,17 @@ pub(crate) fn setup_timer(mut alarm0: TimeBase) {
let cb: extern "C" fn() = unsafe { core::mem::transmute(handler as *const ()) };
alarm0.set_interrupt_handler(InterruptHandler::new(cb, interrupt::Priority::Priority1));
unwrap!(alarm0.start(TIMESLICE_FREQUENCY.into_duration()));
critical_section::with(|cs| {
TIMER.with(|timer| {
alarm0.enable_interrupt(true);
TIMER.borrow_ref_mut(cs).replace(alarm0);
timer.replace(alarm0);
});
}
pub(crate) fn disable_timer() {
critical_section::with(|cs| {
unwrap!(TIMER.borrow_ref_mut(cs).as_mut()).enable_interrupt(false);
unwrap!(unwrap!(TIMER.borrow_ref_mut(cs).as_mut()).cancel());
TIMER.with(|timer| {
let timer = unwrap!(timer.as_mut());
timer.enable_interrupt(false);
unwrap!(timer.cancel());
});
}
@ -60,8 +61,8 @@ pub(crate) fn disable_multitasking() {
extern "C" fn handler(trap_frame: &mut TrapFrame) {
// clear the systimer intr
critical_section::with(|cs| {
unwrap!(TIMER.borrow_ref_mut(cs).as_mut()).clear_interrupt();
TIMER.with(|timer| {
unwrap!(timer.as_mut()).clear_interrupt();
});
task_switch(trap_frame);
@ -76,8 +77,7 @@ extern "C" fn FROM_CPU_INTR3(trap_frame: &mut TrapFrame) {
.modify(|_, w| w.cpu_intr_from_cpu_3().clear_bit());
}
critical_section::with(|cs| {
let mut alarm0 = TIMER.borrow_ref_mut(cs);
TIMER.with(|alarm0| {
let alarm0 = unwrap!(alarm0.as_mut());
alarm0.clear_interrupt();
});

View File

@ -27,16 +27,17 @@ pub(crate) fn setup_timer(mut timer1: TimeBase) {
interrupt::Priority::Priority2,
));
unwrap!(timer1.start(TIMESLICE_FREQUENCY.into_duration()));
critical_section::with(|cs| {
TIMER.with(|timer| {
timer1.enable_interrupt(true);
TIMER.borrow_ref_mut(cs).replace(timer1);
timer.replace(timer1);
});
}
pub(crate) fn disable_timer() {
critical_section::with(|cs| {
unwrap!(TIMER.borrow_ref_mut(cs).as_mut()).enable_interrupt(false);
unwrap!(unwrap!(TIMER.borrow_ref_mut(cs).as_mut()).cancel());
TIMER.with(|timer| {
let timer = unwrap!(timer.as_mut());
timer.enable_interrupt(false);
unwrap!(timer.cancel());
});
}
@ -58,8 +59,7 @@ pub(crate) fn disable_multitasking() {
}
fn do_task_switch(context: &mut TrapFrame) {
critical_section::with(|cs| {
let mut timer = TIMER.borrow_ref_mut(cs);
TIMER.with(|timer| {
let timer = unwrap!(timer.as_mut());
timer.clear_interrupt();
});

View File

@ -1,7 +1,6 @@
use alloc::boxed::Box;
use core::cell::RefCell;
use critical_section::Mutex;
use esp_hal::sync::Locked;
use super::WifiEvent;
@ -10,17 +9,17 @@ pub(crate) mod sealed {
pub trait Event {
/// Get the static reference to the handler for this event.
fn handler() -> &'static Mutex<RefCell<Option<Box<Handler<Self>>>>>;
fn handler() -> &'static Locked<Option<Box<Handler<Self>>>>;
/// # Safety
/// `ptr` must be a valid for casting to this event's inner event data.
unsafe fn from_raw_event_data(ptr: *mut crate::binary::c_types::c_void) -> Self;
}
}
/// The type of handlers of events.
pub type Handler<T> = dyn FnMut(critical_section::CriticalSection<'_>, &T) + Sync + Send;
pub type Handler<T> = dyn FnMut(&T) + Sync + Send;
fn default_handler<Event: 'static>() -> Box<Handler<Event>> {
fn drop_ref<T>(_: critical_section::CriticalSection<'_>, _: &T) {}
fn drop_ref<T>(_: &T) {}
// perf: `drop_ref` is a ZST [function item](https://doc.rust-lang.org/reference/types/function-item.html)
// so this doesn't actually allocate.
Box::new(drop_ref)
@ -29,9 +28,10 @@ fn default_handler<Event: 'static>() -> Box<Handler<Event>> {
/// Extension trait for setting handlers for an event.
///
/// Register a new event handler like:
/// ```
///
/// ```rust, no_run
/// # use esp_wifi::wifi::event::{self, *};
/// # fn new_handler(_: critical_section::CriticalSection<'_>, _: &ApStaconnected) {}
/// # fn new_handler(_: &ApStaconnected) {}
/// event::ApStaconnected::update_handler(|_cs, event| {
/// new_handler(event);
/// })
@ -43,46 +43,28 @@ fn default_handler<Event: 'static>() -> Box<Handler<Event>> {
pub trait EventExt: sealed::Event + Sized + 'static {
/// Get the handler for this event, replacing it with the default handler.
fn take_handler() -> Box<Handler<Self>> {
critical_section::with(|cs| {
Self::handler()
.borrow_ref_mut(cs)
.take()
.unwrap_or_else(default_handler::<Self>)
})
Self::handler().with(|handler| handler.take().unwrap_or_else(default_handler::<Self>))
}
/// Set the handler for this event, returning the old handler.
fn replace_handler<
F: FnMut(critical_section::CriticalSection<'_>, &Self) + Sync + Send + 'static,
>(
f: F,
) -> Box<Handler<Self>> {
critical_section::with(|cs| {
Self::handler()
.borrow_ref_mut(cs)
fn replace_handler<F: FnMut(&Self) + Sync + Send + 'static>(f: F) -> Box<Handler<Self>> {
Self::handler().with(|handler| {
handler
.replace(Box::new(f))
.unwrap_or_else(default_handler::<Self>)
})
}
/// Atomic combination of [`take_handler`] and [`replace_handler`]. Use this
/// to add a new handler which runs after the previously registered
/// handlers.
fn update_handler<
F: FnMut(critical_section::CriticalSection<'_>, &Self) + Sync + Send + 'static,
>(
mut f: F,
) {
critical_section::with(move |cs| {
let mut handler: Box<Handler<Self>> = Self::handler()
.borrow_ref_mut(cs)
.take()
.unwrap_or_else(default_handler::<Self>);
Self::handler().borrow_ref_mut(cs).replace(Box::new(
move |cs: critical_section::CriticalSection<'_>, event| {
handler(cs, event);
f(cs, event)
},
));
});
/// Atomic combination of [`Self::take_handler`] and
/// [`Self::replace_handler`]. Use this to add a new handler which runs
/// after the previously registered handlers.
fn update_handler<F: FnMut(&Self) + Sync + Send + 'static>(mut f: F) {
Self::handler().with(|handler| {
let mut prev: Box<Handler<Self>> =
handler.take().unwrap_or_else(default_handler::<Self>);
handler.replace(Box::new(move |event| {
prev(event);
f(event)
}));
})
}
}
impl<T: sealed::Event + 'static> EventExt for T {}
@ -97,9 +79,8 @@ macro_rules! impl_wifi_event {
unsafe fn from_raw_event_data(_: *mut crate::binary::c_types::c_void) -> Self {
Self
}
fn handler() -> &'static Mutex<RefCell<Option<Box<Handler<Self>>>>> {
static HANDLE: Mutex<RefCell<Option<Box<Handler<$newtype>>>>> =
Mutex::new(RefCell::new(None));
fn handler() -> &'static Locked<Option<Box<Handler<Self>>>> {
static HANDLE: Locked<Option<Box<Handler<$newtype>>>> = Locked::new(None);
&HANDLE
}
}
@ -114,9 +95,8 @@ macro_rules! impl_wifi_event {
unsafe fn from_raw_event_data(ptr: *mut crate::binary::c_types::c_void) -> Self {
Self(unsafe { *ptr.cast() })
}
fn handler() -> &'static Mutex<RefCell<Option<Box<Handler<Self>>>>> {
static HANDLE: Mutex<RefCell<Option<Box<Handler<$newtype>>>>> =
Mutex::new(RefCell::new(None));
fn handler() -> &'static Locked<Option<Box<Handler<Self>>>> {
static HANDLE: Locked<Option<Box<Handler<$newtype>>>> = Locked::new(None);
&HANDLE
}
}
@ -170,23 +150,21 @@ impl_wifi_event!(HomeChannelChange, wifi_event_home_channel_change_t);
impl_wifi_event!(StaNeighborRep, wifi_event_neighbor_report_t);
/// Handle the given event using the registered event handlers.
pub fn handle<Event: EventExt>(
cs: critical_section::CriticalSection<'_>,
event_data: &Event,
) -> bool {
if let Some(handler) = &mut *Event::handler().borrow_ref_mut(cs) {
handler(cs, event_data);
true
} else {
false
}
pub fn handle<Event: EventExt>(event_data: &Event) -> bool {
Event::handler().with(|handler| {
if let Some(handler) = handler {
handler(event_data);
true
} else {
false
}
})
}
/// Handle an event given the raw pointers.
/// # Safety
/// The pointer should be valid to cast to `Event`'s inner type (if it has one)
pub(crate) unsafe fn handle_raw<Event: EventExt>(
cs: critical_section::CriticalSection<'_>,
event_data: *mut crate::binary::c_types::c_void,
event_data_size: usize,
) -> bool {
@ -195,7 +173,7 @@ pub(crate) unsafe fn handle_raw<Event: EventExt>(
core::mem::size_of::<Event>(),
"wrong size event data"
);
handle::<Event>(cs, unsafe { &Event::from_raw_event_data(event_data) })
handle::<Event>(unsafe { &Event::from_raw_event_data(event_data) })
}
/// Handle event regardless of its type.
@ -203,146 +181,145 @@ pub(crate) unsafe fn handle_raw<Event: EventExt>(
/// Arguments should be self-consistent.
#[rustfmt::skip]
pub(crate) unsafe fn dispatch_event_handler(
cs: critical_section::CriticalSection<'_>,
event: WifiEvent,
event_data: *mut crate::binary::c_types::c_void,
event_data_size: usize,
) -> bool {
match event {
WifiEvent::WifiReady => {
handle_raw::<WifiReady>(cs, event_data, event_data_size)
handle_raw::<WifiReady>(event_data, event_data_size)
}
WifiEvent::ScanDone => {
handle_raw::<ScanDone>(cs, event_data, event_data_size)
handle_raw::<ScanDone>(event_data, event_data_size)
}
WifiEvent::StaStart => {
handle_raw::<StaStart>(cs, event_data, event_data_size)
handle_raw::<StaStart>(event_data, event_data_size)
}
WifiEvent::StaStop => {
handle_raw::<StaStop>(cs, event_data, event_data_size)
handle_raw::<StaStop>(event_data, event_data_size)
}
WifiEvent::StaConnected => {
handle_raw::<StaConnected>(cs, event_data, event_data_size)
handle_raw::<StaConnected>(event_data, event_data_size)
}
WifiEvent::StaDisconnected => {
handle_raw::<StaDisconnected>(cs, event_data, event_data_size)
handle_raw::<StaDisconnected>(event_data, event_data_size)
}
WifiEvent::StaAuthmodeChange => {
handle_raw::<StaAuthmodeChange>(cs, event_data, event_data_size)
handle_raw::<StaAuthmodeChange>(event_data, event_data_size)
}
WifiEvent::StaWpsErSuccess => {
handle_raw::<StaWpsErSuccess>(cs, event_data, event_data_size)
handle_raw::<StaWpsErSuccess>(event_data, event_data_size)
}
WifiEvent::StaWpsErFailed => {
handle_raw::<StaWpsErFailed>(cs, event_data, event_data_size)
handle_raw::<StaWpsErFailed>(event_data, event_data_size)
}
WifiEvent::StaWpsErTimeout => {
handle_raw::<StaWpsErTimeout>(cs, event_data, event_data_size)
handle_raw::<StaWpsErTimeout>(event_data, event_data_size)
}
WifiEvent::StaWpsErPin => {
handle_raw::<StaWpsErPin>(cs, event_data, event_data_size)
handle_raw::<StaWpsErPin>(event_data, event_data_size)
}
WifiEvent::StaWpsErPbcOverlap => {
handle_raw::<StaWpsErPbcOverlap>(cs, event_data, event_data_size)
handle_raw::<StaWpsErPbcOverlap>(event_data, event_data_size)
}
WifiEvent::ApStart => {
handle_raw::<ApStart>(cs, event_data, event_data_size)
handle_raw::<ApStart>(event_data, event_data_size)
}
WifiEvent::ApStop => {
handle_raw::<ApStop>(cs, event_data, event_data_size)
handle_raw::<ApStop>(event_data, event_data_size)
}
WifiEvent::ApStaconnected => {
handle_raw::<ApStaconnected>(cs, event_data, event_data_size)
handle_raw::<ApStaconnected>(event_data, event_data_size)
}
WifiEvent::ApStadisconnected => {
handle_raw::<ApStadisconnected>(cs, event_data, event_data_size)
handle_raw::<ApStadisconnected>(event_data, event_data_size)
}
WifiEvent::ApProbereqrecved => {
handle_raw::<ApProbereqrecved>(cs, event_data, event_data_size)
handle_raw::<ApProbereqrecved>(event_data, event_data_size)
}
WifiEvent::FtmReport => {
handle_raw::<FtmReport>(cs, event_data, event_data_size)
handle_raw::<FtmReport>(event_data, event_data_size)
}
WifiEvent::StaBssRssiLow => {
handle_raw::<StaBssRssiLow>(cs, event_data, event_data_size)
handle_raw::<StaBssRssiLow>(event_data, event_data_size)
}
WifiEvent::ActionTxStatus => {
handle_raw::<ActionTxStatus>(cs, event_data, event_data_size)
handle_raw::<ActionTxStatus>(event_data, event_data_size)
}
WifiEvent::RocDone => {
handle_raw::<RocDone>(cs, event_data, event_data_size)
handle_raw::<RocDone>(event_data, event_data_size)
}
WifiEvent::StaBeaconTimeout => {
handle_raw::<StaBeaconTimeout>(cs, event_data, event_data_size)
handle_raw::<StaBeaconTimeout>(event_data, event_data_size)
}
WifiEvent::ConnectionlessModuleWakeIntervalStart => {
handle_raw::<ConnectionlessModuleWakeIntervalStart>(cs, event_data, event_data_size)
handle_raw::<ConnectionlessModuleWakeIntervalStart>(event_data, event_data_size)
}
WifiEvent::ApWpsRgSuccess => {
handle_raw::<ApWpsRgSuccess>(cs, event_data, event_data_size)
handle_raw::<ApWpsRgSuccess>(event_data, event_data_size)
}
WifiEvent::ApWpsRgFailed => {
handle_raw::<ApWpsRgFailed>(cs, event_data, event_data_size)
handle_raw::<ApWpsRgFailed>(event_data, event_data_size)
}
WifiEvent::ApWpsRgTimeout => {
handle_raw::<ApWpsRgTimeout>(cs, event_data, event_data_size)
handle_raw::<ApWpsRgTimeout>(event_data, event_data_size)
}
WifiEvent::ApWpsRgPin => {
handle_raw::<ApWpsRgPin>(cs, event_data, event_data_size)
handle_raw::<ApWpsRgPin>(event_data, event_data_size)
}
WifiEvent::ApWpsRgPbcOverlap => {
handle_raw::<ApWpsRgPbcOverlap>(cs, event_data, event_data_size)
handle_raw::<ApWpsRgPbcOverlap>(event_data, event_data_size)
}
WifiEvent::ItwtSetup => {
handle_raw::<ItwtSetup>(cs, event_data, event_data_size)
handle_raw::<ItwtSetup>(event_data, event_data_size)
}
WifiEvent::ItwtTeardown => {
handle_raw::<ItwtTeardown>(cs, event_data, event_data_size)
handle_raw::<ItwtTeardown>(event_data, event_data_size)
}
WifiEvent::ItwtProbe => {
handle_raw::<ItwtProbe>(cs, event_data, event_data_size)
handle_raw::<ItwtProbe>(event_data, event_data_size)
}
WifiEvent::ItwtSuspend => {
handle_raw::<ItwtSuspend>(cs, event_data, event_data_size)
handle_raw::<ItwtSuspend>(event_data, event_data_size)
}
WifiEvent::TwtWakeup => {
handle_raw::<TwtWakeup>(cs, event_data, event_data_size)
handle_raw::<TwtWakeup>(event_data, event_data_size)
}
WifiEvent::BtwtSetup => {
handle_raw::<BtwtSetup>(cs, event_data, event_data_size)
handle_raw::<BtwtSetup>(event_data, event_data_size)
}
WifiEvent::BtwtTeardown => {
handle_raw::<BtwtTeardown>(cs, event_data, event_data_size)
handle_raw::<BtwtTeardown>(event_data, event_data_size)
}
WifiEvent::NanStarted => {
handle_raw::<NanStarted>(cs, event_data, event_data_size)
handle_raw::<NanStarted>(event_data, event_data_size)
}
WifiEvent::NanStopped => {
handle_raw::<NanStopped>(cs, event_data, event_data_size)
handle_raw::<NanStopped>(event_data, event_data_size)
}
WifiEvent::NanSvcMatch => {
handle_raw::<NanSvcMatch>(cs, event_data, event_data_size)
handle_raw::<NanSvcMatch>(event_data, event_data_size)
}
WifiEvent::NanReplied => {
handle_raw::<NanReplied>(cs, event_data, event_data_size)
handle_raw::<NanReplied>(event_data, event_data_size)
}
WifiEvent::NanReceive => {
handle_raw::<NanReceive>(cs, event_data, event_data_size)
handle_raw::<NanReceive>(event_data, event_data_size)
}
WifiEvent::NdpIndication => {
handle_raw::<NdpIndication>(cs, event_data, event_data_size)
handle_raw::<NdpIndication>(event_data, event_data_size)
}
WifiEvent::NdpConfirm => {
handle_raw::<NdpConfirm>(cs, event_data, event_data_size)
handle_raw::<NdpConfirm>(event_data, event_data_size)
}
WifiEvent::NdpTerminated => {
handle_raw::<NdpTerminated>(cs, event_data, event_data_size)
handle_raw::<NdpTerminated>(event_data, event_data_size)
}
WifiEvent::HomeChannelChange => {
handle_raw::<HomeChannelChange>(cs, event_data, event_data_size)
handle_raw::<HomeChannelChange>(event_data, event_data_size)
}
WifiEvent::StaNeighborRep => {
handle_raw::<StaNeighborRep>(cs, event_data, event_data_size)
handle_raw::<StaNeighborRep>(event_data, event_data_size)
}
}
}

View File

@ -6,15 +6,14 @@ pub(crate) mod state;
use alloc::collections::vec_deque::VecDeque;
use core::{
cell::{RefCell, RefMut},
fmt::Debug,
mem::{self, MaybeUninit},
ptr::addr_of,
time::Duration,
};
use critical_section::{CriticalSection, Mutex};
use enumset::{EnumSet, EnumSetType};
use esp_hal::sync::Locked;
use esp_wifi_sys::include::{
esp_eap_client_clear_ca_cert,
esp_eap_client_clear_certificate_and_key,
@ -952,11 +951,11 @@ const DATA_FRAME_SIZE: usize = MTU + ETHERNET_FRAME_HEADER_SIZE;
const RX_QUEUE_SIZE: usize = crate::CONFIG.rx_queue_size;
const TX_QUEUE_SIZE: usize = crate::CONFIG.tx_queue_size;
pub(crate) static DATA_QUEUE_RX_AP: Mutex<RefCell<VecDeque<EspWifiPacketBuffer>>> =
Mutex::new(RefCell::new(VecDeque::new()));
pub(crate) static DATA_QUEUE_RX_AP: Locked<VecDeque<EspWifiPacketBuffer>> =
Locked::new(VecDeque::new());
pub(crate) static DATA_QUEUE_RX_STA: Mutex<RefCell<VecDeque<EspWifiPacketBuffer>>> =
Mutex::new(RefCell::new(VecDeque::new()));
pub(crate) static DATA_QUEUE_RX_STA: Locked<VecDeque<EspWifiPacketBuffer>> =
Locked::new(VecDeque::new());
/// Common errors.
#[derive(Debug, Clone, Copy)]
@ -1529,14 +1528,13 @@ unsafe extern "C" fn recv_cb_sta(
eb: *mut c_types::c_void,
) -> esp_err_t {
let packet = EspWifiPacketBuffer { buffer, len, eb };
// We must handle the result outside of the critical section because
// We must handle the result outside of the lock because
// EspWifiPacketBuffer::drop must not be called in a critical section.
// Dropping an EspWifiPacketBuffer will call `esp_wifi_internal_free_rx_buffer`
// which will try to lock an internal mutex. If the mutex is already taken,
// the function will try to trigger a context switch, which will fail if we
// are in a critical section.
if critical_section::with(|cs| {
let mut queue = DATA_QUEUE_RX_STA.borrow_ref_mut(cs);
// are in an interrupt-free context.
if DATA_QUEUE_RX_STA.with(|queue| {
if queue.len() < RX_QUEUE_SIZE {
queue.push_back(packet);
true
@ -1563,9 +1561,8 @@ unsafe extern "C" fn recv_cb_ap(
// Dropping an EspWifiPacketBuffer will call `esp_wifi_internal_free_rx_buffer`
// which will try to lock an internal mutex. If the mutex is already taken,
// the function will try to trigger a context switch, which will fail if we
// are in a critical section.
if critical_section::with(|cs| {
let mut queue = DATA_QUEUE_RX_AP.borrow_ref_mut(cs);
// are in an interrupt-free context.
if DATA_QUEUE_RX_AP.with(|queue| {
if queue.len() < RX_QUEUE_SIZE {
queue.push_back(packet);
true
@ -1905,7 +1902,7 @@ mod sealed {
fn wrap_config(config: Self::Config) -> Configuration;
fn data_queue_rx(self, cs: CriticalSection) -> RefMut<'_, VecDeque<EspWifiPacketBuffer>>;
fn data_queue_rx(self) -> &'static Locked<VecDeque<EspWifiPacketBuffer>>;
fn can_send(self) -> bool {
WIFI_TX_INFLIGHT.load(Ordering::SeqCst) < TX_QUEUE_SIZE
@ -1928,13 +1925,12 @@ mod sealed {
}
fn rx_token(self) -> Option<(WifiRxToken<Self>, WifiTxToken<Self>)> {
let is_empty = critical_section::with(|cs| self.data_queue_rx(cs).is_empty());
let is_empty = self.data_queue_rx().with(|q| q.is_empty());
if is_empty || !self.can_send() {
crate::timer::yield_task();
}
let is_empty =
is_empty && critical_section::with(|cs| self.data_queue_rx(cs).is_empty());
let is_empty = is_empty && self.data_queue_rx().with(|q| q.is_empty());
if !is_empty {
self.tx_token().map(|tx| (WifiRxToken { mode: self }, tx))
@ -1967,8 +1963,8 @@ mod sealed {
Configuration::Client(config)
}
fn data_queue_rx(self, cs: CriticalSection) -> RefMut<'_, VecDeque<EspWifiPacketBuffer>> {
DATA_QUEUE_RX_STA.borrow_ref_mut(cs)
fn data_queue_rx(self) -> &'static Locked<VecDeque<EspWifiPacketBuffer>> {
&DATA_QUEUE_RX_STA
}
fn interface(self) -> wifi_interface_t {
@ -2003,8 +1999,8 @@ mod sealed {
Configuration::AccessPoint(config)
}
fn data_queue_rx(self, cs: CriticalSection) -> RefMut<'_, VecDeque<EspWifiPacketBuffer>> {
DATA_QUEUE_RX_AP.borrow_ref_mut(cs)
fn data_queue_rx(self) -> &'static Locked<VecDeque<EspWifiPacketBuffer>> {
&DATA_QUEUE_RX_AP
}
fn interface(self) -> wifi_interface_t {
@ -2321,7 +2317,7 @@ impl PromiscuousPkt<'_> {
frame_type,
len,
data: core::slice::from_raw_parts(
(buf as *const u8).add(size_of::<wifi_pkt_rx_ctrl_t>()),
(buf as *const u8).add(core::mem::size_of::<wifi_pkt_rx_ctrl_t>()),
len,
),
}
@ -2329,18 +2325,14 @@ impl PromiscuousPkt<'_> {
}
#[cfg(feature = "sniffer")]
#[allow(clippy::type_complexity)]
static SNIFFER_CB: Mutex<RefCell<Option<fn(PromiscuousPkt)>>> = Mutex::new(RefCell::new(None));
static SNIFFER_CB: Locked<Option<fn(PromiscuousPkt)>> = Locked::new(None);
#[cfg(feature = "sniffer")]
unsafe extern "C" fn promiscuous_rx_cb(buf: *mut core::ffi::c_void, frame_type: u32) {
critical_section::with(|cs| {
let Some(sniffer_callback) = *SNIFFER_CB.borrow_ref(cs) else {
return;
};
if let Some(sniffer_callback) = SNIFFER_CB.with(|callback| *callback) {
let promiscuous_pkt = PromiscuousPkt::from_raw(buf as *const _, frame_type);
sniffer_callback(promiscuous_pkt);
});
}
}
#[cfg(feature = "sniffer")]
@ -2385,9 +2377,7 @@ impl Sniffer {
}
/// Set the callback for receiving a packet.
pub fn set_receive_cb(&mut self, cb: fn(PromiscuousPkt)) {
critical_section::with(|cs| {
*SNIFFER_CB.borrow_ref_mut(cs) = Some(cb);
});
SNIFFER_CB.with(|callback| *callback = Some(cb));
}
}
@ -2675,21 +2665,19 @@ impl<MODE: Sealed> WifiRxToken<MODE> {
where
F: FnOnce(&mut [u8]) -> R,
{
let mut data = critical_section::with(|cs| {
let mut queue = self.mode.data_queue_rx(cs);
let mut data = self.mode.data_queue_rx().with(|queue| {
unwrap!(
queue.pop_front(),
"unreachable: transmit()/receive() ensures there is a packet to process"
)
});
// We handle the received data outside of the critical section because
// We handle the received data outside of the lock because
// EspWifiPacketBuffer::drop must not be called in a critical section.
// Dropping an EspWifiPacketBuffer will call `esp_wifi_internal_free_rx_buffer`
// which will try to lock an internal mutex. If the mutex is already
// taken, the function will try to trigger a context switch, which will
// fail if we are in a critical section.
// fail if we are in an interrupt-free context.
let buffer = data.as_slice_mut();
dump_packet_info(buffer);
@ -3321,7 +3309,7 @@ mod asynch {
}
fn clear_events(events: impl Into<EnumSet<WifiEvent>>) {
critical_section::with(|cs| WIFI_EVENTS.borrow_ref_mut(cs).remove_all(events.into()));
WIFI_EVENTS.with(|evts| evts.get_mut().remove_all(events.into()));
}
/// Wait for one [`WifiEvent`].
@ -3390,7 +3378,7 @@ mod asynch {
cx: &mut core::task::Context<'_>,
) -> Poll<Self::Output> {
self.event.waker().register(cx.waker());
if critical_section::with(|cs| WIFI_EVENTS.borrow_ref_mut(cs).remove(self.event)) {
if WIFI_EVENTS.with(|events| events.get_mut().remove(self.event)) {
Poll::Ready(())
} else {
Poll::Pending
@ -3417,8 +3405,8 @@ mod asynch {
self: core::pin::Pin<&mut Self>,
cx: &mut core::task::Context<'_>,
) -> Poll<Self::Output> {
let output = critical_section::with(|cs| {
let mut events = WIFI_EVENTS.borrow_ref_mut(cs);
let output = WIFI_EVENTS.with(|events| {
let events = events.get_mut();
let active = events.intersection(self.event);
events.remove_all(active);
active

View File

@ -9,8 +9,8 @@ pub(crate) mod os_adapter_chip_specific;
use core::{cell::RefCell, ptr::addr_of_mut};
use critical_section::Mutex;
use enumset::EnumSet;
use esp_hal::sync::{Lock, Locked};
use super::WifiEvent;
use crate::{
@ -35,12 +35,14 @@ use crate::{
timer::yield_task,
};
static WIFI_LOCK: Lock = Lock::new();
static mut QUEUE_HANDLE: *mut ConcurrentQueue = core::ptr::null_mut();
// useful for waiting for events - clear and wait for the event bit to be set
// again
pub(crate) static WIFI_EVENTS: Mutex<RefCell<EnumSet<WifiEvent>>> =
Mutex::new(RefCell::new(enumset::enum_set!()));
pub(crate) static WIFI_EVENTS: Locked<RefCell<EnumSet<WifiEvent>>> =
Locked::new(RefCell::new(enumset::enum_set!()));
/// **************************************************************************
/// Name: wifi_env_is_chip
@ -214,10 +216,11 @@ pub unsafe extern "C" fn spin_lock_delete(lock: *mut crate::binary::c_types::c_v
///
/// *************************************************************************
pub unsafe extern "C" fn wifi_int_disable(
wifi_int_mux: *mut crate::binary::c_types::c_void,
_wifi_int_mux: *mut crate::binary::c_types::c_void,
) -> u32 {
trace!("wifi_int_disable");
crate::wifi::os_adapter::os_adapter_chip_specific::wifi_int_disable(wifi_int_mux)
// TODO: can we use wifi_int_mux?
unsafe { WIFI_LOCK.acquire() as _ }
}
/// **************************************************************************
@ -236,11 +239,12 @@ pub unsafe extern "C" fn wifi_int_disable(
///
/// *************************************************************************
pub unsafe extern "C" fn wifi_int_restore(
wifi_int_mux: *mut crate::binary::c_types::c_void,
_wifi_int_mux: *mut crate::binary::c_types::c_void,
tmp: u32,
) {
trace!("wifi_int_restore");
crate::wifi::os_adapter::os_adapter_chip_specific::wifi_int_restore(wifi_int_mux, tmp)
let token = tmp as critical_section::RawRestoreState;
unsafe { WIFI_LOCK.release(token) }
}
/// **************************************************************************
@ -867,11 +871,8 @@ pub unsafe extern "C" fn event_post(
let event = unwrap!(WifiEvent::from_i32(event_id));
trace!("EVENT: {:?}", event);
let mut handled = false;
critical_section::with(|cs| {
WIFI_EVENTS.borrow_ref_mut(cs).insert(event);
handled = super::event::dispatch_event_handler(cs, event, event_data, event_data_size);
});
WIFI_EVENTS.with(|events| events.borrow_mut().insert(event));
let handled = super::event::dispatch_event_handler(event, event_data, event_data_size);
super::state::update_state(event, handled);

View File

@ -1,11 +1,5 @@
#![allow(unused_variables)]
#![allow(dead_code)]
#![allow(non_snake_case)]
use crate::hal::{interrupt, peripherals};
const DPORT_WIFI_CLK_WIFI_EN_M: u32 = 0x406;
pub(crate) fn chip_ints_on(mask: u32) {
unsafe { crate::hal::xtensa_lx::interrupt::enable_mask(mask) };
}
@ -14,21 +8,6 @@ pub(crate) fn chip_ints_off(mask: u32) {
crate::hal::xtensa_lx::interrupt::disable_mask(mask);
}
pub(crate) unsafe extern "C" fn wifi_int_disable(
wifi_int_mux: *mut crate::binary::c_types::c_void,
) -> u32 {
core::mem::transmute(critical_section::acquire())
}
pub(crate) unsafe extern "C" fn wifi_int_restore(
wifi_int_mux: *mut crate::binary::c_types::c_void,
tmp: u32,
) {
critical_section::release(core::mem::transmute::<u32, critical_section::RestoreState>(
tmp,
))
}
pub(crate) unsafe extern "C" fn phy_common_clock_disable() {
crate::common_adapter::chip_specific::phy_disable_clock();
}
@ -50,24 +29,6 @@ pub(crate) unsafe extern "C" fn set_intr(
intr_matrix_set(0, intr_source, intr_num);
}
pub(crate) unsafe extern "C" fn wifi_clock_enable() {
let dport = &*crate::hal::peripherals::SYSTEM::ptr();
dport.wifi_clk_en().modify(|r, w| {
let old = r.bits();
let new_bits = old | DPORT_WIFI_CLK_WIFI_EN_M;
w.bits(new_bits)
});
}
pub(crate) unsafe extern "C" fn wifi_clock_disable() {
let dport = &*crate::hal::peripherals::SYSTEM::ptr();
dport.wifi_clk_en().modify(|r, w| {
let old = r.bits();
let new_bits = old & !DPORT_WIFI_CLK_WIFI_EN_M;
w.bits(new_bits)
});
}
/// **************************************************************************
/// Name: esp_set_isr
///

View File

@ -1,8 +1,4 @@
use crate::hal::{
interrupt,
peripherals::{self, Interrupt},
riscv,
};
use crate::hal::{interrupt, peripherals};
pub(crate) fn chip_ints_on(mask: u32) {
unsafe {
@ -20,40 +16,6 @@ pub(crate) fn chip_ints_off(mask: u32) {
}
}
pub(crate) unsafe extern "C" fn wifi_int_disable(
wifi_int_mux: *mut crate::binary::c_types::c_void,
) -> u32 {
let res = if riscv::register::mstatus::read().mie() {
1
} else {
0
};
riscv::interrupt::disable();
trace!(
"wifi_int_disable wifi_int_mux {:?} - return {}",
wifi_int_mux,
res,
);
res
}
pub(crate) unsafe extern "C" fn wifi_int_restore(
wifi_int_mux: *mut crate::binary::c_types::c_void,
tmp: u32,
) {
trace!(
"wifi_int_restore wifi_int_mux {:?} tmp {}",
wifi_int_mux,
tmp
);
if tmp == 1 {
riscv::interrupt::enable();
}
}
pub(crate) unsafe extern "C" fn set_intr(
_cpu_no: i32,
_intr_source: u32,
@ -103,11 +65,11 @@ pub unsafe extern "C" fn set_isr(
#[cfg(feature = "wifi")]
{
unwrap!(interrupt::enable(
Interrupt::WIFI_MAC,
peripherals::Interrupt::WIFI_MAC,
interrupt::Priority::Priority1
));
unwrap!(interrupt::enable(
Interrupt::WIFI_PWR,
peripherals::Interrupt::WIFI_PWR,
interrupt::Priority::Priority1
));
}

View File

@ -1,8 +1,4 @@
use crate::hal::{
interrupt,
peripherals::{self, Interrupt},
riscv,
};
use crate::hal::{interrupt, peripherals};
pub(crate) fn chip_ints_on(mask: u32) {
unsafe {
@ -20,40 +16,6 @@ pub(crate) fn chip_ints_off(mask: u32) {
}
}
pub(crate) unsafe extern "C" fn wifi_int_disable(
wifi_int_mux: *mut crate::binary::c_types::c_void,
) -> u32 {
let res = if riscv::register::mstatus::read().mie() {
1
} else {
0
};
riscv::interrupt::disable();
trace!(
"wifi_int_disable wifi_int_mux {:?} - return {}",
wifi_int_mux,
res,
);
res
}
pub(crate) unsafe extern "C" fn wifi_int_restore(
wifi_int_mux: *mut crate::binary::c_types::c_void,
tmp: u32,
) {
trace!(
"wifi_int_restore wifi_int_mux {:?} tmp {}",
wifi_int_mux,
tmp
);
if tmp == 1 {
riscv::interrupt::enable();
}
}
pub(crate) unsafe extern "C" fn set_intr(
_cpu_no: i32,
_intr_source: u32,
@ -104,11 +66,11 @@ pub unsafe extern "C" fn set_isr(
#[cfg(feature = "wifi")]
{
unwrap!(interrupt::enable(
Interrupt::WIFI_MAC,
peripherals::Interrupt::WIFI_MAC,
interrupt::Priority::Priority1
));
unwrap!(interrupt::enable(
Interrupt::WIFI_PWR,
peripherals::Interrupt::WIFI_PWR,
interrupt::Priority::Priority1
));
}

View File

@ -1,8 +1,4 @@
use crate::hal::{
interrupt,
peripherals::{self, Interrupt},
riscv,
};
use crate::hal::{interrupt, peripherals};
pub(crate) fn chip_ints_on(mask: u32) {
unsafe {
@ -20,40 +16,6 @@ pub(crate) fn chip_ints_off(mask: u32) {
}
}
pub(crate) unsafe extern "C" fn wifi_int_disable(
wifi_int_mux: *mut crate::binary::c_types::c_void,
) -> u32 {
let res = if riscv::register::mstatus::read().mie() {
1
} else {
0
};
riscv::interrupt::disable();
trace!(
"wifi_int_disable wifi_int_mux {:?} - return {}",
wifi_int_mux,
res,
);
res
}
pub(crate) unsafe extern "C" fn wifi_int_restore(
wifi_int_mux: *mut crate::binary::c_types::c_void,
tmp: u32,
) {
trace!(
"wifi_int_restore wifi_int_mux {:?} tmp {}",
wifi_int_mux,
tmp
);
if tmp == 1 {
riscv::interrupt::enable();
}
}
pub(crate) unsafe extern "C" fn set_intr(
_cpu_no: i32,
_intr_source: u32,
@ -117,11 +79,11 @@ pub unsafe extern "C" fn set_isr(
#[cfg(feature = "wifi")]
{
unwrap!(interrupt::enable(
Interrupt::WIFI_MAC,
peripherals::Interrupt::WIFI_MAC,
interrupt::Priority::Priority1
));
unwrap!(interrupt::enable(
Interrupt::WIFI_PWR,
peripherals::Interrupt::WIFI_PWR,
interrupt::Priority::Priority1
));
}

View File

@ -1,8 +1,4 @@
use crate::hal::{
interrupt,
peripherals::{self, Interrupt},
riscv,
};
use crate::hal::{interrupt, peripherals};
pub(crate) fn chip_ints_on(mask: u32) {
unsafe {
@ -20,40 +16,6 @@ pub(crate) fn chip_ints_off(mask: u32) {
}
}
pub(crate) unsafe extern "C" fn wifi_int_disable(
wifi_int_mux: *mut crate::binary::c_types::c_void,
) -> u32 {
let res = if riscv::register::mstatus::read().mie() {
1
} else {
0
};
riscv::interrupt::disable();
trace!(
"wifi_int_disable wifi_int_mux {:?} - return {}",
wifi_int_mux,
res,
);
res
}
pub(crate) unsafe extern "C" fn wifi_int_restore(
wifi_int_mux: *mut crate::binary::c_types::c_void,
tmp: u32,
) {
trace!(
"wifi_int_restore wifi_int_mux {:?} tmp {}",
wifi_int_mux,
tmp
);
if tmp == 1 {
riscv::interrupt::enable();
}
}
pub(crate) unsafe extern "C" fn set_intr(
_cpu_no: i32,
_intr_source: u32,

View File

@ -1,7 +1,3 @@
#![allow(unused_variables)]
#![allow(dead_code)]
#![allow(non_snake_case)]
use crate::hal::{interrupt, peripherals};
pub(crate) fn chip_ints_on(mask: u32) {
@ -12,21 +8,6 @@ pub(crate) fn chip_ints_off(mask: u32) {
crate::hal::xtensa_lx::interrupt::disable_mask(mask);
}
pub(crate) unsafe extern "C" fn wifi_int_disable(
wifi_int_mux: *mut crate::binary::c_types::c_void,
) -> u32 {
core::mem::transmute(critical_section::acquire())
}
pub(crate) unsafe extern "C" fn wifi_int_restore(
wifi_int_mux: *mut crate::binary::c_types::c_void,
tmp: u32,
) {
critical_section::release(core::mem::transmute::<u32, critical_section::RestoreState>(
tmp,
))
}
pub(crate) unsafe extern "C" fn set_intr(
_cpu_no: i32,
intr_source: u32,

View File

@ -1,7 +1,3 @@
#![allow(unused_variables)]
#![allow(dead_code)]
#![allow(non_snake_case)]
use crate::hal::{interrupt, peripherals};
pub(crate) fn chip_ints_on(mask: u32) {
@ -12,21 +8,6 @@ pub(crate) fn chip_ints_off(mask: u32) {
crate::hal::xtensa_lx::interrupt::disable_mask(mask);
}
pub(crate) unsafe extern "C" fn wifi_int_disable(
wifi_int_mux: *mut crate::binary::c_types::c_void,
) -> u32 {
core::mem::transmute(critical_section::acquire())
}
pub(crate) unsafe extern "C" fn wifi_int_restore(
wifi_int_mux: *mut crate::binary::c_types::c_void,
tmp: u32,
) {
critical_section::release(core::mem::transmute::<u32, critical_section::RestoreState>(
tmp,
))
}
pub(crate) unsafe extern "C" fn set_intr(
_cpu_no: i32,
intr_source: u32,

View File

@ -52,15 +52,15 @@ fn main() -> ! {
// Set event handlers for wifi before init to avoid missing any.
let mut connections = 0u32;
_ = event::ApStart::replace_handler(|_, _| esp_println::println!("ap start event"));
event::ApStaconnected::update_handler(move |_, event| {
_ = event::ApStart::replace_handler(|_| esp_println::println!("ap start event"));
event::ApStaconnected::update_handler(move |event| {
connections += 1;
esp_println::println!("connected {}, mac: {:?}", connections, event.0.mac);
});
event::ApStaconnected::update_handler(|_, event| {
event::ApStaconnected::update_handler(|event| {
esp_println::println!("connected aid: {}", event.0.aid);
});
event::ApStadisconnected::update_handler(|_, event| {
event::ApStadisconnected::update_handler(|event| {
esp_println::println!(
"disconnected mac: {:?}, reason: {:?}",
event.0.mac,

View File

@ -9,7 +9,7 @@
//! Because of the huge task-arena size configured this won't work on ESP32-S2
//!
//% FEATURES: embassy embassy-generic-timers esp-wifi esp-wifi/wifi esp-wifi/utils
//% FEATURES: embassy embassy-generic-timers esp-wifi esp-wifi/wifi esp-wifi/utils esp-wifi/sniffer
//% CHIPS: esp32 esp32s2 esp32s3 esp32c2 esp32c3 esp32c6
#![no_std]