Skip to content

Commit

Permalink
embassy: create esp-wifi-thread if threading enabled
Browse files Browse the repository at this point in the history
  • Loading branch information
elenaf9 committed May 27, 2024
1 parent fb9f68e commit 69c69ad
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 88 deletions.
3 changes: 0 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 4 additions & 14 deletions examples/threading-net-tcp/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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" }

67 changes: 5 additions & 62 deletions examples/threading-net-tcp/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand All @@ -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 {
Expand All @@ -100,6 +41,8 @@ async fn tcp_echo() {
}
};

//println!("rxd {:02x}", &buf[..n]);

match socket.write_all(&buf[..n]).await {
Ok(()) => {}
Err(e) => {
Expand Down
94 changes: 85 additions & 9 deletions src/riot-rs-embassy/src/wifi/esp_wifi.rs
Original file line number Diff line number Diff line change
@@ -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>;

Expand All @@ -14,6 +19,9 @@ pub type NetworkDevice = WifiDevice<'static, WifiStaDevice>;
// sure.
pub static WIFI_INIT: OnceCell<EspWifiInitialization> = OnceCell::new();

#[cfg(feature = "threading")]
pub static WIFI_THREAD_ID: OnceCell<riot_rs_threads::ThreadId> = OnceCell::new();

pub fn init(peripherals: &mut OptionalPeripherals, spawner: Spawner) -> NetworkDevice {
let wifi = peripherals.WIFI.take().unwrap();
let init = WIFI_INIT.get().unwrap();
Expand All @@ -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());
Expand Down Expand Up @@ -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();
}
}

0 comments on commit 69c69ad

Please sign in to comment.