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-net",
"embassy-sync 0.8.0", "embassy-sync 0.8.0",
"embassy-time", "embassy-time",
"embedded-rpc",
"esp-alloc", "esp-alloc",
"esp-backtrace", "esp-backtrace",
"esp-bootloader-esp-idf", "esp-bootloader-esp-idf",
@@ -688,6 +689,15 @@ dependencies = [
"embedded-nal", "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]] [[package]]
name = "embedded-storage" name = "embedded-storage"
version = "0.3.1" version = "0.3.1"
+1
View File
@@ -58,6 +58,7 @@ portable-atomic = "1.15.0"
picoserve = { version = "0.19", features = ["defmt", "embassy", "json"] } picoserve = { version = "0.19", features = ["defmt", "embassy", "json"] }
embassy-sync = { version = "0.8.0", features = ["defmt"] } embassy-sync = { version = "0.8.0", features = ["defmt"] }
embassy-futures = { version = "0.1.2", 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 # 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 defmt::{error, info};
use embassy_executor::Spawner; use embassy_executor::Spawner;
use embassy_futures::select::Either::First; use embassy_futures::select::{Either, select};
use embassy_futures::select::select;
use embassy_net::{Runner, Stack}; use embassy_net::{Runner, Stack};
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
use embassy_sync::{channel::Channel};
use embassy_time::{Duration, Timer}; use embassy_time::{Duration, Timer};
use embedded_rpc::{RequestDroppedError, RpcService};
use esp_hal::peripherals::WIFI; use esp_hal::peripherals::WIFI;
use esp_radio::wifi::sta::StationConfig; use esp_radio::wifi::sta::StationConfig;
use esp_radio::wifi::{ControllerConfig, Interface, WifiController}; use esp_radio::wifi::{ControllerConfig, Interface, WifiController};
@@ -16,14 +15,16 @@ pub enum WifiCommand {
} }
impl WifiCommand { impl WifiCommand {
pub async fn set_station_config(config: esp_radio::wifi::Config) { pub async fn set_station_config(
WIFI_CH config: esp_radio::wifi::Config,
.send(WifiCommand::SetStationConfig(config)) ) -> Result<(), RequestDroppedError> {
.await; 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> { pub fn start_wifi(spawner: Spawner, wifi: WIFI<'static>) -> Stack<'static> {
let wifi_config = esp_radio::wifi::Config::Station(StationConfig::default()); 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(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 net_stack
} }
#[embassy_executor::task] #[embassy_executor::task]
async fn handler(mut controller: WifiController<'static>, net_stack: Stack<'static>) { async fn handler(net_stack: Stack<'static>) {
let receiver = WIFI_CH.receiver();
loop { loop {
match select(receiver.receive(), connection(&mut controller, net_stack)).await { let (req, served) = WIFI_SERVICE.serve().await;
First(WifiCommand::SetStationConfig(config)) => {
if controller.set_config(&config).is_err() { match req {
error!("Set WiFi config failed: {:?}", config); 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)); 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>) { static WIFI_HANDLER_RPC: RpcService<CriticalSectionRawMutex, esp_radio::wifi::Config, ()> =
info!("start connection task"); RpcService::new();
select( #[embassy_executor::task]
async { async fn wifi_handler(mut controller: WifiController<'static>) {
loop { let connection = async |controller: &mut WifiController<'static>| {
info!("Connecting to WiFi..."); info!("Connecting to WiFi...");
match controller.connect_async().await { 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); 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 { loop {
info!("Getting IP address..."); info!("Getting IP address...");
net_stack.wait_config_up().await; 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 Timer::after(Duration::from_millis(5000)).await
} }
},
)
.await;
} }
#[embassy_executor::task] #[embassy_executor::task]