feat: use the embedded-rpc library for the wifi service

This commit is contained in:
2026-08-17 17:38:00 -05:00
parent 8695d0abfa
commit aed1e41665
3 changed files with 83 additions and 62 deletions
Generated
+10
View File
@@ -191,6 +191,7 @@ dependencies = [
"embassy-net",
"embassy-sync 0.8.0",
"embassy-time",
"embedded-rpc",
"esp-alloc",
"esp-backtrace",
"esp-bootloader-esp-idf",
@@ -688,6 +689,15 @@ dependencies = [
"embedded-nal",
]
[[package]]
name = "embedded-rpc"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "691855ab7f974e2aaa87433e0f6e5967a959f312c486f6f929ff1cda14c7f80d"
dependencies = [
"embassy-sync 0.8.0",
]
[[package]]
name = "embedded-storage"
version = "0.3.1"
+1
View File
@@ -58,6 +58,7 @@ portable-atomic = "1.15.0"
picoserve = { version = "0.19", features = ["defmt", "embassy", "json"] }
embassy-sync = { version = "0.8.0", features = ["defmt"] }
embassy-futures = { version = "0.1.2", features = ["defmt"] }
embedded-rpc = "0.2.0"
# For fine tuning these settings, please refer to https://doc.rust-lang.org/cargo/reference/profiles.html
+41 -31
View File
@@ -1,11 +1,10 @@
use defmt::{error, info};
use embassy_executor::Spawner;
use embassy_futures::select::Either::First;
use embassy_futures::select::select;
use embassy_futures::select::{Either, select};
use embassy_net::{Runner, Stack};
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
use embassy_sync::{channel::Channel};
use embassy_time::{Duration, Timer};
use embedded_rpc::{RequestDroppedError, RpcService};
use esp_hal::peripherals::WIFI;
use esp_radio::wifi::sta::StationConfig;
use esp_radio::wifi::{ControllerConfig, Interface, WifiController};
@@ -16,14 +15,16 @@ pub enum WifiCommand {
}
impl WifiCommand {
pub async fn set_station_config(config: esp_radio::wifi::Config) {
WIFI_CH
.send(WifiCommand::SetStationConfig(config))
.await;
pub async fn set_station_config(
config: esp_radio::wifi::Config,
) -> Result<(), RequestDroppedError> {
WIFI_SERVICE
.request(WifiCommand::SetStationConfig(config))
.await
}
}
pub static WIFI_CH: Channel<CriticalSectionRawMutex, WifiCommand, 4> = Channel::new();
pub static WIFI_SERVICE: RpcService<CriticalSectionRawMutex, WifiCommand, ()> = RpcService::new();
pub fn start_wifi(spawner: Spawner, wifi: WIFI<'static>) -> Stack<'static> {
let wifi_config = esp_radio::wifi::Config::Station(StationConfig::default());
@@ -52,37 +53,39 @@ pub fn start_wifi(spawner: Spawner, wifi: WIFI<'static>) -> Stack<'static> {
);
spawner.spawn(net_task(net_runner).unwrap());
spawner.spawn(handler(wifi_controller, net_stack).unwrap());
spawner.spawn(wifi_handler(wifi_controller).unwrap());
spawner.spawn(ip_logger(net_stack).unwrap());
spawner.spawn(handler(net_stack).unwrap());
net_stack
}
#[embassy_executor::task]
async fn handler(mut controller: WifiController<'static>, net_stack: Stack<'static>) {
let receiver = WIFI_CH.receiver();
async fn handler(net_stack: Stack<'static>) {
loop {
match select(receiver.receive(), connection(&mut controller, net_stack)).await {
First(WifiCommand::SetStationConfig(config)) => {
if controller.set_config(&config).is_err() {
error!("Set WiFi config failed: {:?}", config);
};
let (req, served) = WIFI_SERVICE.serve().await;
match req {
WifiCommand::SetStationConfig(config) => {
if WIFI_HANDLER_RPC.request(config).await.is_err() {
continue;
}
First(WifiCommand::SetDhcpConfig(dhcp_config)) => {
}
WifiCommand::SetDhcpConfig(dhcp_config) => {
net_stack.set_config_v4(embassy_net::ConfigV4::Dhcp(dhcp_config));
}
embassy_futures::select::Either::Second(_) => {
unreachable!("connection function should be infinite loop")
}
}
served.respond(());
}
}
async fn connection(controller: &mut WifiController<'static>, net_stack: Stack<'static>) {
info!("start connection task");
static WIFI_HANDLER_RPC: RpcService<CriticalSectionRawMutex, esp_radio::wifi::Config, ()> =
RpcService::new();
select(
async {
loop {
#[embassy_executor::task]
async fn wifi_handler(mut controller: WifiController<'static>) {
let connection = async |controller: &mut WifiController<'static>| {
info!("Connecting to WiFi...");
match controller.connect_async().await {
@@ -97,11 +100,21 @@ async fn connection(controller: &mut WifiController<'static>, net_stack: Stack<'
error!("Failed to connect to wifi: {:?}", e);
}
}
};
Timer::after(Duration::from_millis(5000)).await
loop {
if let Either::First((req, served)) =
select(WIFI_HANDLER_RPC.serve(), connection(&mut controller)).await
{
if controller.set_config(&req).is_ok() {
served.respond(());
}
},
async {
}
}
}
#[embassy_executor::task]
async fn ip_logger(net_stack: Stack<'static>) {
loop {
info!("Getting IP address...");
net_stack.wait_config_up().await;
@@ -121,9 +134,6 @@ async fn connection(controller: &mut WifiController<'static>, net_stack: Stack<'
Timer::after(Duration::from_millis(5000)).await
}
},
)
.await;
}
#[embassy_executor::task]