From 69c69ad26c7ead96ba8921d78a46cee79c96afc2 Mon Sep 17 00:00:00 2001 From: Elena Frank Date: Mon, 27 May 2024 10:57:38 +0200 Subject: [PATCH] embassy: create esp-wifi-thread if threading enabled --- Cargo.lock | 3 - examples/threading-net-tcp/Cargo.toml | 18 +---- examples/threading-net-tcp/src/main.rs | 67 ++--------------- src/riot-rs-embassy/src/wifi/esp_wifi.rs | 94 +++++++++++++++++++++--- 4 files changed, 94 insertions(+), 88 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7a5f268b4..2a96656cd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3847,11 +3847,8 @@ dependencies = [ "embassy-net", "embassy-time", "embedded-io-async", - "esp-hal", - "heapless 0.8.0", "riot-rs", "riot-rs-boards", - "static_cell", ] [[package]] diff --git a/examples/threading-net-tcp/Cargo.toml b/examples/threading-net-tcp/Cargo.toml index 3c3d33f34..2b3ba7c0a 100644 --- a/examples/threading-net-tcp/Cargo.toml +++ b/examples/threading-net-tcp/Cargo.toml @@ -6,20 +6,10 @@ edition.workspace = true publish = false [dependencies] - -embassy-executor = { workspace = true, default-features = false } -embassy-time = { workspace = true, default-features = false } -riot-rs = { path = "../../src/riot-rs", features = ["threading"] } -riot-rs-boards = { path = "../../src/riot-rs-boards" } -static_cell = "2.1" +embassy-executor = { workspace = true } embassy-net = { workspace = true, features = ["tcp"] } -heapless = { workspace = true } +embassy-time = { workspace = true } embedded-io-async = "0.6.1" - - -[target.'cfg(context = "esp32c3")'.dependencies] -esp-hal = { workspace = true, features = ["esp32c3"] } - -[target.'cfg(context = "esp32c6")'.dependencies] -esp-hal = { workspace = true, features = ["esp32c6"] } +riot-rs = { path = "../../src/riot-rs", features = ["threading"] } +riot-rs-boards = { path = "../../src/riot-rs-boards" } diff --git a/examples/threading-net-tcp/src/main.rs b/examples/threading-net-tcp/src/main.rs index d6af02eeb..07699ca63 100644 --- a/examples/threading-net-tcp/src/main.rs +++ b/examples/threading-net-tcp/src/main.rs @@ -4,71 +4,12 @@ #![feature(used_with_arg)] use embassy_net::tcp::TcpSocket; +use embassy_time::Duration; use embedded_io_async::Write; -use esp_hal::{ - interrupt, - peripherals::{Interrupt, SYSTIMER}, -}; -use riot_rs::{ - debug::println, - embassy::network, - thread::{thread_flags, ThreadId}, -}; +use riot_rs::{debug::println, embassy::network}; -#[cfg(context = "esp32c6")] -use esp_hal::peripherals::INTPRI as SystemPeripheral; -#[cfg(context = "esp32c3")] -use esp_hal::peripherals::SYSTEM as SystemPeripheral; - -// Handle the systimer alarm 0 interrupt, configured in esp-wifi. -extern "C" fn systimer_target0_() { - unsafe { - SYSTIMER::steal() - .int_clr() - .write(|w| w.target0().clear_bit_by_one()) - } - // Wakeup `esp_wifi_thread`. - riot_rs::thread::wakeup(ThreadId::new(0)); -} - -// CPU Interrupt 3 triggers the scheduler in `esp-wifi`. -fn yield_to_esp_wifi_scheduler() { - unsafe { - (&*SystemPeripheral::PTR) - .cpu_intr_from_cpu_3() - .modify(|_, w| w.cpu_intr_from_cpu_3().set_bit()); - } -} - -/// High priority thread that frequently wakes up to run the esp-wifi -/// scheduler. -#[riot_rs::thread(autostart, priority = 10, stacksize = 4096)] -fn esp_wifi_thread() { - // Wait until `embassy` was intialized. - thread_flags::wait_all(1); - - // Bind the periodic systimer that is configured in esp-wifi to our own handler. - unsafe { - interrupt::bind_interrupt( - Interrupt::SYSTIMER_TARGET0, - core::mem::transmute(systimer_target0_ as *const ()), - ); - } - - loop { - // Yield to the esp-wifi scheduler tasks, so that they get a chance to run. - yield_to_esp_wifi_scheduler(); - // Sleep until the systimer alarm 0 interrupts again. - riot_rs::thread::sleep() - } -} - -/// Application task. #[riot_rs::task(autostart)] async fn tcp_echo() { - // Start the esp-wifi thread. - thread_flags::set(ThreadId::new(0), 1); - let stack = network::network_stack().await.unwrap(); let mut rx_buffer = [0; 4096]; @@ -77,7 +18,7 @@ async fn tcp_echo() { loop { let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer); - socket.set_timeout(Some(embassy_time::Duration::from_secs(10))); + socket.set_timeout(Some(Duration::from_secs(10))); println!("Listening on TCP:1234..."); if let Err(e) = socket.accept(1234).await { @@ -100,6 +41,8 @@ async fn tcp_echo() { } }; + //println!("rxd {:02x}", &buf[..n]); + match socket.write_all(&buf[..n]).await { Ok(()) => {} Err(e) => { diff --git a/src/riot-rs-embassy/src/wifi/esp_wifi.rs b/src/riot-rs-embassy/src/wifi/esp_wifi.rs index b85f16533..e491b7a6e 100644 --- a/src/riot-rs-embassy/src/wifi/esp_wifi.rs +++ b/src/riot-rs-embassy/src/wifi/esp_wifi.rs @@ -1,9 +1,14 @@ -use esp_wifi::{wifi::WifiStaDevice, EspWifiInitialization}; -use once_cell::sync::OnceCell; - use crate::{arch::OptionalPeripherals, Spawner}; - -use esp_wifi::wifi::{WifiController, WifiDevice}; +use embassy_time::{Duration, Timer}; +use esp_wifi::{ + wifi::{ + ClientConfiguration, Configuration, WifiController, WifiDevice, WifiEvent, WifiStaDevice, + WifiState, + }, + EspWifiInitialization, +}; +use once_cell::sync::OnceCell; +use riot_rs_debug::println; pub type NetworkDevice = WifiDevice<'static, WifiStaDevice>; @@ -14,6 +19,9 @@ pub type NetworkDevice = WifiDevice<'static, WifiStaDevice>; // sure. pub static WIFI_INIT: OnceCell = OnceCell::new(); +#[cfg(feature = "threading")] +pub static WIFI_THREAD_ID: OnceCell = OnceCell::new(); + pub fn init(peripherals: &mut OptionalPeripherals, spawner: Spawner) -> NetworkDevice { let wifi = peripherals.WIFI.take().unwrap(); let init = WIFI_INIT.get().unwrap(); @@ -26,10 +34,11 @@ pub fn init(peripherals: &mut OptionalPeripherals, spawner: Spawner) -> NetworkD #[embassy_executor::task] async fn connection(mut controller: WifiController<'static>) { - use riot_rs_debug::println; - - use embassy_time::{Duration, Timer}; - use esp_wifi::wifi::{ClientConfiguration, Configuration, WifiEvent, WifiState}; + #[cfg(feature = "threading")] + { + let thread_id = WIFI_THREAD_ID.get().unwrap(); + riot_rs_threads::wakeup(*thread_id); + } println!("start connection task"); println!("Device capabilities: {:?}", controller.get_capabilities()); @@ -64,3 +73,70 @@ async fn connection(mut controller: WifiController<'static>) { } } } + +#[cfg(feature = "threading")] +mod wifi_thread { + + use super::*; + #[cfg(context = "esp32c6")] + use esp_hal::peripherals::INTPRI as SystemPeripheral; + #[cfg(context = "esp32c3")] + use esp_hal::peripherals::SYSTEM as SystemPeripheral; + use esp_hal::{ + interrupt, + peripherals::{Interrupt, SYSTIMER}, + }; + + // Handle the systimer alarm 0 interrupt, configured in esp-wifi. + extern "C" fn systimer_target0_() { + unsafe { + SYSTIMER::steal() + .int_clr() + .write(|w| w.target0().clear_bit_by_one()) + } + // Wakeup `esp_wifi_thread`. + riot_rs_threads::wakeup(*WIFI_THREAD_ID.get().unwrap()); + } + + // CPU Interrupt 3 triggers the scheduler in `esp-wifi`. + fn yield_to_esp_wifi_scheduler() { + unsafe { + (&*SystemPeripheral::PTR) + .cpu_intr_from_cpu_3() + .modify(|_, w| w.cpu_intr_from_cpu_3().set_bit()); + } + } + + /// High priority thread that frequently wakes up to run the esp-wifi + /// scheduler. + fn esp_wifi_thread() { + // Wait until `embassy` was intialized. + riot_rs_threads::sleep(); + + // Bind the periodic systimer that is configured in esp-wifi to our own handler. + unsafe { + interrupt::bind_interrupt( + Interrupt::SYSTIMER_TARGET0, + core::mem::transmute(systimer_target0_ as *const ()), + ); + } + + loop { + // Yield to the esp-wifi scheduler tasks, so that they get a chance to run. + yield_to_esp_wifi_scheduler(); + // Sleep until the systimer alarm 0 interrupts again. + riot_rs_threads::sleep() + } + } + + #[linkme::distributed_slice(riot_rs_threads::THREAD_FNS)] + fn start_esp_wifi_thread() { + let stack = static_cell::make_static!([0u8; 2048]); + let id = riot_rs_threads::thread_create_noarg( + esp_wifi_thread, + stack, + riot_rs_threads::SCHED_PRIO_LEVELS as u8 - 1, + ); + WIFI_THREAD_ID.set(id).unwrap(); + } +}