From b1d2c836f1893a7b880937a3fbe1313fb7978f5c Mon Sep 17 00:00:00 2001 From: Matt Johnston Date: Fri, 29 Nov 2024 05:28:19 +0100 Subject: [PATCH] Update demos for embassy-net Removes some duplication between cyw43 vs w5500 --- Cargo.lock | 116 ++++++++--------------------- embassy/demos/common/Cargo.toml | 2 +- embassy/demos/common/src/config.rs | 18 ++--- embassy/demos/common/src/server.rs | 3 +- embassy/demos/picow/Cargo.toml | 2 +- embassy/demos/picow/src/main.rs | 64 ++++++---------- embassy/demos/picow/src/w5500.rs | 22 ++---- embassy/demos/picow/src/wifi.rs | 21 ++---- embassy/demos/std/Cargo.toml | 2 +- embassy/demos/std/src/main.rs | 21 ++---- 10 files changed, 91 insertions(+), 180 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 78c6a7e..0bc6de8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -130,27 +130,6 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" -[[package]] -name = "as-slice" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45403b49e3954a4b8428a0ac21a4b7afadccf92bfd96273f1a58cd4812496ae0" -dependencies = [ - "generic-array 0.12.4", - "generic-array 0.13.3", - "generic-array 0.14.7", - "stable_deref_trait", -] - -[[package]] -name = "as-slice" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "516b6b4f0e40d50dcda9365d53964ec74560ad4284da2e7fc97122cd83174516" -dependencies = [ - "stable_deref_trait", -] - [[package]] name = "ascii" version = "1.1.0" @@ -204,18 +183,6 @@ dependencies = [ "critical-section", ] -[[package]] -name = "atomic-pool" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58c5fc22e05ec2884db458bf307dc7b278c9428888d2b6e6fad9c0ae7804f5f6" -dependencies = [ - "as-slice 0.1.5", - "as-slice 0.2.1", - "atomic-polyfill", - "stable_deref_trait", -] - [[package]] name = "autocfg" version = "1.1.0" @@ -320,7 +287,7 @@ version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ - "generic-array 0.14.7", + "generic-array", ] [[package]] @@ -517,7 +484,7 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" dependencies = [ - "generic-array 0.14.7", + "generic-array", "rand_core", "subtle", "zeroize", @@ -529,7 +496,7 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ - "generic-array 0.14.7", + "generic-array", "typenum", ] @@ -762,7 +729,7 @@ dependencies = [ "crypto-bigint", "digest", "ff", - "generic-array 0.14.7", + "generic-array", "group", "pkcs8", "rand_core", @@ -834,25 +801,20 @@ dependencies = [ [[package]] name = "embassy-net" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55cf91dd36dfd623de32242af711fd294d41159f02130052fc93c5c5ba93febe" +checksum = "49f9f2979069031c153e41075a43074c36a64492e598780b27944a605f829d23" dependencies = [ - "as-slice 0.2.1", - "atomic-pool", "document-features", "embassy-net-driver", - "embassy-sync 0.5.0", + "embassy-sync 0.6.1", "embassy-time", "embedded-io-async", "embedded-nal-async", - "futures", - "generic-array 0.14.7", "heapless 0.8.0", "log", "managed", "smoltcp", - "stable_deref_trait", ] [[package]] @@ -959,11 +921,25 @@ dependencies = [ "heapless 0.8.0", ] +[[package]] +name = "embassy-sync" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3899a6e39fa3f54bf8aaf00979f9f9c0145a522f7244810533abbb748be6ce82" +dependencies = [ + "cfg-if", + "critical-section", + "embedded-io-async", + "futures-sink", + "futures-util", + "heapless 0.8.0", +] + [[package]] name = "embassy-time" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "274c019608a9004aed3cafc871e2a3c87ce9351d537dcaab4cc5db184d4a04b1" +checksum = "158080d48f824fad101d7b2fae2d83ac39e3f7a6fa01811034f7ab8ffc6e7309" dependencies = [ "cfg-if", "critical-section", @@ -1089,23 +1065,21 @@ dependencies = [ [[package]] name = "embedded-nal" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8a943fad5ed3d3f8a00f1e80f6bba371f1e7f0df28ec38477535eb318dc19cc" +checksum = "c56a28be191a992f28f178ec338a0bf02f63d7803244add736d026a471e6ed77" dependencies = [ "nb 1.1.0", - "no-std-net", ] [[package]] name = "embedded-nal-async" -version = "0.7.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72229137a4fc12d239b0b7f50f04b30790678da6d782a0f3f1909bf57ec4b759" +checksum = "76959917cd2b86f40a98c28dd5624eddd1fa69d746241c8257eac428d83cb211" dependencies = [ "embedded-io-async", "embedded-nal", - "no-std-net", ] [[package]] @@ -1335,24 +1309,6 @@ dependencies = [ "slab", ] -[[package]] -name = "generic-array" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" -dependencies = [ - "typenum", -] - -[[package]] -name = "generic-array" -version = "0.13.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f797e67af32588215eaaab8327027ee8e71b9dd0b2b26996aedf20c030fce309" -dependencies = [ - "typenum", -] - [[package]] name = "generic-array" version = "0.14.7" @@ -1498,7 +1454,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" dependencies = [ - "generic-array 0.14.7", + "generic-array", ] [[package]] @@ -1734,12 +1690,6 @@ dependencies = [ "pin-utils", ] -[[package]] -name = "no-std-net" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43794a0ace135be66a25d3ae77d41b91615fb68ae937f904090203e81f755b65" - [[package]] name = "num-bigint-dig" version = "0.8.4" @@ -2391,7 +2341,7 @@ checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ "base16ct", "der", - "generic-array 0.14.7", + "generic-array", "pkcs8", "subtle", "zeroize", @@ -2502,9 +2452,9 @@ checksum = "3b187f0231d56fe41bfb12034819dd2bf336422a5866de41bc3fec4b2e3883e8" [[package]] name = "smoltcp" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a1a996951e50b5971a2c8c0fa05a381480d70a933064245c4a223ddc87ccc97" +checksum = "dad095989c1533c1c266d9b1e8d70a1329dd3723c3edac6d03bbd67e7bf6f4bb" dependencies = [ "bitflags 1.3.2", "byteorder", @@ -3362,9 +3312,9 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" dependencies = [ "zeroize_derive", ] diff --git a/embassy/demos/common/Cargo.toml b/embassy/demos/common/Cargo.toml index 7ab437c..b76b8a7 100644 --- a/embassy/demos/common/Cargo.toml +++ b/embassy/demos/common/Cargo.toml @@ -10,7 +10,7 @@ sunset = { path = "../../.." } sunset-sshwire-derive = { path = "../../../sshwire-derive" } embassy-sync = { version = "0.5" } -embassy-net = { version = "0.4", features = ["tcp", "dhcpv4", "medium-ethernet", "log"] } +embassy-net = { version = "0.5", features = ["tcp", "dhcpv4", "medium-ethernet", "log"] } embassy-net-driver = { version = "0.2" } embassy-futures = { version = "0.1" } embassy-time = { version = "0.3" } diff --git a/embassy/demos/common/src/config.rs b/embassy/demos/common/src/config.rs index d54db5c..65d1334 100644 --- a/embassy/demos/common/src/config.rs +++ b/embassy/demos/common/src/config.rs @@ -156,10 +156,10 @@ where fn enc_ip4config(v: &Option, s: &mut dyn SSHSink) -> WireResult<()> { v.is_some().enc(s)?; if let Some(v) = v { - v.address.address().0.enc(s)?; + v.address.address().to_bits().enc(s)?; v.address.prefix_len().enc(s)?; - // to [u8; 4] - let gw = v.gateway.map(|a| a.0); + // to u32 + let gw = v.gateway.map(|a| a.to_bits()); enc_option(&gw, s)?; } Ok(()) @@ -171,15 +171,15 @@ where { let opt = bool::dec(s)?; opt.then(|| { - let ad: [u8; 4] = SSHDecode::dec(s)?; - let ad = Ipv4Address::from_bytes(&ad); + let ad: u32 = SSHDecode::dec(s)?; + let ad = Ipv4Address::from_bits(ad); let prefix = SSHDecode::dec(s)?; if prefix > 32 { // emabassy panics, so test it here return Err(WireError::PacketWrong) } - let gw: Option<[u8; 4]> = dec_option(s)?; - let gateway = gw.map(|gw| Ipv4Address::from_bytes(&gw)); + let gw: Option = dec_option(s)?; + let gateway = gw.map(|gw| Ipv4Address::from_bits(gw)); Ok(StaticConfigV4 { address: Ipv4Cidr::new(ad, prefix), gateway, @@ -364,8 +364,8 @@ mod tests { ), mac: [6, 2, 3, 4, 5, 6], ip4_static: Some(embassy_net::StaticConfigV4 { - address: embassy_net::Ipv4Cidr::new(embassy_net::Ipv4Address([44,33,22,11]), 8), - gateway: Some(embassy_net::Ipv4Address([1,2,3,4])), + address: embassy_net::Ipv4Cidr::new(embassy_net::Ipv4Address::new(44,33,22,11), 8), + gateway: Some(embassy_net::Ipv4Address::new(1,2,3,4)), // no dns servers. may need changing later? dns_servers: heapless::Vec::new(), }), diff --git a/embassy/demos/common/src/server.rs b/embassy/demos/common/src/server.rs index bf93444..0678005 100644 --- a/embassy/demos/common/src/server.rs +++ b/embassy/demos/common/src/server.rs @@ -4,7 +4,6 @@ use log::{debug, error, info, log, trace, warn}; use embassy_net::tcp::TcpSocket; use embassy_net::Stack; -use embassy_net_driver::Driver; use embassy_futures::select::{select, Either}; use embedded_io_async::Write; @@ -17,7 +16,7 @@ use sunset_embassy::{SSHServer, SunsetMutex}; use crate::SSHConfig; // common entry point -pub async fn listener(stack: &'static Stack, +pub async fn listener(stack: Stack<'_>, config: &SunsetMutex, init: S::Init) -> ! { // TODO: buffer size? diff --git a/embassy/demos/picow/Cargo.toml b/embassy/demos/picow/Cargo.toml index 54a4305..a095414 100644 --- a/embassy/demos/picow/Cargo.toml +++ b/embassy/demos/picow/Cargo.toml @@ -21,7 +21,7 @@ embassy-executor = { version = "0.5", features = [ "task-arena-size-131072"] } embassy-time = { version = "0.3", features = [] } embassy-rp = { version = "0.1", features = ["unstable-pac", "time-driver"] } -embassy-net = { version = "0.4", features = ["tcp", "dhcpv4", "medium-ethernet", "log"] } +embassy-net = { version = "0.5", features = ["tcp", "dhcpv4", "medium-ethernet", "log"] } embassy-net-driver = { version = "0.2" } embassy-usb-driver = { version = "0.1" } embassy-sync = { version = "0.5" } diff --git a/embassy/demos/picow/src/main.rs b/embassy/demos/picow/src/main.rs index 2952085..d649260 100644 --- a/embassy/demos/picow/src/main.rs +++ b/embassy/demos/picow/src/main.rs @@ -110,37 +110,28 @@ async fn main(spawner: Spawner) { static STATE: StaticCell = StaticCell::new(); let state = STATE.init_with(|| GlobalState { usb_pipe, serial1_pipe, config, flash, watchdog, net_mac}); - // Spawn network tasks to handle incoming connections with demo_common::session() + // create the network stack #[cfg(feature = "cyw43")] - { - let stack = wifi::wifi_stack( - &spawner, p.PIN_23, p.PIN_24, p.PIN_25, p.PIN_29, p.DMA_CH0, p.PIO0, - config, - ) - .await; - - let HardwareAddress::Ethernet(EthernetAddress(eth)) = stack.hardware_address(); - *state.net_mac.lock().await = eth; - for _ in 0..NUM_LISTENERS { - debug!("spawn listen"); - spawner.spawn(cyw43_listener(&stack, config, state)).unwrap(); - } - } - + let stack = wifi::wifi_stack( + &spawner, p.PIN_23, p.PIN_24, p.PIN_25, p.PIN_29, p.DMA_CH0, p.PIO0, + config, + ) + .await; #[cfg(feature = "w5500")] - { - let stack = w5500::w5500_stack( - &spawner, p.PIN_16, p.PIN_17, p.PIN_18, p.PIN_19, p.PIN_20, p.PIN_21, - p.DMA_CH0, p.DMA_CH1, p.SPI0, config, - ) - .await; - - let HardwareAddress::Ethernet(EthernetAddress(eth)) = stack.hardware_address(); - *state.net_mac.lock().await = eth; - for _ in 0..NUM_LISTENERS { - spawner.spawn(w5500_listener(&stack, config, state)).unwrap(); - } + let stack = w5500::w5500_stack( + &spawner, p.PIN_16, p.PIN_17, p.PIN_18, p.PIN_19, p.PIN_20, p.PIN_21, + p.DMA_CH0, p.DMA_CH1, p.SPI0, config, + ) + .await; + + let HardwareAddress::Ethernet(EthernetAddress(eth)) = stack.hardware_address(); + *state.net_mac.lock().await = eth; + + // Spawn network tasks to handle incoming connections with demo_common::session() + for _ in 0..NUM_LISTENERS { + debug!("spawn listen"); + spawner.spawn(net_listener(stack, config, state)).unwrap(); } spawner @@ -157,24 +148,13 @@ async fn main(spawner: Spawner) { spawner.spawn(usb::task(p.USB, state)).unwrap(); } -#[cfg(feature = "cyw43")] -#[embassy_executor::task(pool_size = NUM_LISTENERS)] -async fn cyw43_listener( - stack: &'static Stack>, - config: &'static SunsetMutex, - global: &'static GlobalState, -) -> ! { - demo_common::listener::<_, PicoServer>(stack, config, global).await -} - -#[cfg(feature = "w5500")] #[embassy_executor::task(pool_size = NUM_LISTENERS)] -async fn w5500_listener( - stack: &'static Stack>, +async fn net_listener( + stack: Stack<'static>, config: &'static SunsetMutex, global: &'static GlobalState, ) -> ! { - demo_common::listener::<_, PicoServer>(stack, config, global).await + demo_common::listener::(stack, config, global).await } pub(crate) struct GlobalState { diff --git a/embassy/demos/picow/src/w5500.rs b/embassy/demos/picow/src/w5500.rs index 7665111..79b4e1d 100644 --- a/embassy/demos/picow/src/w5500.rs +++ b/embassy/demos/picow/src/w5500.rs @@ -6,7 +6,7 @@ pub use log::{debug, error, info, log, trace, warn}; use embassy_executor::Spawner; -use embassy_net::{Stack, StackResources}; +use embassy_net::{StackResources}; use embassy_rp::gpio::{Input, Level, Output, Pull}; use embassy_rp::peripherals::*; use embassy_rp::spi::{Async, Config as SpiConfig, Spi}; @@ -46,7 +46,7 @@ pub(crate) async fn w5500_stack( dma1: DMA_CH1, spi0: SPI0, config: &'static SunsetMutex, -) -> &'static embassy_net::Stack> { +) -> embassy_net::Stack<'static> { let mut spi_cfg = SpiConfig::default(); spi_cfg.frequency = 50_000_000; let (miso, mosi, clk) = (p16, p19, p18); @@ -59,7 +59,7 @@ pub(crate) async fn w5500_stack( // static STATE: StaticCell> = StaticCell::new(); let state = STATE.init_with(|| State::new()); - let (device, runner) = embassy_net_wiznet::new( + let (net_device, runner) = embassy_net_wiznet::new( mac_addr, state, ExclusiveDevice::new(spi, cs, Delay), @@ -69,7 +69,7 @@ pub(crate) async fn w5500_stack( .await; spawner.spawn(ethernet_task(runner)).unwrap(); - let config = if let Some(ref s) = config.lock().await.ip4_static { + let net_cf = if let Some(ref s) = config.lock().await.ip4_static { embassy_net::Config::ipv4_static(s.clone()) } else { embassy_net::Config::dhcpv4(Default::default()) @@ -80,21 +80,15 @@ pub(crate) async fn w5500_stack( // Init network stack static SR: StaticCell> = StaticCell::new(); - static STACK: StaticCell> = StaticCell::new(); - let stack = STACK.init_with(|| Stack::new( - device, - config, - SR.init_with(|| StackResources::new()), - seed - )); + let (stack, runner) = embassy_net::new(net_device, net_cf, SR.init(StackResources::new()), seed); // Launch network task - spawner.spawn(net_task(stack)).unwrap(); + spawner.spawn(net_task(runner)).unwrap(); stack } #[embassy_executor::task] -async fn net_task(stack: &'static Stack>) -> ! { - stack.run().await +async fn net_task(mut runner: embassy_net::Runner<'static, Device<'static>>) -> ! { + runner.run().await } diff --git a/embassy/demos/picow/src/wifi.rs b/embassy/demos/picow/src/wifi.rs index 255f60c..0f12d7b 100644 --- a/embassy/demos/picow/src/wifi.rs +++ b/embassy/demos/picow/src/wifi.rs @@ -11,7 +11,7 @@ use embassy_rp::pio::Pio; use embassy_rp::peripherals::*; use embassy_rp::bind_interrupts; use embassy_executor::Spawner; -use embassy_net::{Stack, StackResources}; +use embassy_net::StackResources; use cyw43_pio::PioSpi; @@ -41,7 +41,7 @@ pub(crate) async fn wifi_stack(spawner: &Spawner, p23: PIN_23, p24: PIN_24, p25: PIN_25, p29: PIN_29, dma: DMA_CH0, pio0: PIO0, config: &'static SunsetMutex, - ) -> &'static embassy_net::Stack> + ) -> embassy_net::Stack<'static> { let (fw, _clm) = get_fw(); @@ -63,24 +63,17 @@ pub(crate) async fn wifi_stack(spawner: &Spawner, embassy_net::Config::dhcpv4(Default::default()) }; - static SR: StaticCell> = StaticCell::new(); - // Init network stack - static STACK: StaticCell> = StaticCell::new(); - let stack = STACK.init_with(|| Stack::new( - net_device, - net_cf, - SR.init_with(|| StackResources::new()), - seed) - ); + static SR: StaticCell> = StaticCell::new(); + let (stack, runner) = embassy_net::new(net_device, net_cf, SR.init(StackResources::new()), seed); - spawner.spawn(net_task(stack, control, config)).unwrap(); + spawner.spawn(net_task(runner, control, config)).unwrap(); stack } #[embassy_executor::task] -async fn net_task(stack: &'static Stack>, +async fn net_task(mut runner: embassy_net::Runner<'static, cyw43::NetDriver<'static>>, mut control: cyw43::Control<'static>, config: &'static SunsetMutex, ) -> ! { @@ -114,7 +107,7 @@ async fn net_task(stack: &'static Stack>, } } - stack.run().await + runner.run().await } // Get the WiFi firmware and Country Locale Matrix (CLM) blobs. diff --git a/embassy/demos/std/Cargo.toml b/embassy/demos/std/Cargo.toml index 80e1436..11f119f 100644 --- a/embassy/demos/std/Cargo.toml +++ b/embassy/demos/std/Cargo.toml @@ -8,7 +8,7 @@ edition = "2021" embassy-executor = { version = "0.5", features = ["log", "arch-std", "integrated-timers", "executor-thread", "task-arena-size-131072"] } embassy-time = { version = "0.3", default-features=false, features = ["log", "std"] } # embassy-net/nightly is required for asynch::Read/Write on TcpReader/TcpWriter -embassy-net = { version = "0.4", features = ["tcp", "dhcpv4", "medium-ethernet"] } +embassy-net = { version = "0.5", features = ["tcp", "dhcpv4", "medium-ethernet"] } embassy-net-tuntap = { version = "0.1" } embassy-sync = { version = "0.5" } embassy-futures = { version = "0.1" } diff --git a/embassy/demos/std/src/main.rs b/embassy/demos/std/src/main.rs index b92515c..cb68eab 100644 --- a/embassy/demos/std/src/main.rs +++ b/embassy/demos/std/src/main.rs @@ -29,8 +29,8 @@ const NUM_LISTENERS: usize = 4; const NUM_SOCKETS: usize = NUM_LISTENERS+1; #[embassy_executor::task] -async fn net_task(stack: &'static Stack) -> ! { - stack.run().await +async fn net_task(mut runner: embassy_net::Runner<'static, TunTapDevice>) -> ! { + runner.run().await } #[embassy_executor::task] @@ -45,28 +45,23 @@ async fn main_task(spawner: Spawner) { SunsetMutex::new(config) })); - let net_config = if let Some(ref s) = config.lock().await.ip4_static { + let net_cf = if let Some(ref s) = config.lock().await.ip4_static { embassy_net::Config::ipv4_static(s.clone()) } else { embassy_net::Config::dhcpv4(Default::default()) }; // Init network device - let device = TunTapDevice::new(opt_tap0).unwrap(); + let net_device = TunTapDevice::new(opt_tap0).unwrap(); let seed = OsRng.next_u64(); // Init network stack let res = Box::leak(Box::new(StackResources::::new())); - let stack = Box::leak(Box::new(Stack::new( - device, - net_config, - res, - seed - ))); + let (stack, runner) = embassy_net::new(net_device, net_cf, res, seed); // Launch network task - spawner.spawn(net_task(stack)).unwrap(); + spawner.spawn(net_task(runner)).unwrap(); for _ in 0..NUM_LISTENERS { spawner.spawn(listener(stack, config)).unwrap(); @@ -152,10 +147,10 @@ impl DemoServer for StdDemo { // TODO: pool_size should be NUM_LISTENERS but needs a literal #[embassy_executor::task(pool_size = 4)] -async fn listener(stack: &'static Stack, +async fn listener(stack: Stack<'static>, config: &'static SunsetMutex) -> ! { - demo_common::listener::<_, StdDemo>(stack, config, ()).await + demo_common::listener::(stack, config, ()).await } #[embassy_executor::main]