feat(wifi): implement a mutex for the wifi_controller and add it to the WifiService state

This commit is contained in:
2026-08-27 23:12:30 -05:00
parent 68412464ec
commit 15fad17fab
+41 -33
View File
@@ -1,27 +1,34 @@
use defmt::{error, info};
use embassy_executor::Spawner;
use embassy_futures::select::{Either, select};
use embassy_net::{Runner, Stack};
use embassy_sync::signal::Signal;
use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, rpc_service::RpcService};
use embassy_sync::{
blocking_mutex::raw::CriticalSectionRawMutex, mutex::Mutex, rpc_service::RpcService,
};
use embassy_time::{Duration, Timer};
use esp_hal::peripherals::WIFI;
use esp_radio::wifi::sta::StationConfig;
use esp_radio::wifi::{ControllerConfig, Interface, WifiController};
use esp_radio::wifi::{ControllerConfig, Interface, WifiController, WifiError};
pub static WIFI_SERVICE: RpcService<CriticalSectionRawMutex, WifiService, 64> = RpcService::new();
pub struct WifiService {
pub net_stack: Stack<'static>
pub net_stack: Stack<'static>,
wifi_controller: &'static Mutex<CriticalSectionRawMutex, WifiController<'static>>,
}
impl WifiService {
pub async fn set_station_config(config: esp_radio::wifi::Config) {
WIFI_HANDLER_RPC.signal(config);
pub async fn set_station_config(
&self,
config: esp_radio::wifi::Config,
) -> Result<(), WifiError> {
let mut controller = self.wifi_controller.lock().await;
controller.set_config(&config)?;
Ok(())
}
pub async fn set_dhcp_config(&self, config: embassy_net::DhcpConfig) {
self.net_stack.set_config_v4(embassy_net::ConfigV4::Dhcp(config));
pub fn set_dhcp_config(&self, config: embassy_net::DhcpConfig) {
self.net_stack
.set_config_v4(embassy_net::ConfigV4::Dhcp(config));
}
}
@@ -51,53 +58,54 @@ pub fn start_wifi(spawner: Spawner, wifi: WIFI<'static>) -> Stack<'static> {
seed,
);
spawner.spawn(net_task(net_runner).unwrap());
spawner.spawn(wifi_handler(wifi_controller).unwrap());
let service = WifiService {
net_stack: net_stack,
wifi_controller: crate::mk_static!(Mutex<CriticalSectionRawMutex, WifiController<'static>>, Mutex::new(wifi_controller)),
};
spawner.spawn(net_handler(net_runner).unwrap());
spawner.spawn(connection_handler(service.wifi_controller).unwrap());
spawner.spawn(handler(service).unwrap());
spawner.spawn(ip_logger(net_stack).unwrap());
spawner.spawn(handler(net_stack).unwrap());
net_stack
}
#[embassy_executor::task]
async fn handler(net_stack: Stack<'static>) {
WIFI_SERVICE.run(&mut WifiService {net_stack: net_stack}).await;
async fn handler(mut service: WifiService) -> ! {
WIFI_SERVICE.run(&mut service).await
}
static WIFI_HANDLER_RPC: Signal<CriticalSectionRawMutex, esp_radio::wifi::Config> = Signal::new();
#[embassy_executor::task]
async fn wifi_handler(mut controller: WifiController<'static>) {
let connection = async |controller: &mut WifiController<'static>| {
async fn connection_handler(
controller: &'static Mutex<CriticalSectionRawMutex, WifiController<'static>>,
) -> ! {
loop {
info!("Connecting to WiFi...");
match controller.connect_async().await {
match controller.lock().await.connect_async().await {
Ok(info) => {
info!("Wifi connected to {:?}", info);
// wait until we're no longer connected
let info = controller.wait_for_disconnect_async().await.ok();
info!("Disconnected: {:?}", info);
// TODO: reimplement the wait for disconnect
// let info = controller
// .lock()
// .await
// .wait_for_disconnect_async()
// .await
// .ok();
// info!("Disconnected: {:?}", info);
}
Err(e) => {
error!("Failed to connect to wifi: {:?}", e);
}
}
};
loop {
if let Either::First(req) =
select(WIFI_HANDLER_RPC.wait(), connection(&mut controller)).await
{
if let Some(err) = controller.set_config(&req).err() {
error!("Wifi controller failed to set a new config: {:?}", err)
}
}
}
}
#[embassy_executor::task]
async fn ip_logger(net_stack: Stack<'static>) {
async fn ip_logger(net_stack: Stack<'static>) -> ! {
loop {
info!("Getting IP address...");
net_stack.wait_config_up().await;
@@ -120,6 +128,6 @@ async fn ip_logger(net_stack: Stack<'static>) {
}
#[embassy_executor::task]
async fn net_task(mut runner: Runner<'static, Interface<'static>>) {
async fn net_handler(mut runner: Runner<'static, Interface<'static>>) -> ! {
runner.run().await
}