diff --git a/embassy-net/src/lib.rs b/embassy-net/src/lib.rs index 51eb97a2e..47a3650b0 100644 --- a/embassy-net/src/lib.rs +++ b/embassy-net/src/lib.rs @@ -14,7 +14,7 @@ pub use config::{Config, Configurator, Event as ConfigEvent, StaticConfigurator} pub use device::{Device, LinkState}; pub use packet_pool::{Packet, PacketBox, PacketBoxExt, PacketBuf, MTU}; -pub use stack::{init, is_config_up, is_init, is_link_up, run}; +pub use stack::{init, is_config_up, is_init, is_link_up, run, StackResources}; #[cfg(feature = "tcp")] mod tcp_socket; diff --git a/embassy-net/src/stack.rs b/embassy-net/src/stack.rs index a38f00958..5e795a4fd 100644 --- a/embassy-net/src/stack.rs +++ b/embassy-net/src/stack.rs @@ -4,7 +4,7 @@ use core::task::Context; use core::task::Poll; use embassy::time::{Instant, Timer}; use embassy::util::ThreadModeMutex; -use embassy::util::{Forever, WakerRegistration}; +use embassy::util::WakerRegistration; use futures::pin_mut; use smoltcp::iface::InterfaceBuilder; #[cfg(feature = "medium-ethernet")] @@ -22,23 +22,34 @@ use crate::config::Event; use crate::device::{Device, DeviceAdapter, LinkState}; use crate::{Interface, SocketSet}; -const ADDRESSES_LEN: usize = 1; -const NEIGHBOR_CACHE_LEN: usize = 8; -const SOCKETS_LEN: usize = 2; const LOCAL_PORT_MIN: u16 = 1025; const LOCAL_PORT_MAX: u16 = 65535; -struct StackResources { - addresses: [IpCidr; ADDRESSES_LEN], - sockets: [Option>; SOCKETS_LEN], +pub struct StackResources { + addresses: [IpCidr; ADDR], + sockets: [Option>; SOCK], #[cfg(feature = "medium-ethernet")] routes: [Option<(IpCidr, Route)>; 1], #[cfg(feature = "medium-ethernet")] - neighbor_cache: [Option<(IpAddress, Neighbor)>; NEIGHBOR_CACHE_LEN], + neighbor_cache: [Option<(IpAddress, Neighbor)>; NEIGHBOR], +} + +impl + StackResources +{ + pub fn new() -> Self { + const NONE_SOCKET: Option> = None; + + Self { + addresses: [IpCidr::new(Ipv4Address::UNSPECIFIED.into(), 32); ADDR], + sockets: [NONE_SOCKET; SOCK], + routes: [None; 1], + neighbor_cache: [None; NEIGHBOR], + } + } } -static STACK_RESOURCES: Forever = Forever::new(); static STACK: ThreadModeMutex>> = ThreadModeMutex::new(RefCell::new(None)); pub(crate) struct Stack { @@ -164,18 +175,11 @@ fn set_ipv4_addr(iface: &mut Interface, cidr: Ipv4Cidr) { /// Initialize embassy_net. /// This function must be called from thread mode. -pub fn init(device: &'static mut dyn Device, configurator: &'static mut dyn Configurator) { - const NONE_SOCKET: Option> = None; - let res = STACK_RESOURCES.put(StackResources { - addresses: [IpCidr::new(Ipv4Address::UNSPECIFIED.into(), 32)], - sockets: [NONE_SOCKET; SOCKETS_LEN], - - #[cfg(feature = "medium-ethernet")] - routes: [None; 1], - #[cfg(feature = "medium-ethernet")] - neighbor_cache: [None; NEIGHBOR_CACHE_LEN], - }); - +pub fn init( + device: &'static mut dyn Device, + configurator: &'static mut dyn Configurator, + resources: &'static mut StackResources, +) { let medium = device.capabilities().medium; #[cfg(feature = "medium-ethernet")] @@ -186,18 +190,18 @@ pub fn init(device: &'static mut dyn Device, configurator: &'static mut dyn Conf }; let mut b = InterfaceBuilder::new(DeviceAdapter::new(device)); - b = b.ip_addrs(&mut res.addresses[..]); + b = b.ip_addrs(&mut resources.addresses[..]); #[cfg(feature = "medium-ethernet")] if medium == Medium::Ethernet { b = b.ethernet_addr(EthernetAddress(ethernet_addr)); - b = b.neighbor_cache(NeighborCache::new(&mut res.neighbor_cache[..])); - b = b.routes(Routes::new(&mut res.routes[..])); + b = b.neighbor_cache(NeighborCache::new(&mut resources.neighbor_cache[..])); + b = b.routes(Routes::new(&mut resources.routes[..])); } let iface = b.finalize(); - let sockets = SocketSet::new(&mut res.sockets[..]); + let sockets = SocketSet::new(&mut resources.sockets[..]); let local_port = loop { let mut res = [0u8; 2]; diff --git a/examples/std/src/bin/net.rs b/examples/std/src/bin/net.rs index 5a726e5d2..344a6e4d3 100644 --- a/examples/std/src/bin/net.rs +++ b/examples/std/src/bin/net.rs @@ -19,6 +19,7 @@ use crate::tuntap::TunTapDevice; static DEVICE: Forever = Forever::new(); static CONFIG: Forever = Forever::new(); +static NET_RESOURCES: Forever> = Forever::new(); #[derive(Clap)] #[clap(version = "1.0")] @@ -51,8 +52,10 @@ async fn main_task(spawner: Spawner) { // DHCP configruation let config = DhcpConfigurator::new(); + let net_resources = StackResources::new(); + // Init network stack - embassy_net::init(DEVICE.put(device), CONFIG.put(config)); + embassy_net::init(DEVICE.put(device), CONFIG.put(config), NET_RESOURCES.put(net_resources)); // Launch network task spawner.spawn(net_task()).unwrap(); diff --git a/examples/stm32h7/src/bin/eth.rs b/examples/stm32h7/src/bin/eth.rs index 57997da0a..7d7ff941e 100644 --- a/examples/stm32h7/src/bin/eth.rs +++ b/examples/stm32h7/src/bin/eth.rs @@ -16,7 +16,9 @@ use embassy::io::AsyncWriteExt; use embassy::time::{Duration, Timer}; use embassy::util::Forever; use embassy_macros::interrupt_take; -use embassy_net::{Config as NetConfig, Ipv4Address, Ipv4Cidr, StaticConfigurator, TcpSocket}; +use embassy_net::{ + Config as NetConfig, Ipv4Address, Ipv4Cidr, StackResources, StaticConfigurator, TcpSocket, +}; use embassy_stm32::clock::{Alarm, Clock}; use embassy_stm32::eth::lan8742a::LAN8742A; use embassy_stm32::eth::Ethernet; @@ -43,8 +45,10 @@ async fn main_task( config: &'static mut StaticConfigurator, spawner: Spawner, ) { + let net_resources = NET_RESOURCES.put(StackResources::new()); + // Init network stack - embassy_net::init(device, config); + embassy_net::init(device, config, net_resources); // Launch network task unwrap!(spawner.spawn(net_task())); @@ -97,6 +101,7 @@ static ALARM: Forever> = Forever::new(); static ETH: Forever> = Forever::new(); static DEVICE: Forever>> = Forever::new(); static CONFIG: Forever = Forever::new(); +static NET_RESOURCES: Forever> = Forever::new(); #[entry] fn main() -> ! {