mirror of
https://github.com/embassy-rs/embassy.git
synced 2024-11-21 22:32:29 +00:00
net: refactor to simplify lifetimes/generics.
This commit is contained in:
parent
7648d42b7f
commit
be0d9775e3
2
ci.sh
2
ci.sh
@ -47,7 +47,7 @@ cargo batch \
|
|||||||
--- build --release --manifest-path embassy-sync/Cargo.toml --target thumbv6m-none-eabi --features defmt \
|
--- build --release --manifest-path embassy-sync/Cargo.toml --target thumbv6m-none-eabi --features defmt \
|
||||||
--- build --release --manifest-path embassy-time/Cargo.toml --target thumbv6m-none-eabi --features defmt,defmt-timestamp-uptime,generic-queue-8,mock-driver \
|
--- build --release --manifest-path embassy-time/Cargo.toml --target thumbv6m-none-eabi --features defmt,defmt-timestamp-uptime,generic-queue-8,mock-driver \
|
||||||
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv4,medium-ethernet,packet-trace \
|
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv4,medium-ethernet,packet-trace \
|
||||||
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv4,igmp,medium-ethernet \
|
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv4,multicast,medium-ethernet \
|
||||||
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,dhcpv4,medium-ethernet \
|
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,dhcpv4,medium-ethernet \
|
||||||
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,dhcpv4,medium-ethernet,dhcpv4-hostname \
|
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,dhcpv4,medium-ethernet,dhcpv4-hostname \
|
||||||
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ethernet \
|
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ethernet \
|
||||||
|
@ -16,11 +16,11 @@ categories = [
|
|||||||
[package.metadata.embassy_docs]
|
[package.metadata.embassy_docs]
|
||||||
src_base = "https://github.com/embassy-rs/embassy/blob/embassy-net-v$VERSION/embassy-net/src/"
|
src_base = "https://github.com/embassy-rs/embassy/blob/embassy-net-v$VERSION/embassy-net/src/"
|
||||||
src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-net/src/"
|
src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-net/src/"
|
||||||
features = ["defmt", "tcp", "udp", "raw", "dns", "dhcpv4", "proto-ipv6", "medium-ethernet", "medium-ip", "medium-ieee802154", "igmp", "dhcpv4-hostname"]
|
features = ["defmt", "tcp", "udp", "raw", "dns", "dhcpv4", "proto-ipv6", "medium-ethernet", "medium-ip", "medium-ieee802154", "multicast", "dhcpv4-hostname"]
|
||||||
target = "thumbv7em-none-eabi"
|
target = "thumbv7em-none-eabi"
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
features = ["defmt", "tcp", "udp", "raw", "dns", "dhcpv4", "proto-ipv6", "medium-ethernet", "medium-ip", "medium-ieee802154", "igmp", "dhcpv4-hostname"]
|
features = ["defmt", "tcp", "udp", "raw", "dns", "dhcpv4", "proto-ipv6", "medium-ethernet", "medium-ip", "medium-ieee802154", "multicast", "dhcpv4-hostname"]
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
@ -60,15 +60,15 @@ medium-ethernet = ["smoltcp/medium-ethernet"]
|
|||||||
medium-ip = ["smoltcp/medium-ip"]
|
medium-ip = ["smoltcp/medium-ip"]
|
||||||
## Enable the IEEE 802.15.4 medium
|
## Enable the IEEE 802.15.4 medium
|
||||||
medium-ieee802154 = ["smoltcp/medium-ieee802154"]
|
medium-ieee802154 = ["smoltcp/medium-ieee802154"]
|
||||||
## Enable IGMP support
|
## Enable multicast support (for both ipv4 and/or ipv6 if enabled)
|
||||||
igmp = ["smoltcp/proto-igmp"]
|
multicast = ["smoltcp/multicast"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|
||||||
defmt = { version = "0.3", optional = true }
|
defmt = { version = "0.3", optional = true }
|
||||||
log = { version = "0.4.14", optional = true }
|
log = { version = "0.4.14", optional = true }
|
||||||
|
|
||||||
smoltcp = { version = "0.11.0", default-features = false, features = [
|
smoltcp = { git="https://github.com/smoltcp-rs/smoltcp", rev="dd43c8f189178b0ab3bda798ed8578b5b0a6f094", default-features = false, features = [
|
||||||
"socket",
|
"socket",
|
||||||
"async",
|
"async",
|
||||||
] }
|
] }
|
||||||
|
@ -10,8 +10,9 @@ memory management designed to work well for embedded systems, aiming for a more
|
|||||||
|
|
||||||
- IPv4, IPv6
|
- IPv4, IPv6
|
||||||
- Ethernet and bare-IP mediums.
|
- Ethernet and bare-IP mediums.
|
||||||
- TCP, UDP, DNS, DHCPv4, IGMPv4
|
- TCP, UDP, DNS, DHCPv4
|
||||||
- TCP sockets implement the `embedded-io` async traits.
|
- TCP sockets implement the `embedded-io` async traits.
|
||||||
|
- Multicast
|
||||||
|
|
||||||
See the [`smoltcp`](https://github.com/smoltcp-rs/smoltcp) README for a detailed list of implemented and
|
See the [`smoltcp`](https://github.com/smoltcp-rs/smoltcp) README for a detailed list of implemented and
|
||||||
unimplemented features of the network protocols.
|
unimplemented features of the network protocols.
|
||||||
|
@ -9,7 +9,7 @@ pub use smoltcp::socket::dns::{DnsQuery, Socket};
|
|||||||
pub(crate) use smoltcp::socket::dns::{GetQueryResultError, StartQueryError};
|
pub(crate) use smoltcp::socket::dns::{GetQueryResultError, StartQueryError};
|
||||||
pub use smoltcp::wire::{DnsQueryType, IpAddress};
|
pub use smoltcp::wire::{DnsQueryType, IpAddress};
|
||||||
|
|
||||||
use crate::{Driver, Stack};
|
use crate::Stack;
|
||||||
|
|
||||||
/// Errors returned by DnsSocket.
|
/// Errors returned by DnsSocket.
|
||||||
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||||
@ -44,21 +44,15 @@ impl From<StartQueryError> for Error {
|
|||||||
/// This exists only for compatibility with crates that use `embedded-nal-async`.
|
/// This exists only for compatibility with crates that use `embedded-nal-async`.
|
||||||
/// Prefer using [`Stack::dns_query`](crate::Stack::dns_query) directly if you're
|
/// Prefer using [`Stack::dns_query`](crate::Stack::dns_query) directly if you're
|
||||||
/// not using `embedded-nal-async`.
|
/// not using `embedded-nal-async`.
|
||||||
pub struct DnsSocket<'a, D>
|
pub struct DnsSocket<'a> {
|
||||||
where
|
stack: Stack<'a>,
|
||||||
D: Driver + 'static,
|
|
||||||
{
|
|
||||||
stack: &'a Stack<D>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, D> DnsSocket<'a, D>
|
impl<'a> DnsSocket<'a> {
|
||||||
where
|
|
||||||
D: Driver + 'static,
|
|
||||||
{
|
|
||||||
/// Create a new DNS socket using the provided stack.
|
/// Create a new DNS socket using the provided stack.
|
||||||
///
|
///
|
||||||
/// NOTE: If using DHCP, make sure it has reconfigured the stack to ensure the DNS servers are updated.
|
/// NOTE: If using DHCP, make sure it has reconfigured the stack to ensure the DNS servers are updated.
|
||||||
pub fn new(stack: &'a Stack<D>) -> Self {
|
pub fn new(stack: Stack<'a>) -> Self {
|
||||||
Self { stack }
|
Self { stack }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,10 +66,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, D> embedded_nal_async::Dns for DnsSocket<'a, D>
|
impl<'a> embedded_nal_async::Dns for DnsSocket<'a> {
|
||||||
where
|
|
||||||
D: Driver + 'static,
|
|
||||||
{
|
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
async fn get_host_by_name(
|
async fn get_host_by_name(
|
||||||
@ -124,3 +115,7 @@ where
|
|||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn _assert_covariant<'a, 'b: 'a>(x: DnsSocket<'b>) -> DnsSocket<'a> {
|
||||||
|
x
|
||||||
|
}
|
||||||
|
@ -74,7 +74,7 @@ where
|
|||||||
{
|
{
|
||||||
fn consume<R, F>(self, f: F) -> R
|
fn consume<R, F>(self, f: F) -> R
|
||||||
where
|
where
|
||||||
F: FnOnce(&mut [u8]) -> R,
|
F: FnOnce(&[u8]) -> R,
|
||||||
{
|
{
|
||||||
self.0.consume(|buf| {
|
self.0.consume(|buf| {
|
||||||
#[cfg(feature = "packet-trace")]
|
#[cfg(feature = "packet-trace")]
|
@ -12,9 +12,9 @@ compile_error!("You must enable at least one of the following features: proto-ip
|
|||||||
// This mod MUST go first, so that the others see its macros.
|
// This mod MUST go first, so that the others see its macros.
|
||||||
pub(crate) mod fmt;
|
pub(crate) mod fmt;
|
||||||
|
|
||||||
mod device;
|
|
||||||
#[cfg(feature = "dns")]
|
#[cfg(feature = "dns")]
|
||||||
pub mod dns;
|
pub mod dns;
|
||||||
|
mod driver_util;
|
||||||
#[cfg(feature = "raw")]
|
#[cfg(feature = "raw")]
|
||||||
pub mod raw;
|
pub mod raw;
|
||||||
#[cfg(feature = "tcp")]
|
#[cfg(feature = "tcp")]
|
||||||
@ -25,6 +25,7 @@ pub mod udp;
|
|||||||
|
|
||||||
use core::cell::RefCell;
|
use core::cell::RefCell;
|
||||||
use core::future::{poll_fn, Future};
|
use core::future::{poll_fn, Future};
|
||||||
|
use core::mem::MaybeUninit;
|
||||||
use core::pin::pin;
|
use core::pin::pin;
|
||||||
use core::task::{Context, Poll};
|
use core::task::{Context, Poll};
|
||||||
|
|
||||||
@ -36,7 +37,7 @@ use embassy_time::{Instant, Timer};
|
|||||||
use heapless::Vec;
|
use heapless::Vec;
|
||||||
#[cfg(feature = "dns")]
|
#[cfg(feature = "dns")]
|
||||||
pub use smoltcp::config::DNS_MAX_SERVER_COUNT;
|
pub use smoltcp::config::DNS_MAX_SERVER_COUNT;
|
||||||
#[cfg(feature = "igmp")]
|
#[cfg(feature = "multicast")]
|
||||||
pub use smoltcp::iface::MulticastError;
|
pub use smoltcp::iface::MulticastError;
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use smoltcp::iface::{Interface, SocketHandle, SocketSet, SocketStorage};
|
use smoltcp::iface::{Interface, SocketHandle, SocketSet, SocketStorage};
|
||||||
@ -57,7 +58,7 @@ pub use smoltcp::wire::{Ipv4Address, Ipv4Cidr};
|
|||||||
#[cfg(feature = "proto-ipv6")]
|
#[cfg(feature = "proto-ipv6")]
|
||||||
pub use smoltcp::wire::{Ipv6Address, Ipv6Cidr};
|
pub use smoltcp::wire::{Ipv6Address, Ipv6Cidr};
|
||||||
|
|
||||||
use crate::device::DriverAdapter;
|
use crate::driver_util::DriverAdapter;
|
||||||
use crate::time::{instant_from_smoltcp, instant_to_smoltcp};
|
use crate::time::{instant_from_smoltcp, instant_to_smoltcp};
|
||||||
|
|
||||||
const LOCAL_PORT_MIN: u16 = 1025;
|
const LOCAL_PORT_MIN: u16 = 1025;
|
||||||
@ -69,33 +70,33 @@ const MAX_HOSTNAME_LEN: usize = 32;
|
|||||||
|
|
||||||
/// Memory resources needed for a network stack.
|
/// Memory resources needed for a network stack.
|
||||||
pub struct StackResources<const SOCK: usize> {
|
pub struct StackResources<const SOCK: usize> {
|
||||||
sockets: [SocketStorage<'static>; SOCK],
|
sockets: MaybeUninit<[SocketStorage<'static>; SOCK]>,
|
||||||
|
inner: MaybeUninit<RefCell<Inner>>,
|
||||||
#[cfg(feature = "dns")]
|
#[cfg(feature = "dns")]
|
||||||
queries: [Option<dns::DnsQuery>; MAX_QUERIES],
|
queries: MaybeUninit<[Option<dns::DnsQuery>; MAX_QUERIES]>,
|
||||||
#[cfg(feature = "dhcpv4-hostname")]
|
#[cfg(feature = "dhcpv4-hostname")]
|
||||||
hostname: core::cell::UnsafeCell<HostnameResources>,
|
hostname: HostnameResources,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "dhcpv4-hostname")]
|
#[cfg(feature = "dhcpv4-hostname")]
|
||||||
struct HostnameResources {
|
struct HostnameResources {
|
||||||
option: smoltcp::wire::DhcpOption<'static>,
|
option: MaybeUninit<smoltcp::wire::DhcpOption<'static>>,
|
||||||
data: [u8; MAX_HOSTNAME_LEN],
|
data: MaybeUninit<[u8; MAX_HOSTNAME_LEN]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<const SOCK: usize> StackResources<SOCK> {
|
impl<const SOCK: usize> StackResources<SOCK> {
|
||||||
/// Create a new set of stack resources.
|
/// Create a new set of stack resources.
|
||||||
pub const fn new() -> Self {
|
pub const fn new() -> Self {
|
||||||
#[cfg(feature = "dns")]
|
|
||||||
const INIT: Option<dns::DnsQuery> = None;
|
|
||||||
Self {
|
Self {
|
||||||
sockets: [SocketStorage::EMPTY; SOCK],
|
sockets: MaybeUninit::uninit(),
|
||||||
|
inner: MaybeUninit::uninit(),
|
||||||
#[cfg(feature = "dns")]
|
#[cfg(feature = "dns")]
|
||||||
queries: [INIT; MAX_QUERIES],
|
queries: MaybeUninit::uninit(),
|
||||||
#[cfg(feature = "dhcpv4-hostname")]
|
#[cfg(feature = "dhcpv4-hostname")]
|
||||||
hostname: core::cell::UnsafeCell::new(HostnameResources {
|
hostname: HostnameResources {
|
||||||
option: smoltcp::wire::DhcpOption { kind: 0, data: &[] },
|
option: MaybeUninit::uninit(),
|
||||||
data: [0; MAX_HOSTNAME_LEN],
|
data: MaybeUninit::uninit(),
|
||||||
}),
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -239,16 +240,29 @@ pub enum ConfigV6 {
|
|||||||
Static(StaticConfigV6),
|
Static(StaticConfigV6),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A network stack.
|
/// Network stack runner.
|
||||||
///
|
///
|
||||||
/// This is the main entry point for the network stack.
|
/// You must call [`Runner::run()`] in a background task for the network stack to work.
|
||||||
pub struct Stack<D: Driver> {
|
pub struct Runner<'d, D: Driver> {
|
||||||
pub(crate) socket: RefCell<SocketStack>,
|
driver: D,
|
||||||
inner: RefCell<Inner<D>>,
|
stack: Stack<'d>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Inner<D: Driver> {
|
/// Network stack handle
|
||||||
device: D,
|
///
|
||||||
|
/// Use this to create sockets. It's `Copy`, so you can pass
|
||||||
|
/// it by value instead of by reference.
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
pub struct Stack<'d> {
|
||||||
|
inner: &'d RefCell<Inner>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) struct Inner {
|
||||||
|
pub(crate) sockets: SocketSet<'static>, // Lifetime type-erased.
|
||||||
|
pub(crate) iface: Interface,
|
||||||
|
pub(crate) waker: WakerRegistration,
|
||||||
|
hardware_address: HardwareAddress,
|
||||||
|
next_local_port: u16,
|
||||||
link_up: bool,
|
link_up: bool,
|
||||||
#[cfg(feature = "proto-ipv4")]
|
#[cfg(feature = "proto-ipv4")]
|
||||||
static_v4: Option<StaticConfigV4>,
|
static_v4: Option<StaticConfigV4>,
|
||||||
@ -262,14 +276,83 @@ struct Inner<D: Driver> {
|
|||||||
#[cfg(feature = "dns")]
|
#[cfg(feature = "dns")]
|
||||||
dns_waker: WakerRegistration,
|
dns_waker: WakerRegistration,
|
||||||
#[cfg(feature = "dhcpv4-hostname")]
|
#[cfg(feature = "dhcpv4-hostname")]
|
||||||
hostname: &'static mut core::cell::UnsafeCell<HostnameResources>,
|
hostname: *mut HostnameResources,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct SocketStack {
|
fn _assert_covariant<'a, 'b: 'a>(x: Stack<'b>) -> Stack<'a> {
|
||||||
pub(crate) sockets: SocketSet<'static>,
|
x
|
||||||
pub(crate) iface: Interface,
|
}
|
||||||
pub(crate) waker: WakerRegistration,
|
|
||||||
next_local_port: u16,
|
/// Create a new network stack.
|
||||||
|
pub fn new<'d, D: Driver, const SOCK: usize>(
|
||||||
|
mut driver: D,
|
||||||
|
config: Config,
|
||||||
|
resources: &'d mut StackResources<SOCK>,
|
||||||
|
random_seed: u64,
|
||||||
|
) -> (Stack<'d>, Runner<'d, D>) {
|
||||||
|
let (hardware_address, medium) = to_smoltcp_hardware_address(driver.hardware_address());
|
||||||
|
let mut iface_cfg = smoltcp::iface::Config::new(hardware_address);
|
||||||
|
iface_cfg.random_seed = random_seed;
|
||||||
|
|
||||||
|
let iface = Interface::new(
|
||||||
|
iface_cfg,
|
||||||
|
&mut DriverAdapter {
|
||||||
|
inner: &mut driver,
|
||||||
|
cx: None,
|
||||||
|
medium,
|
||||||
|
},
|
||||||
|
instant_to_smoltcp(Instant::now()),
|
||||||
|
);
|
||||||
|
|
||||||
|
unsafe fn transmute_slice<T>(x: &mut [T]) -> &'static mut [T] {
|
||||||
|
core::mem::transmute(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
let sockets = resources.sockets.write([SocketStorage::EMPTY; SOCK]);
|
||||||
|
#[allow(unused_mut)]
|
||||||
|
let mut sockets: SocketSet<'static> = SocketSet::new(unsafe { transmute_slice(sockets) });
|
||||||
|
|
||||||
|
let next_local_port = (random_seed % (LOCAL_PORT_MAX - LOCAL_PORT_MIN) as u64) as u16 + LOCAL_PORT_MIN;
|
||||||
|
|
||||||
|
#[cfg(feature = "dns")]
|
||||||
|
let dns_socket = sockets.add(dns::Socket::new(
|
||||||
|
&[],
|
||||||
|
managed::ManagedSlice::Borrowed(unsafe {
|
||||||
|
transmute_slice(resources.queries.write([const { None }; MAX_QUERIES]))
|
||||||
|
}),
|
||||||
|
));
|
||||||
|
|
||||||
|
let mut inner = Inner {
|
||||||
|
sockets,
|
||||||
|
iface,
|
||||||
|
waker: WakerRegistration::new(),
|
||||||
|
next_local_port,
|
||||||
|
hardware_address,
|
||||||
|
link_up: false,
|
||||||
|
#[cfg(feature = "proto-ipv4")]
|
||||||
|
static_v4: None,
|
||||||
|
#[cfg(feature = "proto-ipv6")]
|
||||||
|
static_v6: None,
|
||||||
|
#[cfg(feature = "dhcpv4")]
|
||||||
|
dhcp_socket: None,
|
||||||
|
config_waker: WakerRegistration::new(),
|
||||||
|
#[cfg(feature = "dns")]
|
||||||
|
dns_socket,
|
||||||
|
#[cfg(feature = "dns")]
|
||||||
|
dns_waker: WakerRegistration::new(),
|
||||||
|
#[cfg(feature = "dhcpv4-hostname")]
|
||||||
|
hostname: &mut resources.hostname,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[cfg(feature = "proto-ipv4")]
|
||||||
|
inner.set_config_v4(config.ipv4);
|
||||||
|
#[cfg(feature = "proto-ipv6")]
|
||||||
|
inner.set_config_v6(config.ipv6);
|
||||||
|
inner.apply_static_config();
|
||||||
|
|
||||||
|
let inner = &*resources.inner.write(RefCell::new(inner));
|
||||||
|
let stack = Stack { inner };
|
||||||
|
(stack, Runner { driver, stack })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_smoltcp_hardware_address(addr: driver::HardwareAddress) -> (HardwareAddress, Medium) {
|
fn to_smoltcp_hardware_address(addr: driver::HardwareAddress) -> (HardwareAddress, Medium) {
|
||||||
@ -292,89 +375,23 @@ fn to_smoltcp_hardware_address(addr: driver::HardwareAddress) -> (HardwareAddres
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: Driver> Stack<D> {
|
impl<'d> Stack<'d> {
|
||||||
/// Create a new network stack.
|
fn with<R>(&self, f: impl FnOnce(&Inner) -> R) -> R {
|
||||||
pub fn new<const SOCK: usize>(
|
f(&*self.inner.borrow())
|
||||||
mut device: D,
|
|
||||||
config: Config,
|
|
||||||
resources: &'static mut StackResources<SOCK>,
|
|
||||||
random_seed: u64,
|
|
||||||
) -> Self {
|
|
||||||
let (hardware_addr, medium) = to_smoltcp_hardware_address(device.hardware_address());
|
|
||||||
let mut iface_cfg = smoltcp::iface::Config::new(hardware_addr);
|
|
||||||
iface_cfg.random_seed = random_seed;
|
|
||||||
|
|
||||||
let iface = Interface::new(
|
|
||||||
iface_cfg,
|
|
||||||
&mut DriverAdapter {
|
|
||||||
inner: &mut device,
|
|
||||||
cx: None,
|
|
||||||
medium,
|
|
||||||
},
|
|
||||||
instant_to_smoltcp(Instant::now()),
|
|
||||||
);
|
|
||||||
|
|
||||||
let sockets = SocketSet::new(&mut resources.sockets[..]);
|
|
||||||
|
|
||||||
let next_local_port = (random_seed % (LOCAL_PORT_MAX - LOCAL_PORT_MIN) as u64) as u16 + LOCAL_PORT_MIN;
|
|
||||||
|
|
||||||
#[cfg_attr(feature = "medium-ieee802154", allow(unused_mut))]
|
|
||||||
let mut socket = SocketStack {
|
|
||||||
sockets,
|
|
||||||
iface,
|
|
||||||
waker: WakerRegistration::new(),
|
|
||||||
next_local_port,
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut inner = Inner {
|
|
||||||
device,
|
|
||||||
link_up: false,
|
|
||||||
#[cfg(feature = "proto-ipv4")]
|
|
||||||
static_v4: None,
|
|
||||||
#[cfg(feature = "proto-ipv6")]
|
|
||||||
static_v6: None,
|
|
||||||
#[cfg(feature = "dhcpv4")]
|
|
||||||
dhcp_socket: None,
|
|
||||||
config_waker: WakerRegistration::new(),
|
|
||||||
#[cfg(feature = "dns")]
|
|
||||||
dns_socket: socket.sockets.add(dns::Socket::new(
|
|
||||||
&[],
|
|
||||||
managed::ManagedSlice::Borrowed(&mut resources.queries),
|
|
||||||
)),
|
|
||||||
#[cfg(feature = "dns")]
|
|
||||||
dns_waker: WakerRegistration::new(),
|
|
||||||
#[cfg(feature = "dhcpv4-hostname")]
|
|
||||||
hostname: &mut resources.hostname,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[cfg(feature = "proto-ipv4")]
|
|
||||||
inner.set_config_v4(&mut socket, config.ipv4);
|
|
||||||
#[cfg(feature = "proto-ipv6")]
|
|
||||||
inner.set_config_v6(&mut socket, config.ipv6);
|
|
||||||
inner.apply_static_config(&mut socket);
|
|
||||||
|
|
||||||
Self {
|
|
||||||
socket: RefCell::new(socket),
|
|
||||||
inner: RefCell::new(inner),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with<R>(&self, f: impl FnOnce(&SocketStack, &Inner<D>) -> R) -> R {
|
fn with_mut<R>(&self, f: impl FnOnce(&mut Inner) -> R) -> R {
|
||||||
f(&*self.socket.borrow(), &*self.inner.borrow())
|
f(&mut *self.inner.borrow_mut())
|
||||||
}
|
|
||||||
|
|
||||||
fn with_mut<R>(&self, f: impl FnOnce(&mut SocketStack, &mut Inner<D>) -> R) -> R {
|
|
||||||
f(&mut *self.socket.borrow_mut(), &mut *self.inner.borrow_mut())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the hardware address of the network interface.
|
/// Get the hardware address of the network interface.
|
||||||
pub fn hardware_address(&self) -> HardwareAddress {
|
pub fn hardware_address(&self) -> HardwareAddress {
|
||||||
self.with(|_s, i| to_smoltcp_hardware_address(i.device.hardware_address()).0)
|
self.with(|i| i.hardware_address)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get whether the link is up.
|
/// Get whether the link is up.
|
||||||
pub fn is_link_up(&self) -> bool {
|
pub fn is_link_up(&self) -> bool {
|
||||||
self.with(|_s, i| i.link_up)
|
self.with(|i| i.link_up)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get whether the network stack has a valid IP configuration.
|
/// Get whether the network stack has a valid IP configuration.
|
||||||
@ -420,15 +437,14 @@ impl<D: Driver> Stack<D> {
|
|||||||
/// // provisioning space for 3 sockets here: one for DHCP, one for DNS, and one for your code (e.g. TCP).
|
/// // provisioning space for 3 sockets here: one for DHCP, one for DNS, and one for your code (e.g. TCP).
|
||||||
/// // If you use more sockets you must increase this. If you don't enable DHCP or DNS you can decrease it.
|
/// // If you use more sockets you must increase this. If you don't enable DHCP or DNS you can decrease it.
|
||||||
/// static RESOURCES: StaticCell<embassy_net::StackResources<3>> = StaticCell::new();
|
/// static RESOURCES: StaticCell<embassy_net::StackResources<3>> = StaticCell::new();
|
||||||
/// static STACK: StaticCell<embassy_net::Stack> = StaticCell::new();
|
/// let (stack, runner) = embassy_net::new(
|
||||||
/// let stack = &*STACK.init(embassy_net::Stack::new(
|
/// driver,
|
||||||
/// device,
|
|
||||||
/// config,
|
/// config,
|
||||||
/// RESOURCES.init(embassy_net::StackResources::new()),
|
/// RESOURCES.init(embassy_net::StackResources::new()),
|
||||||
/// seed
|
/// seed
|
||||||
/// ));
|
/// );
|
||||||
/// // Launch network task that runs `stack.run().await`
|
/// // Launch network task that runs `runner.run().await`
|
||||||
/// spawner.spawn(net_task(stack)).unwrap();
|
/// spawner.spawn(net_task(runner)).unwrap();
|
||||||
/// // Wait for DHCP config
|
/// // Wait for DHCP config
|
||||||
/// stack.wait_config_up().await;
|
/// stack.wait_config_up().await;
|
||||||
/// // use the network stack
|
/// // use the network stack
|
||||||
@ -448,7 +464,7 @@ impl<D: Driver> Stack<D> {
|
|||||||
// when a config is applied (static or DHCP).
|
// when a config is applied (static or DHCP).
|
||||||
trace!("Waiting for config up");
|
trace!("Waiting for config up");
|
||||||
|
|
||||||
self.with_mut(|_, i| {
|
self.with_mut(|i| {
|
||||||
i.config_waker.register(cx.waker());
|
i.config_waker.register(cx.waker());
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -464,45 +480,33 @@ impl<D: Driver> Stack<D> {
|
|||||||
/// acquire an IP address, or Some if it has.
|
/// acquire an IP address, or Some if it has.
|
||||||
#[cfg(feature = "proto-ipv4")]
|
#[cfg(feature = "proto-ipv4")]
|
||||||
pub fn config_v4(&self) -> Option<StaticConfigV4> {
|
pub fn config_v4(&self) -> Option<StaticConfigV4> {
|
||||||
self.with(|_, i| i.static_v4.clone())
|
self.with(|i| i.static_v4.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the current IPv6 configuration.
|
/// Get the current IPv6 configuration.
|
||||||
#[cfg(feature = "proto-ipv6")]
|
#[cfg(feature = "proto-ipv6")]
|
||||||
pub fn config_v6(&self) -> Option<StaticConfigV6> {
|
pub fn config_v6(&self) -> Option<StaticConfigV6> {
|
||||||
self.with(|_, i| i.static_v6.clone())
|
self.with(|i| i.static_v6.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the IPv4 configuration.
|
/// Set the IPv4 configuration.
|
||||||
#[cfg(feature = "proto-ipv4")]
|
#[cfg(feature = "proto-ipv4")]
|
||||||
pub fn set_config_v4(&self, config: ConfigV4) {
|
pub fn set_config_v4(&self, config: ConfigV4) {
|
||||||
self.with_mut(|s, i| {
|
self.with_mut(|i| {
|
||||||
i.set_config_v4(s, config);
|
i.set_config_v4(config);
|
||||||
i.apply_static_config(s);
|
i.apply_static_config();
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the IPv6 configuration.
|
/// Set the IPv6 configuration.
|
||||||
#[cfg(feature = "proto-ipv6")]
|
#[cfg(feature = "proto-ipv6")]
|
||||||
pub fn set_config_v6(&self, config: ConfigV6) {
|
pub fn set_config_v6(&self, config: ConfigV6) {
|
||||||
self.with_mut(|s, i| {
|
self.with_mut(|i| {
|
||||||
i.set_config_v6(s, config);
|
i.set_config_v6(config);
|
||||||
i.apply_static_config(s);
|
i.apply_static_config();
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Run the network stack.
|
|
||||||
///
|
|
||||||
/// You must call this in a background task, to process network events.
|
|
||||||
pub async fn run(&self) -> ! {
|
|
||||||
poll_fn(|cx| {
|
|
||||||
self.with_mut(|s, i| i.poll(cx, s));
|
|
||||||
Poll::<()>::Pending
|
|
||||||
})
|
|
||||||
.await;
|
|
||||||
unreachable!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Make a query for a given name and return the corresponding IP addresses.
|
/// Make a query for a given name and return the corresponding IP addresses.
|
||||||
#[cfg(feature = "dns")]
|
#[cfg(feature = "dns")]
|
||||||
pub async fn dns_query(
|
pub async fn dns_query(
|
||||||
@ -528,11 +532,11 @@ impl<D: Driver> Stack<D> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let query = poll_fn(|cx| {
|
let query = poll_fn(|cx| {
|
||||||
self.with_mut(|s, i| {
|
self.with_mut(|i| {
|
||||||
let socket = s.sockets.get_mut::<dns::Socket>(i.dns_socket);
|
let socket = i.sockets.get_mut::<dns::Socket>(i.dns_socket);
|
||||||
match socket.start_query(s.iface.context(), name, qtype) {
|
match socket.start_query(i.iface.context(), name, qtype) {
|
||||||
Ok(handle) => {
|
Ok(handle) => {
|
||||||
s.waker.wake();
|
i.waker.wake();
|
||||||
Poll::Ready(Ok(handle))
|
Poll::Ready(Ok(handle))
|
||||||
}
|
}
|
||||||
Err(dns::StartQueryError::NoFreeSlot) => {
|
Err(dns::StartQueryError::NoFreeSlot) => {
|
||||||
@ -569,17 +573,17 @@ impl<D: Driver> Stack<D> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let drop = OnDrop::new(|| {
|
let drop = OnDrop::new(|| {
|
||||||
self.with_mut(|s, i| {
|
self.with_mut(|i| {
|
||||||
let socket = s.sockets.get_mut::<dns::Socket>(i.dns_socket);
|
let socket = i.sockets.get_mut::<dns::Socket>(i.dns_socket);
|
||||||
socket.cancel_query(query);
|
socket.cancel_query(query);
|
||||||
s.waker.wake();
|
i.waker.wake();
|
||||||
i.dns_waker.wake();
|
i.dns_waker.wake();
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
let res = poll_fn(|cx| {
|
let res = poll_fn(|cx| {
|
||||||
self.with_mut(|s, i| {
|
self.with_mut(|i| {
|
||||||
let socket = s.sockets.get_mut::<dns::Socket>(i.dns_socket);
|
let socket = i.sockets.get_mut::<dns::Socket>(i.dns_socket);
|
||||||
match socket.get_query_result(query) {
|
match socket.get_query_result(query) {
|
||||||
Ok(addrs) => {
|
Ok(addrs) => {
|
||||||
i.dns_waker.wake();
|
i.dns_waker.wake();
|
||||||
@ -604,104 +608,34 @@ impl<D: Driver> Stack<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "igmp")]
|
#[cfg(feature = "multicast")]
|
||||||
impl<D: Driver> Stack<D> {
|
impl<'d> Stack<'d> {
|
||||||
/// Join a multicast group.
|
/// Join a multicast group.
|
||||||
pub async fn join_multicast_group<T>(&self, addr: T) -> Result<bool, MulticastError>
|
pub fn join_multicast_group(&self, addr: impl Into<IpAddress>) -> Result<(), MulticastError> {
|
||||||
where
|
self.with_mut(|i| i.iface.join_multicast_group(addr))
|
||||||
T: Into<IpAddress>,
|
|
||||||
{
|
|
||||||
let addr = addr.into();
|
|
||||||
|
|
||||||
poll_fn(move |cx| self.poll_join_multicast_group(addr, cx)).await
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Join a multicast group.
|
|
||||||
///
|
|
||||||
/// When the send queue is full, this method will return `Poll::Pending`
|
|
||||||
/// and register the current task to be notified when the queue has space available.
|
|
||||||
pub fn poll_join_multicast_group<T>(&self, addr: T, cx: &mut Context<'_>) -> Poll<Result<bool, MulticastError>>
|
|
||||||
where
|
|
||||||
T: Into<IpAddress>,
|
|
||||||
{
|
|
||||||
let addr = addr.into();
|
|
||||||
|
|
||||||
self.with_mut(|s, i| {
|
|
||||||
let (_hardware_addr, medium) = to_smoltcp_hardware_address(i.device.hardware_address());
|
|
||||||
let mut smoldev = DriverAdapter {
|
|
||||||
cx: Some(cx),
|
|
||||||
inner: &mut i.device,
|
|
||||||
medium,
|
|
||||||
};
|
|
||||||
|
|
||||||
match s
|
|
||||||
.iface
|
|
||||||
.join_multicast_group(&mut smoldev, addr, instant_to_smoltcp(Instant::now()))
|
|
||||||
{
|
|
||||||
Ok(announce_sent) => Poll::Ready(Ok(announce_sent)),
|
|
||||||
Err(MulticastError::Exhausted) => Poll::Pending,
|
|
||||||
Err(other) => Poll::Ready(Err(other)),
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Leave a multicast group.
|
/// Leave a multicast group.
|
||||||
pub async fn leave_multicast_group<T>(&self, addr: T) -> Result<bool, MulticastError>
|
pub fn leave_multicast_group(&self, addr: impl Into<IpAddress>) -> Result<(), MulticastError> {
|
||||||
where
|
self.with_mut(|i| i.iface.leave_multicast_group(addr))
|
||||||
T: Into<IpAddress>,
|
|
||||||
{
|
|
||||||
let addr = addr.into();
|
|
||||||
|
|
||||||
poll_fn(move |cx| self.poll_leave_multicast_group(addr, cx)).await
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Leave a multicast group.
|
|
||||||
///
|
|
||||||
/// When the send queue is full, this method will return `Poll::Pending`
|
|
||||||
/// and register the current task to be notified when the queue has space available.
|
|
||||||
pub fn poll_leave_multicast_group<T>(&self, addr: T, cx: &mut Context<'_>) -> Poll<Result<bool, MulticastError>>
|
|
||||||
where
|
|
||||||
T: Into<IpAddress>,
|
|
||||||
{
|
|
||||||
let addr = addr.into();
|
|
||||||
|
|
||||||
self.with_mut(|s, i| {
|
|
||||||
let (_hardware_addr, medium) = to_smoltcp_hardware_address(i.device.hardware_address());
|
|
||||||
let mut smoldev = DriverAdapter {
|
|
||||||
cx: Some(cx),
|
|
||||||
inner: &mut i.device,
|
|
||||||
medium,
|
|
||||||
};
|
|
||||||
|
|
||||||
match s
|
|
||||||
.iface
|
|
||||||
.leave_multicast_group(&mut smoldev, addr, instant_to_smoltcp(Instant::now()))
|
|
||||||
{
|
|
||||||
Ok(leave_sent) => Poll::Ready(Ok(leave_sent)),
|
|
||||||
Err(MulticastError::Exhausted) => Poll::Pending,
|
|
||||||
Err(other) => Poll::Ready(Err(other)),
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get whether the network stack has joined the given multicast group.
|
/// Get whether the network stack has joined the given multicast group.
|
||||||
pub fn has_multicast_group<T: Into<IpAddress>>(&self, addr: T) -> bool {
|
pub fn has_multicast_group(&self, addr: impl Into<IpAddress>) -> bool {
|
||||||
self.socket.borrow().iface.has_multicast_group(addr)
|
self.with(|i| i.iface.has_multicast_group(addr))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SocketStack {
|
impl Inner {
|
||||||
#[allow(clippy::absurd_extreme_comparisons, dead_code)]
|
#[allow(clippy::absurd_extreme_comparisons, dead_code)]
|
||||||
pub fn get_local_port(&mut self) -> u16 {
|
pub fn get_local_port(&mut self) -> u16 {
|
||||||
let res = self.next_local_port;
|
let res = self.next_local_port;
|
||||||
self.next_local_port = if res >= LOCAL_PORT_MAX { LOCAL_PORT_MIN } else { res + 1 };
|
self.next_local_port = if res >= LOCAL_PORT_MAX { LOCAL_PORT_MIN } else { res + 1 };
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl<D: Driver> Inner<D> {
|
|
||||||
#[cfg(feature = "proto-ipv4")]
|
#[cfg(feature = "proto-ipv4")]
|
||||||
pub fn set_config_v4(&mut self, _s: &mut SocketStack, config: ConfigV4) {
|
pub fn set_config_v4(&mut self, config: ConfigV4) {
|
||||||
// Handle static config.
|
// Handle static config.
|
||||||
self.static_v4 = match config.clone() {
|
self.static_v4 = match config.clone() {
|
||||||
ConfigV4::None => None,
|
ConfigV4::None => None,
|
||||||
@ -717,12 +651,12 @@ impl<D: Driver> Inner<D> {
|
|||||||
// Create the socket if it doesn't exist.
|
// Create the socket if it doesn't exist.
|
||||||
if self.dhcp_socket.is_none() {
|
if self.dhcp_socket.is_none() {
|
||||||
let socket = smoltcp::socket::dhcpv4::Socket::new();
|
let socket = smoltcp::socket::dhcpv4::Socket::new();
|
||||||
let handle = _s.sockets.add(socket);
|
let handle = self.sockets.add(socket);
|
||||||
self.dhcp_socket = Some(handle);
|
self.dhcp_socket = Some(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure it
|
// Configure it
|
||||||
let socket = _s.sockets.get_mut::<dhcpv4::Socket>(unwrap!(self.dhcp_socket));
|
let socket = self.sockets.get_mut::<dhcpv4::Socket>(unwrap!(self.dhcp_socket));
|
||||||
socket.set_ignore_naks(c.ignore_naks);
|
socket.set_ignore_naks(c.ignore_naks);
|
||||||
socket.set_max_lease_duration(c.max_lease_duration.map(crate::time::duration_to_smoltcp));
|
socket.set_max_lease_duration(c.max_lease_duration.map(crate::time::duration_to_smoltcp));
|
||||||
socket.set_ports(c.server_port, c.client_port);
|
socket.set_ports(c.server_port, c.client_port);
|
||||||
@ -731,19 +665,20 @@ impl<D: Driver> Inner<D> {
|
|||||||
socket.set_outgoing_options(&[]);
|
socket.set_outgoing_options(&[]);
|
||||||
#[cfg(feature = "dhcpv4-hostname")]
|
#[cfg(feature = "dhcpv4-hostname")]
|
||||||
if let Some(h) = c.hostname {
|
if let Some(h) = c.hostname {
|
||||||
// safety: we just did set_outgoing_options([]) so we know the socket is no longer holding a reference.
|
// safety:
|
||||||
let hostname = unsafe { &mut *self.hostname.get() };
|
// - we just did set_outgoing_options([]) so we know the socket is no longer holding a reference.
|
||||||
|
// - we know this pointer lives for as long as the stack exists, because `new()` borrows
|
||||||
|
// the resources for `'d`. Therefore it's OK to pass a reference to this to smoltcp.
|
||||||
|
let hostname = unsafe { &mut *self.hostname };
|
||||||
|
|
||||||
// create data
|
// create data
|
||||||
// safety: we know the buffer lives forever, new borrows the StackResources for 'static.
|
let data = hostname.data.write([0; MAX_HOSTNAME_LEN]);
|
||||||
// also we won't modify it until next call to this function.
|
data[..h.len()].copy_from_slice(h.as_bytes());
|
||||||
hostname.data[..h.len()].copy_from_slice(h.as_bytes());
|
let data: &[u8] = &data[..h.len()];
|
||||||
let data: &[u8] = &hostname.data[..h.len()];
|
|
||||||
let data: &'static [u8] = unsafe { core::mem::transmute(data) };
|
|
||||||
|
|
||||||
// set the option.
|
// set the option.
|
||||||
hostname.option = smoltcp::wire::DhcpOption { data, kind: 12 };
|
let option = hostname.option.write(smoltcp::wire::DhcpOption { data, kind: 12 });
|
||||||
socket.set_outgoing_options(core::slice::from_ref(&hostname.option));
|
socket.set_outgoing_options(core::slice::from_ref(option));
|
||||||
}
|
}
|
||||||
|
|
||||||
socket.reset();
|
socket.reset();
|
||||||
@ -751,7 +686,7 @@ impl<D: Driver> Inner<D> {
|
|||||||
_ => {
|
_ => {
|
||||||
// Remove DHCP socket if any.
|
// Remove DHCP socket if any.
|
||||||
if let Some(socket) = self.dhcp_socket {
|
if let Some(socket) = self.dhcp_socket {
|
||||||
_s.sockets.remove(socket);
|
self.sockets.remove(socket);
|
||||||
self.dhcp_socket = None;
|
self.dhcp_socket = None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -759,14 +694,14 @@ impl<D: Driver> Inner<D> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "proto-ipv6")]
|
#[cfg(feature = "proto-ipv6")]
|
||||||
pub fn set_config_v6(&mut self, _s: &mut SocketStack, config: ConfigV6) {
|
pub fn set_config_v6(&mut self, config: ConfigV6) {
|
||||||
self.static_v6 = match config {
|
self.static_v6 = match config {
|
||||||
ConfigV6::None => None,
|
ConfigV6::None => None,
|
||||||
ConfigV6::Static(c) => Some(c),
|
ConfigV6::Static(c) => Some(c),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply_static_config(&mut self, s: &mut SocketStack) {
|
fn apply_static_config(&mut self) {
|
||||||
let mut addrs = Vec::new();
|
let mut addrs = Vec::new();
|
||||||
#[cfg(feature = "dns")]
|
#[cfg(feature = "dns")]
|
||||||
let mut dns_servers: Vec<_, 6> = Vec::new();
|
let mut dns_servers: Vec<_, 6> = Vec::new();
|
||||||
@ -810,20 +745,20 @@ impl<D: Driver> Inner<D> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Apply addresses
|
// Apply addresses
|
||||||
s.iface.update_ip_addrs(|a| *a = addrs);
|
self.iface.update_ip_addrs(|a| *a = addrs);
|
||||||
|
|
||||||
// Apply gateways
|
// Apply gateways
|
||||||
#[cfg(feature = "proto-ipv4")]
|
#[cfg(feature = "proto-ipv4")]
|
||||||
if let Some(gateway) = gateway_v4 {
|
if let Some(gateway) = gateway_v4 {
|
||||||
unwrap!(s.iface.routes_mut().add_default_ipv4_route(gateway));
|
unwrap!(self.iface.routes_mut().add_default_ipv4_route(gateway));
|
||||||
} else {
|
} else {
|
||||||
s.iface.routes_mut().remove_default_ipv4_route();
|
self.iface.routes_mut().remove_default_ipv4_route();
|
||||||
}
|
}
|
||||||
#[cfg(feature = "proto-ipv6")]
|
#[cfg(feature = "proto-ipv6")]
|
||||||
if let Some(gateway) = gateway_v6 {
|
if let Some(gateway) = gateway_v6 {
|
||||||
unwrap!(s.iface.routes_mut().add_default_ipv6_route(gateway));
|
unwrap!(self.iface.routes_mut().add_default_ipv6_route(gateway));
|
||||||
} else {
|
} else {
|
||||||
s.iface.routes_mut().remove_default_ipv6_route();
|
self.iface.routes_mut().remove_default_ipv6_route();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply DNS servers
|
// Apply DNS servers
|
||||||
@ -835,7 +770,7 @@ impl<D: Driver> Inner<D> {
|
|||||||
} else {
|
} else {
|
||||||
dns_servers.len()
|
dns_servers.len()
|
||||||
};
|
};
|
||||||
s.sockets
|
self.sockets
|
||||||
.get_mut::<smoltcp::socket::dns::Socket>(self.dns_socket)
|
.get_mut::<smoltcp::socket::dns::Socket>(self.dns_socket)
|
||||||
.update_servers(&dns_servers[..count]);
|
.update_servers(&dns_servers[..count]);
|
||||||
}
|
}
|
||||||
@ -843,10 +778,10 @@ impl<D: Driver> Inner<D> {
|
|||||||
self.config_waker.wake();
|
self.config_waker.wake();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn poll(&mut self, cx: &mut Context<'_>, s: &mut SocketStack) {
|
fn poll<D: Driver>(&mut self, cx: &mut Context<'_>, driver: &mut D) {
|
||||||
s.waker.register(cx.waker());
|
self.waker.register(cx.waker());
|
||||||
|
|
||||||
let (_hardware_addr, medium) = to_smoltcp_hardware_address(self.device.hardware_address());
|
let (_hardware_addr, medium) = to_smoltcp_hardware_address(driver.hardware_address());
|
||||||
|
|
||||||
#[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))]
|
#[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))]
|
||||||
{
|
{
|
||||||
@ -859,21 +794,21 @@ impl<D: Driver> Inner<D> {
|
|||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
if do_set {
|
if do_set {
|
||||||
s.iface.set_hardware_addr(_hardware_addr);
|
self.iface.set_hardware_addr(_hardware_addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let timestamp = instant_to_smoltcp(Instant::now());
|
let timestamp = instant_to_smoltcp(Instant::now());
|
||||||
let mut smoldev = DriverAdapter {
|
let mut smoldev = DriverAdapter {
|
||||||
cx: Some(cx),
|
cx: Some(cx),
|
||||||
inner: &mut self.device,
|
inner: driver,
|
||||||
medium,
|
medium,
|
||||||
};
|
};
|
||||||
s.iface.poll(timestamp, &mut smoldev, &mut s.sockets);
|
self.iface.poll(timestamp, &mut smoldev, &mut self.sockets);
|
||||||
|
|
||||||
// Update link up
|
// Update link up
|
||||||
let old_link_up = self.link_up;
|
let old_link_up = self.link_up;
|
||||||
self.link_up = self.device.link_state(cx) == LinkState::Up;
|
self.link_up = driver.link_state(cx) == LinkState::Up;
|
||||||
|
|
||||||
// Print when changed
|
// Print when changed
|
||||||
if old_link_up != self.link_up {
|
if old_link_up != self.link_up {
|
||||||
@ -885,7 +820,7 @@ impl<D: Driver> Inner<D> {
|
|||||||
|
|
||||||
#[cfg(feature = "dhcpv4")]
|
#[cfg(feature = "dhcpv4")]
|
||||||
if let Some(dhcp_handle) = self.dhcp_socket {
|
if let Some(dhcp_handle) = self.dhcp_socket {
|
||||||
let socket = s.sockets.get_mut::<dhcpv4::Socket>(dhcp_handle);
|
let socket = self.sockets.get_mut::<dhcpv4::Socket>(dhcp_handle);
|
||||||
|
|
||||||
if self.link_up {
|
if self.link_up {
|
||||||
if old_link_up != self.link_up {
|
if old_link_up != self.link_up {
|
||||||
@ -914,10 +849,10 @@ impl<D: Driver> Inner<D> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if apply_config {
|
if apply_config {
|
||||||
self.apply_static_config(s);
|
self.apply_static_config();
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(poll_at) = s.iface.poll_at(timestamp, &mut s.sockets) {
|
if let Some(poll_at) = self.iface.poll_at(timestamp, &mut self.sockets) {
|
||||||
let t = pin!(Timer::at(instant_from_smoltcp(poll_at)));
|
let t = pin!(Timer::at(instant_from_smoltcp(poll_at)));
|
||||||
if t.poll(cx).is_ready() {
|
if t.poll(cx).is_ready() {
|
||||||
cx.waker().wake_by_ref();
|
cx.waker().wake_by_ref();
|
||||||
@ -925,3 +860,17 @@ impl<D: Driver> Inner<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'d, D: Driver> Runner<'d, D> {
|
||||||
|
/// Run the network stack.
|
||||||
|
///
|
||||||
|
/// You must call this in a background task, to process network events.
|
||||||
|
pub async fn run(&mut self) -> ! {
|
||||||
|
poll_fn(|cx| {
|
||||||
|
self.stack.with_mut(|i| i.poll(cx, &mut self.driver));
|
||||||
|
Poll::<()>::Pending
|
||||||
|
})
|
||||||
|
.await;
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
//! Raw sockets.
|
//! Raw sockets.
|
||||||
|
|
||||||
use core::cell::RefCell;
|
|
||||||
use core::future::poll_fn;
|
use core::future::poll_fn;
|
||||||
use core::mem;
|
use core::mem;
|
||||||
use core::task::{Context, Poll};
|
use core::task::{Context, Poll};
|
||||||
@ -11,7 +10,7 @@ use smoltcp::socket::raw;
|
|||||||
pub use smoltcp::socket::raw::PacketMetadata;
|
pub use smoltcp::socket::raw::PacketMetadata;
|
||||||
use smoltcp::wire::{IpProtocol, IpVersion};
|
use smoltcp::wire::{IpProtocol, IpVersion};
|
||||||
|
|
||||||
use crate::{SocketStack, Stack};
|
use crate::Stack;
|
||||||
|
|
||||||
/// Error returned by [`RawSocket::recv`] and [`RawSocket::send`].
|
/// Error returned by [`RawSocket::recv`] and [`RawSocket::send`].
|
||||||
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
|
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
|
||||||
@ -23,14 +22,14 @@ pub enum RecvError {
|
|||||||
|
|
||||||
/// An Raw socket.
|
/// An Raw socket.
|
||||||
pub struct RawSocket<'a> {
|
pub struct RawSocket<'a> {
|
||||||
stack: &'a RefCell<SocketStack>,
|
stack: Stack<'a>,
|
||||||
handle: SocketHandle,
|
handle: SocketHandle,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> RawSocket<'a> {
|
impl<'a> RawSocket<'a> {
|
||||||
/// Create a new Raw socket using the provided stack and buffers.
|
/// Create a new Raw socket using the provided stack and buffers.
|
||||||
pub fn new<D: Driver>(
|
pub fn new<D: Driver>(
|
||||||
stack: &'a Stack<D>,
|
stack: Stack<'a>,
|
||||||
ip_version: IpVersion,
|
ip_version: IpVersion,
|
||||||
ip_protocol: IpProtocol,
|
ip_protocol: IpProtocol,
|
||||||
rx_meta: &'a mut [PacketMetadata],
|
rx_meta: &'a mut [PacketMetadata],
|
||||||
@ -38,31 +37,29 @@ impl<'a> RawSocket<'a> {
|
|||||||
tx_meta: &'a mut [PacketMetadata],
|
tx_meta: &'a mut [PacketMetadata],
|
||||||
tx_buffer: &'a mut [u8],
|
tx_buffer: &'a mut [u8],
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let s = &mut *stack.socket.borrow_mut();
|
let handle = stack.with_mut(|i| {
|
||||||
|
let rx_meta: &'static mut [PacketMetadata] = unsafe { mem::transmute(rx_meta) };
|
||||||
|
let rx_buffer: &'static mut [u8] = unsafe { mem::transmute(rx_buffer) };
|
||||||
|
let tx_meta: &'static mut [PacketMetadata] = unsafe { mem::transmute(tx_meta) };
|
||||||
|
let tx_buffer: &'static mut [u8] = unsafe { mem::transmute(tx_buffer) };
|
||||||
|
i.sockets.add(raw::Socket::new(
|
||||||
|
ip_version,
|
||||||
|
ip_protocol,
|
||||||
|
raw::PacketBuffer::new(rx_meta, rx_buffer),
|
||||||
|
raw::PacketBuffer::new(tx_meta, tx_buffer),
|
||||||
|
))
|
||||||
|
});
|
||||||
|
|
||||||
let rx_meta: &'static mut [PacketMetadata] = unsafe { mem::transmute(rx_meta) };
|
Self { stack, handle }
|
||||||
let rx_buffer: &'static mut [u8] = unsafe { mem::transmute(rx_buffer) };
|
|
||||||
let tx_meta: &'static mut [PacketMetadata] = unsafe { mem::transmute(tx_meta) };
|
|
||||||
let tx_buffer: &'static mut [u8] = unsafe { mem::transmute(tx_buffer) };
|
|
||||||
let handle = s.sockets.add(raw::Socket::new(
|
|
||||||
ip_version,
|
|
||||||
ip_protocol,
|
|
||||||
raw::PacketBuffer::new(rx_meta, rx_buffer),
|
|
||||||
raw::PacketBuffer::new(tx_meta, tx_buffer),
|
|
||||||
));
|
|
||||||
|
|
||||||
Self {
|
|
||||||
stack: &stack.socket,
|
|
||||||
handle,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_mut<R>(&self, f: impl FnOnce(&mut raw::Socket, &mut Interface) -> R) -> R {
|
fn with_mut<R>(&self, f: impl FnOnce(&mut raw::Socket, &mut Interface) -> R) -> R {
|
||||||
let s = &mut *self.stack.borrow_mut();
|
self.stack.with_mut(|i| {
|
||||||
let socket = s.sockets.get_mut::<raw::Socket>(self.handle);
|
let socket = i.sockets.get_mut::<raw::Socket>(self.handle);
|
||||||
let res = f(socket, &mut s.iface);
|
let res = f(socket, &mut i.iface);
|
||||||
s.waker.wake();
|
i.waker.wake();
|
||||||
res
|
res
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Receive a datagram.
|
/// Receive a datagram.
|
||||||
@ -115,6 +112,10 @@ impl<'a> RawSocket<'a> {
|
|||||||
|
|
||||||
impl Drop for RawSocket<'_> {
|
impl Drop for RawSocket<'_> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.stack.borrow_mut().sockets.remove(self.handle);
|
self.stack.with_mut(|i| i.sockets.remove(self.handle));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn _assert_covariant<'a, 'b: 'a>(x: RawSocket<'b>) -> RawSocket<'a> {
|
||||||
|
x
|
||||||
|
}
|
||||||
|
@ -8,12 +8,10 @@
|
|||||||
//! Incoming connections when no socket is listening are rejected. To accept many incoming
|
//! Incoming connections when no socket is listening are rejected. To accept many incoming
|
||||||
//! connections, create many sockets and put them all into listening mode.
|
//! connections, create many sockets and put them all into listening mode.
|
||||||
|
|
||||||
use core::cell::RefCell;
|
|
||||||
use core::future::poll_fn;
|
use core::future::poll_fn;
|
||||||
use core::mem;
|
use core::mem;
|
||||||
use core::task::Poll;
|
use core::task::Poll;
|
||||||
|
|
||||||
use embassy_net_driver::Driver;
|
|
||||||
use embassy_time::Duration;
|
use embassy_time::Duration;
|
||||||
use smoltcp::iface::{Interface, SocketHandle};
|
use smoltcp::iface::{Interface, SocketHandle};
|
||||||
use smoltcp::socket::tcp;
|
use smoltcp::socket::tcp;
|
||||||
@ -21,7 +19,7 @@ pub use smoltcp::socket::tcp::State;
|
|||||||
use smoltcp::wire::{IpEndpoint, IpListenEndpoint};
|
use smoltcp::wire::{IpEndpoint, IpListenEndpoint};
|
||||||
|
|
||||||
use crate::time::duration_to_smoltcp;
|
use crate::time::duration_to_smoltcp;
|
||||||
use crate::{SocketStack, Stack};
|
use crate::Stack;
|
||||||
|
|
||||||
/// Error returned by TcpSocket read/write functions.
|
/// Error returned by TcpSocket read/write functions.
|
||||||
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
|
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
|
||||||
@ -157,20 +155,18 @@ impl<'a> TcpWriter<'a> {
|
|||||||
|
|
||||||
impl<'a> TcpSocket<'a> {
|
impl<'a> TcpSocket<'a> {
|
||||||
/// Create a new TCP socket on the given stack, with the given buffers.
|
/// Create a new TCP socket on the given stack, with the given buffers.
|
||||||
pub fn new<D: Driver>(stack: &'a Stack<D>, rx_buffer: &'a mut [u8], tx_buffer: &'a mut [u8]) -> Self {
|
pub fn new(stack: Stack<'a>, rx_buffer: &'a mut [u8], tx_buffer: &'a mut [u8]) -> Self {
|
||||||
let s = &mut *stack.socket.borrow_mut();
|
let handle = stack.with_mut(|i| {
|
||||||
let rx_buffer: &'static mut [u8] = unsafe { mem::transmute(rx_buffer) };
|
let rx_buffer: &'static mut [u8] = unsafe { mem::transmute(rx_buffer) };
|
||||||
let tx_buffer: &'static mut [u8] = unsafe { mem::transmute(tx_buffer) };
|
let tx_buffer: &'static mut [u8] = unsafe { mem::transmute(tx_buffer) };
|
||||||
let handle = s.sockets.add(tcp::Socket::new(
|
i.sockets.add(tcp::Socket::new(
|
||||||
tcp::SocketBuffer::new(rx_buffer),
|
tcp::SocketBuffer::new(rx_buffer),
|
||||||
tcp::SocketBuffer::new(tx_buffer),
|
tcp::SocketBuffer::new(tx_buffer),
|
||||||
));
|
))
|
||||||
|
});
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
io: TcpIo {
|
io: TcpIo { stack: stack, handle },
|
||||||
stack: &stack.socket,
|
|
||||||
handle,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,7 +224,7 @@ impl<'a> TcpSocket<'a> {
|
|||||||
where
|
where
|
||||||
T: Into<IpEndpoint>,
|
T: Into<IpEndpoint>,
|
||||||
{
|
{
|
||||||
let local_port = self.io.stack.borrow_mut().get_local_port();
|
let local_port = self.io.stack.with_mut(|i| i.get_local_port());
|
||||||
|
|
||||||
match {
|
match {
|
||||||
self.io
|
self.io
|
||||||
@ -401,31 +397,43 @@ impl<'a> TcpSocket<'a> {
|
|||||||
|
|
||||||
impl<'a> Drop for TcpSocket<'a> {
|
impl<'a> Drop for TcpSocket<'a> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.io.stack.borrow_mut().sockets.remove(self.io.handle);
|
self.io.stack.with_mut(|i| i.sockets.remove(self.io.handle));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn _assert_covariant<'a, 'b: 'a>(x: TcpSocket<'b>) -> TcpSocket<'a> {
|
||||||
|
x
|
||||||
|
}
|
||||||
|
fn _assert_covariant_reader<'a, 'b: 'a>(x: TcpReader<'b>) -> TcpReader<'a> {
|
||||||
|
x
|
||||||
|
}
|
||||||
|
fn _assert_covariant_writer<'a, 'b: 'a>(x: TcpWriter<'b>) -> TcpWriter<'a> {
|
||||||
|
x
|
||||||
|
}
|
||||||
|
|
||||||
// =======================
|
// =======================
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
struct TcpIo<'a> {
|
struct TcpIo<'a> {
|
||||||
stack: &'a RefCell<SocketStack>,
|
stack: Stack<'a>,
|
||||||
handle: SocketHandle,
|
handle: SocketHandle,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d> TcpIo<'d> {
|
impl<'d> TcpIo<'d> {
|
||||||
fn with<R>(&self, f: impl FnOnce(&tcp::Socket, &Interface) -> R) -> R {
|
fn with<R>(&self, f: impl FnOnce(&tcp::Socket, &Interface) -> R) -> R {
|
||||||
let s = &*self.stack.borrow();
|
self.stack.with(|i| {
|
||||||
let socket = s.sockets.get::<tcp::Socket>(self.handle);
|
let socket = i.sockets.get::<tcp::Socket>(self.handle);
|
||||||
f(socket, &s.iface)
|
f(socket, &i.iface)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_mut<R>(&mut self, f: impl FnOnce(&mut tcp::Socket, &mut Interface) -> R) -> R {
|
fn with_mut<R>(&mut self, f: impl FnOnce(&mut tcp::Socket, &mut Interface) -> R) -> R {
|
||||||
let s = &mut *self.stack.borrow_mut();
|
self.stack.with_mut(|i| {
|
||||||
let socket = s.sockets.get_mut::<tcp::Socket>(self.handle);
|
let socket = i.sockets.get_mut::<tcp::Socket>(self.handle);
|
||||||
let res = f(socket, &mut s.iface);
|
let res = f(socket, &mut i.iface);
|
||||||
s.waker.wake();
|
i.waker.wake();
|
||||||
res
|
res
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
|
async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
|
||||||
@ -676,15 +684,15 @@ pub mod client {
|
|||||||
/// TCP client connection pool compatible with `embedded-nal-async` traits.
|
/// TCP client connection pool compatible with `embedded-nal-async` traits.
|
||||||
///
|
///
|
||||||
/// The pool is capable of managing up to N concurrent connections with tx and rx buffers according to TX_SZ and RX_SZ.
|
/// The pool is capable of managing up to N concurrent connections with tx and rx buffers according to TX_SZ and RX_SZ.
|
||||||
pub struct TcpClient<'d, D: Driver, const N: usize, const TX_SZ: usize = 1024, const RX_SZ: usize = 1024> {
|
pub struct TcpClient<'d, const N: usize, const TX_SZ: usize = 1024, const RX_SZ: usize = 1024> {
|
||||||
stack: &'d Stack<D>,
|
stack: Stack<'d>,
|
||||||
state: &'d TcpClientState<N, TX_SZ, RX_SZ>,
|
state: &'d TcpClientState<N, TX_SZ, RX_SZ>,
|
||||||
socket_timeout: Option<Duration>,
|
socket_timeout: Option<Duration>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, D: Driver, const N: usize, const TX_SZ: usize, const RX_SZ: usize> TcpClient<'d, D, N, TX_SZ, RX_SZ> {
|
impl<'d, const N: usize, const TX_SZ: usize, const RX_SZ: usize> TcpClient<'d, N, TX_SZ, RX_SZ> {
|
||||||
/// Create a new `TcpClient`.
|
/// Create a new `TcpClient`.
|
||||||
pub fn new(stack: &'d Stack<D>, state: &'d TcpClientState<N, TX_SZ, RX_SZ>) -> Self {
|
pub fn new(stack: Stack<'d>, state: &'d TcpClientState<N, TX_SZ, RX_SZ>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
stack,
|
stack,
|
||||||
state,
|
state,
|
||||||
@ -701,8 +709,8 @@ pub mod client {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, D: Driver, const N: usize, const TX_SZ: usize, const RX_SZ: usize> embedded_nal_async::TcpConnect
|
impl<'d, const N: usize, const TX_SZ: usize, const RX_SZ: usize> embedded_nal_async::TcpConnect
|
||||||
for TcpClient<'d, D, N, TX_SZ, RX_SZ>
|
for TcpClient<'d, N, TX_SZ, RX_SZ>
|
||||||
{
|
{
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type Connection<'m> = TcpConnection<'m, N, TX_SZ, RX_SZ> where Self: 'm;
|
type Connection<'m> = TcpConnection<'m, N, TX_SZ, RX_SZ> where Self: 'm;
|
||||||
@ -722,7 +730,7 @@ pub mod client {
|
|||||||
IpAddr::V6(_) => panic!("ipv6 support not enabled"),
|
IpAddr::V6(_) => panic!("ipv6 support not enabled"),
|
||||||
};
|
};
|
||||||
let remote_endpoint = (addr, remote.port());
|
let remote_endpoint = (addr, remote.port());
|
||||||
let mut socket = TcpConnection::new(&self.stack, self.state)?;
|
let mut socket = TcpConnection::new(self.stack, self.state)?;
|
||||||
socket.socket.set_timeout(self.socket_timeout.clone());
|
socket.socket.set_timeout(self.socket_timeout.clone());
|
||||||
socket
|
socket
|
||||||
.socket
|
.socket
|
||||||
@ -741,7 +749,7 @@ pub mod client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, const N: usize, const TX_SZ: usize, const RX_SZ: usize> TcpConnection<'d, N, TX_SZ, RX_SZ> {
|
impl<'d, const N: usize, const TX_SZ: usize, const RX_SZ: usize> TcpConnection<'d, N, TX_SZ, RX_SZ> {
|
||||||
fn new<D: Driver>(stack: &'d Stack<D>, state: &'d TcpClientState<N, TX_SZ, RX_SZ>) -> Result<Self, Error> {
|
fn new(stack: Stack<'d>, state: &'d TcpClientState<N, TX_SZ, RX_SZ>) -> Result<Self, Error> {
|
||||||
let mut bufs = state.pool.alloc().ok_or(Error::ConnectionReset)?;
|
let mut bufs = state.pool.alloc().ok_or(Error::ConnectionReset)?;
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
socket: unsafe { TcpSocket::new(stack, &mut bufs.as_mut().1, &mut bufs.as_mut().0) },
|
socket: unsafe { TcpSocket::new(stack, &mut bufs.as_mut().1, &mut bufs.as_mut().0) },
|
||||||
|
@ -1,17 +1,15 @@
|
|||||||
//! UDP sockets.
|
//! UDP sockets.
|
||||||
|
|
||||||
use core::cell::RefCell;
|
|
||||||
use core::future::poll_fn;
|
use core::future::poll_fn;
|
||||||
use core::mem;
|
use core::mem;
|
||||||
use core::task::{Context, Poll};
|
use core::task::{Context, Poll};
|
||||||
|
|
||||||
use embassy_net_driver::Driver;
|
|
||||||
use smoltcp::iface::{Interface, SocketHandle};
|
use smoltcp::iface::{Interface, SocketHandle};
|
||||||
use smoltcp::socket::udp;
|
use smoltcp::socket::udp;
|
||||||
pub use smoltcp::socket::udp::{PacketMetadata, UdpMetadata};
|
pub use smoltcp::socket::udp::{PacketMetadata, UdpMetadata};
|
||||||
use smoltcp::wire::IpListenEndpoint;
|
use smoltcp::wire::IpListenEndpoint;
|
||||||
|
|
||||||
use crate::{SocketStack, Stack};
|
use crate::Stack;
|
||||||
|
|
||||||
/// Error returned by [`UdpSocket::bind`].
|
/// Error returned by [`UdpSocket::bind`].
|
||||||
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
|
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
|
||||||
@ -43,34 +41,31 @@ pub enum RecvError {
|
|||||||
|
|
||||||
/// An UDP socket.
|
/// An UDP socket.
|
||||||
pub struct UdpSocket<'a> {
|
pub struct UdpSocket<'a> {
|
||||||
stack: &'a RefCell<SocketStack>,
|
stack: Stack<'a>,
|
||||||
handle: SocketHandle,
|
handle: SocketHandle,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> UdpSocket<'a> {
|
impl<'a> UdpSocket<'a> {
|
||||||
/// Create a new UDP socket using the provided stack and buffers.
|
/// Create a new UDP socket using the provided stack and buffers.
|
||||||
pub fn new<D: Driver>(
|
pub fn new(
|
||||||
stack: &'a Stack<D>,
|
stack: Stack<'a>,
|
||||||
rx_meta: &'a mut [PacketMetadata],
|
rx_meta: &'a mut [PacketMetadata],
|
||||||
rx_buffer: &'a mut [u8],
|
rx_buffer: &'a mut [u8],
|
||||||
tx_meta: &'a mut [PacketMetadata],
|
tx_meta: &'a mut [PacketMetadata],
|
||||||
tx_buffer: &'a mut [u8],
|
tx_buffer: &'a mut [u8],
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let s = &mut *stack.socket.borrow_mut();
|
let handle = stack.with_mut(|i| {
|
||||||
|
let rx_meta: &'static mut [PacketMetadata] = unsafe { mem::transmute(rx_meta) };
|
||||||
|
let rx_buffer: &'static mut [u8] = unsafe { mem::transmute(rx_buffer) };
|
||||||
|
let tx_meta: &'static mut [PacketMetadata] = unsafe { mem::transmute(tx_meta) };
|
||||||
|
let tx_buffer: &'static mut [u8] = unsafe { mem::transmute(tx_buffer) };
|
||||||
|
i.sockets.add(udp::Socket::new(
|
||||||
|
udp::PacketBuffer::new(rx_meta, rx_buffer),
|
||||||
|
udp::PacketBuffer::new(tx_meta, tx_buffer),
|
||||||
|
))
|
||||||
|
});
|
||||||
|
|
||||||
let rx_meta: &'static mut [PacketMetadata] = unsafe { mem::transmute(rx_meta) };
|
Self { stack, handle }
|
||||||
let rx_buffer: &'static mut [u8] = unsafe { mem::transmute(rx_buffer) };
|
|
||||||
let tx_meta: &'static mut [PacketMetadata] = unsafe { mem::transmute(tx_meta) };
|
|
||||||
let tx_buffer: &'static mut [u8] = unsafe { mem::transmute(tx_buffer) };
|
|
||||||
let handle = s.sockets.add(udp::Socket::new(
|
|
||||||
udp::PacketBuffer::new(rx_meta, rx_buffer),
|
|
||||||
udp::PacketBuffer::new(tx_meta, tx_buffer),
|
|
||||||
));
|
|
||||||
|
|
||||||
Self {
|
|
||||||
stack: &stack.socket,
|
|
||||||
handle,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Bind the socket to a local endpoint.
|
/// Bind the socket to a local endpoint.
|
||||||
@ -82,7 +77,7 @@ impl<'a> UdpSocket<'a> {
|
|||||||
|
|
||||||
if endpoint.port == 0 {
|
if endpoint.port == 0 {
|
||||||
// If user didn't specify port allocate a dynamic port.
|
// If user didn't specify port allocate a dynamic port.
|
||||||
endpoint.port = self.stack.borrow_mut().get_local_port();
|
endpoint.port = self.stack.with_mut(|i| i.get_local_port());
|
||||||
}
|
}
|
||||||
|
|
||||||
match self.with_mut(|s, _| s.bind(endpoint)) {
|
match self.with_mut(|s, _| s.bind(endpoint)) {
|
||||||
@ -93,17 +88,19 @@ impl<'a> UdpSocket<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn with<R>(&self, f: impl FnOnce(&udp::Socket, &Interface) -> R) -> R {
|
fn with<R>(&self, f: impl FnOnce(&udp::Socket, &Interface) -> R) -> R {
|
||||||
let s = &*self.stack.borrow();
|
self.stack.with(|i| {
|
||||||
let socket = s.sockets.get::<udp::Socket>(self.handle);
|
let socket = i.sockets.get::<udp::Socket>(self.handle);
|
||||||
f(socket, &s.iface)
|
f(socket, &i.iface)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_mut<R>(&self, f: impl FnOnce(&mut udp::Socket, &mut Interface) -> R) -> R {
|
fn with_mut<R>(&self, f: impl FnOnce(&mut udp::Socket, &mut Interface) -> R) -> R {
|
||||||
let s = &mut *self.stack.borrow_mut();
|
self.stack.with_mut(|i| {
|
||||||
let socket = s.sockets.get_mut::<udp::Socket>(self.handle);
|
let socket = i.sockets.get_mut::<udp::Socket>(self.handle);
|
||||||
let res = f(socket, &mut s.iface);
|
let res = f(socket, &mut i.iface);
|
||||||
s.waker.wake();
|
i.waker.wake();
|
||||||
res
|
res
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Receive a datagram.
|
/// Receive a datagram.
|
||||||
@ -298,6 +295,10 @@ impl<'a> UdpSocket<'a> {
|
|||||||
|
|
||||||
impl Drop for UdpSocket<'_> {
|
impl Drop for UdpSocket<'_> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.stack.borrow_mut().sockets.remove(self.handle);
|
self.stack.with_mut(|i| i.sockets.remove(self.handle));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn _assert_covariant<'a, 'b: 'a>(x: UdpSocket<'b>) -> UdpSocket<'a> {
|
||||||
|
x
|
||||||
|
}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
use defmt::*;
|
use defmt::*;
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_net::tcp::TcpSocket;
|
use embassy_net::tcp::TcpSocket;
|
||||||
use embassy_net::{Stack, StackResources};
|
use embassy_net::StackResources;
|
||||||
use embassy_net_enc28j60::Enc28j60;
|
use embassy_net_enc28j60::Enc28j60;
|
||||||
use embassy_nrf::gpio::{Level, Output, OutputDrive};
|
use embassy_nrf::gpio::{Level, Output, OutputDrive};
|
||||||
use embassy_nrf::rng::Rng;
|
use embassy_nrf::rng::Rng;
|
||||||
@ -23,11 +23,12 @@ bind_interrupts!(struct Irqs {
|
|||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn net_task(
|
async fn net_task(
|
||||||
stack: &'static Stack<
|
mut runner: embassy_net::Runner<
|
||||||
|
'static,
|
||||||
Enc28j60<ExclusiveDevice<Spim<'static, peripherals::SPI3>, Output<'static>, Delay>, Output<'static>>,
|
Enc28j60<ExclusiveDevice<Spim<'static, peripherals::SPI3>, Output<'static>, Delay>, Output<'static>>,
|
||||||
>,
|
>,
|
||||||
) -> ! {
|
) -> ! {
|
||||||
stack.run().await
|
runner.run().await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
@ -67,12 +68,9 @@ async fn main(spawner: Spawner) {
|
|||||||
|
|
||||||
// Init network stack
|
// Init network stack
|
||||||
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
||||||
static STACK: StaticCell<
|
let (stack, runner) = embassy_net::new(device, config, RESOURCES.init(StackResources::new()), seed);
|
||||||
Stack<Enc28j60<ExclusiveDevice<Spim<'static, peripherals::SPI3>, Output<'static>, Delay>, Output<'static>>>,
|
|
||||||
> = StaticCell::new();
|
|
||||||
let stack = STACK.init(Stack::new(device, config, RESOURCES.init(StackResources::new()), seed));
|
|
||||||
|
|
||||||
unwrap!(spawner.spawn(net_task(stack)));
|
unwrap!(spawner.spawn(net_task(runner)));
|
||||||
|
|
||||||
// And now we can use it!
|
// And now we can use it!
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ use core::mem;
|
|||||||
use defmt::*;
|
use defmt::*;
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_net::tcp::TcpSocket;
|
use embassy_net::tcp::TcpSocket;
|
||||||
use embassy_net::{Stack, StackResources};
|
use embassy_net::StackResources;
|
||||||
use embassy_nrf::rng::Rng;
|
use embassy_nrf::rng::Rng;
|
||||||
use embassy_nrf::usb::vbus_detect::HardwareVbusDetect;
|
use embassy_nrf::usb::vbus_detect::HardwareVbusDetect;
|
||||||
use embassy_nrf::usb::Driver;
|
use embassy_nrf::usb::Driver;
|
||||||
@ -39,8 +39,8 @@ async fn usb_ncm_task(class: Runner<'static, MyDriver, MTU>) -> ! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn net_task(stack: &'static Stack<Device<'static, MTU>>) -> ! {
|
async fn net_task(mut runner: embassy_net::Runner<'static, Device<'static, MTU>>) -> ! {
|
||||||
stack.run().await
|
runner.run().await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
@ -116,10 +116,9 @@ async fn main(spawner: Spawner) {
|
|||||||
|
|
||||||
// Init network stack
|
// Init network stack
|
||||||
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
||||||
static STACK: StaticCell<Stack<Device<'static, MTU>>> = StaticCell::new();
|
let (stack, runner) = embassy_net::new(device, config, RESOURCES.init(StackResources::new()), seed);
|
||||||
let stack = &*STACK.init(Stack::new(device, config, RESOURCES.init(StackResources::new()), seed));
|
|
||||||
|
|
||||||
unwrap!(spawner.spawn(net_task(stack)));
|
unwrap!(spawner.spawn(net_task(runner)));
|
||||||
|
|
||||||
// And now we can use it!
|
// And now we can use it!
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
use defmt::{info, unwrap, warn};
|
use defmt::{info, unwrap, warn};
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_net::tcp::TcpSocket;
|
use embassy_net::tcp::TcpSocket;
|
||||||
use embassy_net::{Stack, StackResources};
|
use embassy_net::StackResources;
|
||||||
use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull};
|
use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull};
|
||||||
use embassy_nrf::rng::Rng;
|
use embassy_nrf::rng::Rng;
|
||||||
use embassy_nrf::spim::{self, Spim};
|
use embassy_nrf::spim::{self, Spim};
|
||||||
@ -36,8 +36,8 @@ async fn wifi_task(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn net_task(stack: &'static Stack<hosted::NetDriver<'static>>) -> ! {
|
async fn net_task(mut runner: embassy_net::Runner<'static, hosted::NetDriver<'static>>) -> ! {
|
||||||
stack.run().await
|
runner.run().await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
@ -90,10 +90,9 @@ async fn main(spawner: Spawner) {
|
|||||||
|
|
||||||
// Init network stack
|
// Init network stack
|
||||||
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
||||||
static STACK: StaticCell<Stack<hosted::NetDriver<'static>>> = StaticCell::new();
|
let (stack, runner) = embassy_net::new(device, config, RESOURCES.init(StackResources::new()), seed);
|
||||||
let stack = &*STACK.init(Stack::new(device, config, RESOURCES.init(StackResources::new()), seed));
|
|
||||||
|
|
||||||
unwrap!(spawner.spawn(net_task(stack)));
|
unwrap!(spawner.spawn(net_task(runner)));
|
||||||
|
|
||||||
// And now we can use it!
|
// And now we can use it!
|
||||||
|
|
||||||
|
@ -46,15 +46,15 @@ async fn modem_task(runner: Runner<'static>) -> ! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn net_task(stack: &'static Stack<embassy_net_nrf91::NetDriver<'static>>) -> ! {
|
async fn net_task(mut runner: embassy_net::Runner<'static, embassy_net_nrf91::NetDriver<'static>>) -> ! {
|
||||||
stack.run().await
|
runner.run().await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn control_task(
|
async fn control_task(
|
||||||
control: &'static context::Control<'static>,
|
control: &'static context::Control<'static>,
|
||||||
config: context::Config<'static>,
|
config: context::Config<'static>,
|
||||||
stack: &'static Stack<embassy_net_nrf91::NetDriver<'static>>,
|
stack: Stack<'static>,
|
||||||
) {
|
) {
|
||||||
unwrap!(control.configure(&config).await);
|
unwrap!(control.configure(&config).await);
|
||||||
unwrap!(
|
unwrap!(
|
||||||
@ -150,15 +150,9 @@ async fn main(spawner: Spawner) {
|
|||||||
|
|
||||||
// Init network stack
|
// Init network stack
|
||||||
static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new();
|
static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new();
|
||||||
static STACK: StaticCell<Stack<embassy_net_nrf91::NetDriver<'static>>> = StaticCell::new();
|
let (stack, runner) = embassy_net::new(device, config, RESOURCES.init(StackResources::<2>::new()), seed);
|
||||||
let stack = &*STACK.init(Stack::new(
|
|
||||||
device,
|
|
||||||
config,
|
|
||||||
RESOURCES.init(StackResources::<2>::new()),
|
|
||||||
seed,
|
|
||||||
));
|
|
||||||
|
|
||||||
unwrap!(spawner.spawn(net_task(stack)));
|
unwrap!(spawner.spawn(net_task(runner)));
|
||||||
|
|
||||||
static CONTROL: StaticCell<context::Control<'static>> = StaticCell::new();
|
static CONTROL: StaticCell<context::Control<'static>> = StaticCell::new();
|
||||||
let control = CONTROL.init(context::Control::new(control, 0).await);
|
let control = CONTROL.init(context::Control::new(control, 0).await);
|
||||||
|
@ -36,8 +36,8 @@ async fn ethernet_task(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn net_task(stack: &'static Stack<Device<'static>>) -> ! {
|
async fn net_task(mut runner: embassy_net::Runner<'static, Device<'static>>) -> ! {
|
||||||
stack.run().await
|
runner.run().await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
@ -71,17 +71,16 @@ async fn main(spawner: Spawner) {
|
|||||||
let seed = rng.next_u64();
|
let seed = rng.next_u64();
|
||||||
|
|
||||||
// Init network stack
|
// Init network stack
|
||||||
static STACK: StaticCell<Stack<Device<'static>>> = StaticCell::new();
|
|
||||||
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
||||||
let stack = &*STACK.init(Stack::new(
|
let (stack, runner) = embassy_net::new(
|
||||||
device,
|
device,
|
||||||
embassy_net::Config::dhcpv4(Default::default()),
|
embassy_net::Config::dhcpv4(Default::default()),
|
||||||
RESOURCES.init(StackResources::new()),
|
RESOURCES.init(StackResources::new()),
|
||||||
seed,
|
seed,
|
||||||
));
|
);
|
||||||
|
|
||||||
// Launch network task
|
// Launch network task
|
||||||
unwrap!(spawner.spawn(net_task(&stack)));
|
unwrap!(spawner.spawn(net_task(runner)));
|
||||||
|
|
||||||
info!("Waiting for DHCP...");
|
info!("Waiting for DHCP...");
|
||||||
let cfg = wait_for_config(stack).await;
|
let cfg = wait_for_config(stack).await;
|
||||||
@ -89,12 +88,12 @@ async fn main(spawner: Spawner) {
|
|||||||
info!("IP address: {:?}", local_addr);
|
info!("IP address: {:?}", local_addr);
|
||||||
|
|
||||||
// Create two sockets listening to the same port, to handle simultaneous connections
|
// Create two sockets listening to the same port, to handle simultaneous connections
|
||||||
unwrap!(spawner.spawn(listen_task(&stack, 0, 1234)));
|
unwrap!(spawner.spawn(listen_task(stack, 0, 1234)));
|
||||||
unwrap!(spawner.spawn(listen_task(&stack, 1, 1234)));
|
unwrap!(spawner.spawn(listen_task(stack, 1, 1234)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::task(pool_size = 2)]
|
#[embassy_executor::task(pool_size = 2)]
|
||||||
async fn listen_task(stack: &'static Stack<Device<'static>>, id: u8, port: u16) {
|
async fn listen_task(stack: Stack<'static>, id: u8, port: u16) {
|
||||||
let mut rx_buffer = [0; 4096];
|
let mut rx_buffer = [0; 4096];
|
||||||
let mut tx_buffer = [0; 4096];
|
let mut tx_buffer = [0; 4096];
|
||||||
let mut buf = [0; 4096];
|
let mut buf = [0; 4096];
|
||||||
@ -131,7 +130,7 @@ async fn listen_task(stack: &'static Stack<Device<'static>>, id: u8, port: u16)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn wait_for_config(stack: &'static Stack<Device<'static>>) -> embassy_net::StaticConfigV4 {
|
async fn wait_for_config(stack: Stack<'static>) -> embassy_net::StaticConfigV4 {
|
||||||
loop {
|
loop {
|
||||||
if let Some(config) = stack.config_v4() {
|
if let Some(config) = stack.config_v4() {
|
||||||
return config.clone();
|
return config.clone();
|
||||||
|
@ -38,8 +38,8 @@ async fn ethernet_task(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn net_task(stack: &'static Stack<Device<'static>>) -> ! {
|
async fn net_task(mut runner: embassy_net::Runner<'static, Device<'static>>) -> ! {
|
||||||
stack.run().await
|
runner.run().await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
@ -74,17 +74,16 @@ async fn main(spawner: Spawner) {
|
|||||||
let seed = rng.next_u64();
|
let seed = rng.next_u64();
|
||||||
|
|
||||||
// Init network stack
|
// Init network stack
|
||||||
static STACK: StaticCell<Stack<Device<'static>>> = StaticCell::new();
|
|
||||||
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
||||||
let stack = &*STACK.init(Stack::new(
|
let (stack, runner) = embassy_net::new(
|
||||||
device,
|
device,
|
||||||
embassy_net::Config::dhcpv4(Default::default()),
|
embassy_net::Config::dhcpv4(Default::default()),
|
||||||
RESOURCES.init(StackResources::new()),
|
RESOURCES.init(StackResources::new()),
|
||||||
seed,
|
seed,
|
||||||
));
|
);
|
||||||
|
|
||||||
// Launch network task
|
// Launch network task
|
||||||
unwrap!(spawner.spawn(net_task(&stack)));
|
unwrap!(spawner.spawn(net_task(runner)));
|
||||||
|
|
||||||
info!("Waiting for DHCP...");
|
info!("Waiting for DHCP...");
|
||||||
let cfg = wait_for_config(stack).await;
|
let cfg = wait_for_config(stack).await;
|
||||||
@ -119,7 +118,7 @@ async fn main(spawner: Spawner) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn wait_for_config(stack: &'static Stack<Device<'static>>) -> embassy_net::StaticConfigV4 {
|
async fn wait_for_config(stack: Stack<'static>) -> embassy_net::StaticConfigV4 {
|
||||||
loop {
|
loop {
|
||||||
if let Some(config) = stack.config_v4() {
|
if let Some(config) = stack.config_v4() {
|
||||||
return config.clone();
|
return config.clone();
|
||||||
|
@ -37,8 +37,8 @@ async fn ethernet_task(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn net_task(stack: &'static Stack<Device<'static>>) -> ! {
|
async fn net_task(mut runner: embassy_net::Runner<'static, Device<'static>>) -> ! {
|
||||||
stack.run().await
|
runner.run().await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
@ -73,17 +73,16 @@ async fn main(spawner: Spawner) {
|
|||||||
let seed = rng.next_u64();
|
let seed = rng.next_u64();
|
||||||
|
|
||||||
// Init network stack
|
// Init network stack
|
||||||
static STACK: StaticCell<Stack<Device<'static>>> = StaticCell::new();
|
|
||||||
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
||||||
let stack = &*STACK.init(Stack::new(
|
let (stack, runner) = embassy_net::new(
|
||||||
device,
|
device,
|
||||||
embassy_net::Config::dhcpv4(Default::default()),
|
embassy_net::Config::dhcpv4(Default::default()),
|
||||||
RESOURCES.init(StackResources::new()),
|
RESOURCES.init(StackResources::new()),
|
||||||
seed,
|
seed,
|
||||||
));
|
);
|
||||||
|
|
||||||
// Launch network task
|
// Launch network task
|
||||||
unwrap!(spawner.spawn(net_task(&stack)));
|
unwrap!(spawner.spawn(net_task(runner)));
|
||||||
|
|
||||||
info!("Waiting for DHCP...");
|
info!("Waiting for DHCP...");
|
||||||
let cfg = wait_for_config(stack).await;
|
let cfg = wait_for_config(stack).await;
|
||||||
@ -128,7 +127,7 @@ async fn main(spawner: Spawner) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn wait_for_config(stack: &'static Stack<Device<'static>>) -> embassy_net::StaticConfigV4 {
|
async fn wait_for_config(stack: Stack<'static>) -> embassy_net::StaticConfigV4 {
|
||||||
loop {
|
loop {
|
||||||
if let Some(config) = stack.config_v4() {
|
if let Some(config) = stack.config_v4() {
|
||||||
return config.clone();
|
return config.clone();
|
||||||
|
@ -36,8 +36,8 @@ async fn ethernet_task(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn net_task(stack: &'static Stack<Device<'static>>) -> ! {
|
async fn net_task(mut runner: embassy_net::Runner<'static, Device<'static>>) -> ! {
|
||||||
stack.run().await
|
runner.run().await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
@ -71,17 +71,16 @@ async fn main(spawner: Spawner) {
|
|||||||
let seed = rng.next_u64();
|
let seed = rng.next_u64();
|
||||||
|
|
||||||
// Init network stack
|
// Init network stack
|
||||||
static STACK: StaticCell<Stack<Device<'static>>> = StaticCell::new();
|
|
||||||
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
||||||
let stack = &*STACK.init(Stack::new(
|
let (stack, runner) = embassy_net::new(
|
||||||
device,
|
device,
|
||||||
embassy_net::Config::dhcpv4(Default::default()),
|
embassy_net::Config::dhcpv4(Default::default()),
|
||||||
RESOURCES.init(StackResources::new()),
|
RESOURCES.init(StackResources::new()),
|
||||||
seed,
|
seed,
|
||||||
));
|
);
|
||||||
|
|
||||||
// Launch network task
|
// Launch network task
|
||||||
unwrap!(spawner.spawn(net_task(&stack)));
|
unwrap!(spawner.spawn(net_task(runner)));
|
||||||
|
|
||||||
info!("Waiting for DHCP...");
|
info!("Waiting for DHCP...");
|
||||||
let cfg = wait_for_config(stack).await;
|
let cfg = wait_for_config(stack).await;
|
||||||
@ -108,7 +107,7 @@ async fn main(spawner: Spawner) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn wait_for_config(stack: &'static Stack<Device<'static>>) -> embassy_net::StaticConfigV4 {
|
async fn wait_for_config(stack: Stack<'static>) -> embassy_net::StaticConfigV4 {
|
||||||
loop {
|
loop {
|
||||||
if let Some(config) = stack.config_v4() {
|
if let Some(config) = stack.config_v4() {
|
||||||
return config.clone();
|
return config.clone();
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
use defmt::*;
|
use defmt::*;
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_net::tcp::TcpSocket;
|
use embassy_net::tcp::TcpSocket;
|
||||||
use embassy_net::{Stack, StackResources};
|
use embassy_net::StackResources;
|
||||||
use embassy_rp::clocks::RoscRng;
|
use embassy_rp::clocks::RoscRng;
|
||||||
use embassy_rp::peripherals::USB;
|
use embassy_rp::peripherals::USB;
|
||||||
use embassy_rp::usb::{Driver, InterruptHandler};
|
use embassy_rp::usb::{Driver, InterruptHandler};
|
||||||
@ -40,8 +40,8 @@ async fn usb_ncm_task(class: Runner<'static, MyDriver, MTU>) -> ! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn net_task(stack: &'static Stack<Device<'static, MTU>>) -> ! {
|
async fn net_task(mut runner: embassy_net::Runner<'static, Device<'static, MTU>>) -> ! {
|
||||||
stack.run().await
|
runner.run().await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
@ -108,11 +108,10 @@ async fn main(spawner: Spawner) {
|
|||||||
let seed = rng.next_u64();
|
let seed = rng.next_u64();
|
||||||
|
|
||||||
// Init network stack
|
// Init network stack
|
||||||
static STACK: StaticCell<Stack<Device<'static, MTU>>> = StaticCell::new();
|
|
||||||
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
||||||
let stack = &*STACK.init(Stack::new(device, config, RESOURCES.init(StackResources::new()), seed));
|
let (stack, runner) = embassy_net::new(device, config, RESOURCES.init(StackResources::new()), seed);
|
||||||
|
|
||||||
unwrap!(spawner.spawn(net_task(stack)));
|
unwrap!(spawner.spawn(net_task(runner)));
|
||||||
|
|
||||||
// And now we can use it!
|
// And now we can use it!
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ use cyw43_pio::PioSpi;
|
|||||||
use defmt::*;
|
use defmt::*;
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_net::tcp::TcpSocket;
|
use embassy_net::tcp::TcpSocket;
|
||||||
use embassy_net::{Config, Stack, StackResources};
|
use embassy_net::{Config, StackResources};
|
||||||
use embassy_rp::bind_interrupts;
|
use embassy_rp::bind_interrupts;
|
||||||
use embassy_rp::clocks::RoscRng;
|
use embassy_rp::clocks::RoscRng;
|
||||||
use embassy_rp::gpio::{Level, Output};
|
use embassy_rp::gpio::{Level, Output};
|
||||||
@ -33,8 +33,8 @@ async fn cyw43_task(runner: cyw43::Runner<'static, Output<'static>, PioSpi<'stat
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn net_task(stack: &'static Stack<cyw43::NetDriver<'static>>) -> ! {
|
async fn net_task(mut runner: embassy_net::Runner<'static, cyw43::NetDriver<'static>>) -> ! {
|
||||||
stack.run().await
|
runner.run().await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
@ -80,16 +80,10 @@ async fn main(spawner: Spawner) {
|
|||||||
let seed = rng.next_u64();
|
let seed = rng.next_u64();
|
||||||
|
|
||||||
// Init network stack
|
// Init network stack
|
||||||
static STACK: StaticCell<Stack<cyw43::NetDriver<'static>>> = StaticCell::new();
|
|
||||||
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
||||||
let stack = &*STACK.init(Stack::new(
|
let (stack, runner) = embassy_net::new(net_device, config, RESOURCES.init(StackResources::new()), seed);
|
||||||
net_device,
|
|
||||||
config,
|
|
||||||
RESOURCES.init(StackResources::new()),
|
|
||||||
seed,
|
|
||||||
));
|
|
||||||
|
|
||||||
unwrap!(spawner.spawn(net_task(stack)));
|
unwrap!(spawner.spawn(net_task(runner)));
|
||||||
|
|
||||||
//control.start_ap_open("cyw43", 5).await;
|
//control.start_ap_open("cyw43", 5).await;
|
||||||
control.start_ap_wpa2("cyw43", "password", 5).await;
|
control.start_ap_wpa2("cyw43", "password", 5).await;
|
||||||
|
@ -10,7 +10,6 @@ use core::str;
|
|||||||
use cyw43_pio::PioSpi;
|
use cyw43_pio::PioSpi;
|
||||||
use defmt::*;
|
use defmt::*;
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_net::Stack;
|
|
||||||
use embassy_rp::bind_interrupts;
|
use embassy_rp::bind_interrupts;
|
||||||
use embassy_rp::gpio::{Level, Output};
|
use embassy_rp::gpio::{Level, Output};
|
||||||
use embassy_rp::peripherals::{DMA_CH0, PIO0};
|
use embassy_rp::peripherals::{DMA_CH0, PIO0};
|
||||||
@ -28,8 +27,8 @@ async fn cyw43_task(runner: cyw43::Runner<'static, Output<'static>, PioSpi<'stat
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn net_task(stack: &'static Stack<cyw43::NetDriver<'static>>) -> ! {
|
async fn net_task(mut runner: embassy_net::Runner<'static, cyw43::NetDriver<'static>>) -> ! {
|
||||||
stack.run().await
|
runner.run().await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
|
@ -12,7 +12,7 @@ use cyw43_pio::PioSpi;
|
|||||||
use defmt::*;
|
use defmt::*;
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_net::tcp::TcpSocket;
|
use embassy_net::tcp::TcpSocket;
|
||||||
use embassy_net::{Config, Stack, StackResources};
|
use embassy_net::{Config, StackResources};
|
||||||
use embassy_rp::bind_interrupts;
|
use embassy_rp::bind_interrupts;
|
||||||
use embassy_rp::clocks::RoscRng;
|
use embassy_rp::clocks::RoscRng;
|
||||||
use embassy_rp::gpio::{Level, Output};
|
use embassy_rp::gpio::{Level, Output};
|
||||||
@ -37,8 +37,8 @@ async fn cyw43_task(runner: cyw43::Runner<'static, Output<'static>, PioSpi<'stat
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn net_task(stack: &'static Stack<cyw43::NetDriver<'static>>) -> ! {
|
async fn net_task(mut runner: embassy_net::Runner<'static, cyw43::NetDriver<'static>>) -> ! {
|
||||||
stack.run().await
|
runner.run().await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
@ -84,16 +84,10 @@ async fn main(spawner: Spawner) {
|
|||||||
let seed = rng.next_u64();
|
let seed = rng.next_u64();
|
||||||
|
|
||||||
// Init network stack
|
// Init network stack
|
||||||
static STACK: StaticCell<Stack<cyw43::NetDriver<'static>>> = StaticCell::new();
|
|
||||||
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
||||||
let stack = &*STACK.init(Stack::new(
|
let (stack, runner) = embassy_net::new(net_device, config, RESOURCES.init(StackResources::new()), seed);
|
||||||
net_device,
|
|
||||||
config,
|
|
||||||
RESOURCES.init(StackResources::new()),
|
|
||||||
seed,
|
|
||||||
));
|
|
||||||
|
|
||||||
unwrap!(spawner.spawn(net_task(stack)));
|
unwrap!(spawner.spawn(net_task(runner)));
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
match control
|
match control
|
||||||
|
@ -13,7 +13,7 @@ use defmt::*;
|
|||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_net::dns::DnsSocket;
|
use embassy_net::dns::DnsSocket;
|
||||||
use embassy_net::tcp::client::{TcpClient, TcpClientState};
|
use embassy_net::tcp::client::{TcpClient, TcpClientState};
|
||||||
use embassy_net::{Config, Stack, StackResources};
|
use embassy_net::{Config, StackResources};
|
||||||
use embassy_rp::bind_interrupts;
|
use embassy_rp::bind_interrupts;
|
||||||
use embassy_rp::clocks::RoscRng;
|
use embassy_rp::clocks::RoscRng;
|
||||||
use embassy_rp::gpio::{Level, Output};
|
use embassy_rp::gpio::{Level, Output};
|
||||||
@ -40,8 +40,8 @@ async fn cyw43_task(runner: cyw43::Runner<'static, Output<'static>, PioSpi<'stat
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn net_task(stack: &'static Stack<cyw43::NetDriver<'static>>) -> ! {
|
async fn net_task(mut runner: embassy_net::Runner<'static, cyw43::NetDriver<'static>>) -> ! {
|
||||||
stack.run().await
|
runner.run().await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
@ -87,16 +87,10 @@ async fn main(spawner: Spawner) {
|
|||||||
let seed = rng.next_u64();
|
let seed = rng.next_u64();
|
||||||
|
|
||||||
// Init network stack
|
// Init network stack
|
||||||
static STACK: StaticCell<Stack<cyw43::NetDriver<'static>>> = StaticCell::new();
|
|
||||||
static RESOURCES: StaticCell<StackResources<5>> = StaticCell::new();
|
static RESOURCES: StaticCell<StackResources<5>> = StaticCell::new();
|
||||||
let stack = &*STACK.init(Stack::new(
|
let (stack, runner) = embassy_net::new(net_device, config, RESOURCES.init(StackResources::new()), seed);
|
||||||
net_device,
|
|
||||||
config,
|
|
||||||
RESOURCES.init(StackResources::new()),
|
|
||||||
seed,
|
|
||||||
));
|
|
||||||
|
|
||||||
unwrap!(spawner.spawn(net_task(stack)));
|
unwrap!(spawner.spawn(net_task(runner)));
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
match control
|
match control
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use embassy_executor::{Executor, Spawner};
|
use embassy_executor::{Executor, Spawner};
|
||||||
use embassy_net::tcp::TcpSocket;
|
use embassy_net::tcp::TcpSocket;
|
||||||
use embassy_net::{Config, Ipv4Address, Ipv4Cidr, Stack, StackResources};
|
use embassy_net::{Config, Ipv4Address, Ipv4Cidr, StackResources};
|
||||||
use embassy_net_tuntap::TunTapDevice;
|
use embassy_net_tuntap::TunTapDevice;
|
||||||
use embassy_time::Duration;
|
use embassy_time::Duration;
|
||||||
use embedded_io_async::Write;
|
use embedded_io_async::Write;
|
||||||
@ -22,8 +22,8 @@ struct Opts {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn net_task(stack: &'static Stack<TunTapDevice>) -> ! {
|
async fn net_task(mut runner: embassy_net::Runner<'static, TunTapDevice>) -> ! {
|
||||||
stack.run().await
|
runner.run().await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
@ -50,12 +50,11 @@ async fn main_task(spawner: Spawner) {
|
|||||||
let seed = u64::from_le_bytes(seed);
|
let seed = u64::from_le_bytes(seed);
|
||||||
|
|
||||||
// Init network stack
|
// Init network stack
|
||||||
static STACK: StaticCell<Stack<TunTapDevice>> = StaticCell::new();
|
|
||||||
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
||||||
let stack = &*STACK.init(Stack::new(device, config, RESOURCES.init(StackResources::new()), seed));
|
let (stack, runner) = embassy_net::new(device, config, RESOURCES.init(StackResources::new()), seed);
|
||||||
|
|
||||||
// Launch network task
|
// Launch network task
|
||||||
spawner.spawn(net_task(stack)).unwrap();
|
spawner.spawn(net_task(runner)).unwrap();
|
||||||
|
|
||||||
// Then we can use it!
|
// Then we can use it!
|
||||||
let mut rx_buffer = [0; 4096];
|
let mut rx_buffer = [0; 4096];
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use embassy_executor::{Executor, Spawner};
|
use embassy_executor::{Executor, Spawner};
|
||||||
use embassy_net::dns::DnsQueryType;
|
use embassy_net::dns::DnsQueryType;
|
||||||
use embassy_net::{Config, Ipv4Address, Ipv4Cidr, Stack, StackResources};
|
use embassy_net::{Config, Ipv4Address, Ipv4Cidr, StackResources};
|
||||||
use embassy_net_tuntap::TunTapDevice;
|
use embassy_net_tuntap::TunTapDevice;
|
||||||
use heapless::Vec;
|
use heapless::Vec;
|
||||||
use log::*;
|
use log::*;
|
||||||
@ -20,8 +20,8 @@ struct Opts {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn net_task(stack: &'static Stack<TunTapDevice>) -> ! {
|
async fn net_task(mut runner: embassy_net::Runner<'static, TunTapDevice>) -> ! {
|
||||||
stack.run().await
|
runner.run().await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
@ -49,12 +49,11 @@ async fn main_task(spawner: Spawner) {
|
|||||||
let seed = u64::from_le_bytes(seed);
|
let seed = u64::from_le_bytes(seed);
|
||||||
|
|
||||||
// Init network stack
|
// Init network stack
|
||||||
static STACK: StaticCell<Stack<TunTapDevice>> = StaticCell::new();
|
|
||||||
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
||||||
let stack: &Stack<_> = &*STACK.init(Stack::new(device, config, RESOURCES.init(StackResources::new()), seed));
|
let (stack, runner) = embassy_net::new(device, config, RESOURCES.init(StackResources::new()), seed);
|
||||||
|
|
||||||
// Launch network task
|
// Launch network task
|
||||||
spawner.spawn(net_task(stack)).unwrap();
|
spawner.spawn(net_task(runner)).unwrap();
|
||||||
|
|
||||||
let host = "example.com";
|
let host = "example.com";
|
||||||
info!("querying host {:?}...", host);
|
info!("querying host {:?}...", host);
|
||||||
|
@ -37,16 +37,12 @@ struct Opts {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn net_task(stack: &'static Stack<embassy_net_ppp::Device<'static>>) -> ! {
|
async fn net_task(mut runner: embassy_net::Runner<'static, embassy_net_ppp::Device<'static>>) -> ! {
|
||||||
stack.run().await
|
runner.run().await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn ppp_task(
|
async fn ppp_task(stack: Stack<'static>, mut runner: Runner<'static>, port: SerialPort) -> ! {
|
||||||
stack: &'static Stack<embassy_net_ppp::Device<'static>>,
|
|
||||||
mut runner: Runner<'static>,
|
|
||||||
port: SerialPort,
|
|
||||||
) -> ! {
|
|
||||||
let port = Async::new(port).unwrap();
|
let port = Async::new(port).unwrap();
|
||||||
let port = BufReader::new(port);
|
let port = BufReader::new(port);
|
||||||
let port = adapter::FromFutures::new(port);
|
let port = adapter::FromFutures::new(port);
|
||||||
@ -97,17 +93,16 @@ async fn main_task(spawner: Spawner) {
|
|||||||
let seed = u64::from_le_bytes(seed);
|
let seed = u64::from_le_bytes(seed);
|
||||||
|
|
||||||
// Init network stack
|
// Init network stack
|
||||||
static STACK: StaticCell<Stack<embassy_net_ppp::Device<'static>>> = StaticCell::new();
|
|
||||||
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
||||||
let stack = &*STACK.init(Stack::new(
|
let (stack, net_runner) = embassy_net::new(
|
||||||
device,
|
device,
|
||||||
Config::default(), // don't configure IP yet
|
Config::default(), // don't configure IP yet
|
||||||
RESOURCES.init(StackResources::new()),
|
RESOURCES.init(StackResources::new()),
|
||||||
seed,
|
seed,
|
||||||
));
|
);
|
||||||
|
|
||||||
// Launch network task
|
// Launch network task
|
||||||
spawner.spawn(net_task(stack)).unwrap();
|
spawner.spawn(net_task(net_runner)).unwrap();
|
||||||
spawner.spawn(ppp_task(stack, runner, port)).unwrap();
|
spawner.spawn(ppp_task(stack, runner, port)).unwrap();
|
||||||
|
|
||||||
// Then we can use it!
|
// Then we can use it!
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use embassy_executor::{Executor, Spawner};
|
use embassy_executor::{Executor, Spawner};
|
||||||
use embassy_net::udp::{PacketMetadata, UdpSocket};
|
use embassy_net::udp::{PacketMetadata, UdpSocket};
|
||||||
use embassy_net::{Config, Ipv4Address, Ipv4Cidr, Stack, StackResources};
|
use embassy_net::{Config, Ipv4Address, Ipv4Cidr, StackResources};
|
||||||
use embassy_net_tuntap::TunTapDevice;
|
use embassy_net_tuntap::TunTapDevice;
|
||||||
use heapless::Vec;
|
use heapless::Vec;
|
||||||
use log::*;
|
use log::*;
|
||||||
@ -20,8 +20,8 @@ struct Opts {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn net_task(stack: &'static Stack<TunTapDevice>) -> ! {
|
async fn net_task(mut runner: embassy_net::Runner<'static, TunTapDevice>) -> ! {
|
||||||
stack.run().await
|
runner.run().await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
@ -48,12 +48,11 @@ async fn main_task(spawner: Spawner) {
|
|||||||
let seed = u64::from_le_bytes(seed);
|
let seed = u64::from_le_bytes(seed);
|
||||||
|
|
||||||
// Init network stack
|
// Init network stack
|
||||||
static STACK: StaticCell<Stack<TunTapDevice>> = StaticCell::new();
|
|
||||||
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
||||||
let stack = &*STACK.init(Stack::new(device, config, RESOURCES.init(StackResources::new()), seed));
|
let (stack, runner) = embassy_net::new(device, config, RESOURCES.init(StackResources::new()), seed);
|
||||||
|
|
||||||
// Launch network task
|
// Launch network task
|
||||||
spawner.spawn(net_task(stack)).unwrap();
|
spawner.spawn(net_task(runner)).unwrap();
|
||||||
|
|
||||||
// Then we can use it!
|
// Then we can use it!
|
||||||
let mut rx_meta = [PacketMetadata::EMPTY; 16];
|
let mut rx_meta = [PacketMetadata::EMPTY; 16];
|
||||||
|
@ -3,7 +3,7 @@ use core::fmt::Write as _;
|
|||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use embassy_executor::{Executor, Spawner};
|
use embassy_executor::{Executor, Spawner};
|
||||||
use embassy_net::tcp::TcpSocket;
|
use embassy_net::tcp::TcpSocket;
|
||||||
use embassy_net::{Config, Ipv4Address, Ipv4Cidr, Stack, StackResources};
|
use embassy_net::{Config, Ipv4Address, Ipv4Cidr, StackResources};
|
||||||
use embassy_net_tuntap::TunTapDevice;
|
use embassy_net_tuntap::TunTapDevice;
|
||||||
use embassy_time::{Duration, Timer};
|
use embassy_time::{Duration, Timer};
|
||||||
use embedded_io_async::Write as _;
|
use embedded_io_async::Write as _;
|
||||||
@ -24,8 +24,8 @@ struct Opts {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn net_task(stack: &'static Stack<TunTapDevice>) -> ! {
|
async fn net_task(mut runner: embassy_net::Runner<'static, TunTapDevice>) -> ! {
|
||||||
stack.run().await
|
runner.run().await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
@ -62,12 +62,11 @@ async fn main_task(spawner: Spawner) {
|
|||||||
let seed = u64::from_le_bytes(seed);
|
let seed = u64::from_le_bytes(seed);
|
||||||
|
|
||||||
// Init network stack
|
// Init network stack
|
||||||
static STACK: StaticCell<Stack<TunTapDevice>> = StaticCell::new();
|
|
||||||
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
||||||
let stack = &*STACK.init(Stack::new(device, config, RESOURCES.init(StackResources::new()), seed));
|
let (stack, runner) = embassy_net::new(device, config, RESOURCES.init(StackResources::new()), seed);
|
||||||
|
|
||||||
// Launch network task
|
// Launch network task
|
||||||
spawner.spawn(net_task(stack)).unwrap();
|
spawner.spawn(net_task(runner)).unwrap();
|
||||||
|
|
||||||
// Then we can use it!
|
// Then we can use it!
|
||||||
let mut rx_buffer = [0; 4096];
|
let mut rx_buffer = [0; 4096];
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
use defmt::*;
|
use defmt::*;
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_net::tcp::TcpSocket;
|
use embassy_net::tcp::TcpSocket;
|
||||||
use embassy_net::{Ipv4Address, Stack, StackResources};
|
use embassy_net::{Ipv4Address, StackResources};
|
||||||
use embassy_stm32::eth::generic_smi::GenericSMI;
|
use embassy_stm32::eth::generic_smi::GenericSMI;
|
||||||
use embassy_stm32::eth::{Ethernet, PacketQueue};
|
use embassy_stm32::eth::{Ethernet, PacketQueue};
|
||||||
use embassy_stm32::peripherals::ETH;
|
use embassy_stm32::peripherals::ETH;
|
||||||
@ -24,8 +24,8 @@ bind_interrupts!(struct Irqs {
|
|||||||
type Device = Ethernet<'static, ETH, GenericSMI>;
|
type Device = Ethernet<'static, ETH, GenericSMI>;
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn net_task(stack: &'static Stack<Device>) -> ! {
|
async fn net_task(mut runner: embassy_net::Runner<'static, Device>) -> ! {
|
||||||
stack.run().await
|
runner.run().await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
@ -88,12 +88,11 @@ async fn main(spawner: Spawner) -> ! {
|
|||||||
//});
|
//});
|
||||||
|
|
||||||
// Init network stack
|
// Init network stack
|
||||||
static STACK: StaticCell<Stack<Device>> = StaticCell::new();
|
|
||||||
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
||||||
let stack = &*STACK.init(Stack::new(device, config, RESOURCES.init(StackResources::new()), seed));
|
let (stack, runner) = embassy_net::new(device, config, RESOURCES.init(StackResources::new()), seed);
|
||||||
|
|
||||||
// Launch network task
|
// Launch network task
|
||||||
unwrap!(spawner.spawn(net_task(stack)));
|
unwrap!(spawner.spawn(net_task(runner)));
|
||||||
|
|
||||||
// Ensure DHCP configuration is up before trying connect
|
// Ensure DHCP configuration is up before trying connect
|
||||||
stack.wait_config_up().await;
|
stack.wait_config_up().await;
|
||||||
@ -105,7 +104,7 @@ async fn main(spawner: Spawner) -> ! {
|
|||||||
let mut tx_buffer = [0; 4096];
|
let mut tx_buffer = [0; 4096];
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let mut socket = TcpSocket::new(&stack, &mut rx_buffer, &mut tx_buffer);
|
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(embassy_time::Duration::from_secs(10)));
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
use defmt::*;
|
use defmt::*;
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_net::tcp::TcpSocket;
|
use embassy_net::tcp::TcpSocket;
|
||||||
use embassy_net::{Ipv4Address, Stack, StackResources};
|
use embassy_net::{Ipv4Address, StackResources};
|
||||||
use embassy_net_wiznet::chip::W5500;
|
use embassy_net_wiznet::chip::W5500;
|
||||||
use embassy_net_wiznet::{Device, Runner, State};
|
use embassy_net_wiznet::{Device, Runner, State};
|
||||||
use embassy_stm32::exti::ExtiInput;
|
use embassy_stm32::exti::ExtiInput;
|
||||||
@ -31,8 +31,8 @@ async fn ethernet_task(runner: Runner<'static, W5500, EthernetSPI, ExtiInput<'st
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn net_task(stack: &'static Stack<Device<'static>>) -> ! {
|
async fn net_task(mut runner: embassy_net::Runner<'static, Device<'static>>) -> ! {
|
||||||
stack.run().await
|
runner.run().await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
@ -92,12 +92,11 @@ async fn main(spawner: Spawner) -> ! {
|
|||||||
// gateway: Some(Ipv4Address::new(10, 42, 0, 1)),
|
// gateway: Some(Ipv4Address::new(10, 42, 0, 1)),
|
||||||
//});
|
//});
|
||||||
|
|
||||||
static STACK: StaticCell<Stack<Device>> = StaticCell::new();
|
|
||||||
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
||||||
let stack = &*STACK.init(Stack::new(device, config, RESOURCES.init(StackResources::new()), seed));
|
let (stack, runner) = embassy_net::new(device, config, RESOURCES.init(StackResources::new()), seed);
|
||||||
|
|
||||||
// Launch network task
|
// Launch network task
|
||||||
unwrap!(spawner.spawn(net_task(stack)));
|
unwrap!(spawner.spawn(net_task(runner)));
|
||||||
|
|
||||||
// Ensure DHCP configuration is up before trying connect
|
// Ensure DHCP configuration is up before trying connect
|
||||||
stack.wait_config_up().await;
|
stack.wait_config_up().await;
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
use defmt::*;
|
use defmt::*;
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_net::tcp::TcpSocket;
|
use embassy_net::tcp::TcpSocket;
|
||||||
use embassy_net::{Stack, StackResources};
|
use embassy_net::StackResources;
|
||||||
use embassy_stm32::rng::{self, Rng};
|
use embassy_stm32::rng::{self, Rng};
|
||||||
use embassy_stm32::time::Hertz;
|
use embassy_stm32::time::Hertz;
|
||||||
use embassy_stm32::usb::Driver;
|
use embassy_stm32::usb::Driver;
|
||||||
@ -31,8 +31,8 @@ async fn usb_ncm_task(class: Runner<'static, UsbDriver, MTU>) -> ! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn net_task(stack: &'static Stack<Device<'static, MTU>>) -> ! {
|
async fn net_task(mut runner: embassy_net::Runner<'static, Device<'static, MTU>>) -> ! {
|
||||||
stack.run().await
|
runner.run().await
|
||||||
}
|
}
|
||||||
|
|
||||||
bind_interrupts!(struct Irqs {
|
bind_interrupts!(struct Irqs {
|
||||||
@ -144,11 +144,10 @@ async fn main(spawner: Spawner) {
|
|||||||
let seed = u64::from_le_bytes(seed);
|
let seed = u64::from_le_bytes(seed);
|
||||||
|
|
||||||
// Init network stack
|
// Init network stack
|
||||||
static STACK: StaticCell<Stack<Device<'static, MTU>>> = StaticCell::new();
|
|
||||||
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
||||||
let stack = &*STACK.init(Stack::new(device, config, RESOURCES.init(StackResources::new()), seed));
|
let (stack, runner) = embassy_net::new(device, config, RESOURCES.init(StackResources::new()), seed);
|
||||||
|
|
||||||
unwrap!(spawner.spawn(net_task(stack)));
|
unwrap!(spawner.spawn(net_task(runner)));
|
||||||
|
|
||||||
// And now we can use it!
|
// And now we can use it!
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
use defmt::*;
|
use defmt::*;
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_net::tcp::TcpSocket;
|
use embassy_net::tcp::TcpSocket;
|
||||||
use embassy_net::{Ipv4Address, Stack, StackResources};
|
use embassy_net::{Ipv4Address, StackResources};
|
||||||
use embassy_stm32::eth::generic_smi::GenericSMI;
|
use embassy_stm32::eth::generic_smi::GenericSMI;
|
||||||
use embassy_stm32::eth::{Ethernet, PacketQueue};
|
use embassy_stm32::eth::{Ethernet, PacketQueue};
|
||||||
use embassy_stm32::peripherals::ETH;
|
use embassy_stm32::peripherals::ETH;
|
||||||
@ -25,8 +25,8 @@ bind_interrupts!(struct Irqs {
|
|||||||
type Device = Ethernet<'static, ETH, GenericSMI>;
|
type Device = Ethernet<'static, ETH, GenericSMI>;
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn net_task(stack: &'static Stack<Device>) -> ! {
|
async fn net_task(mut runner: embassy_net::Runner<'static, Device>) -> ! {
|
||||||
stack.run().await
|
runner.run().await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
@ -89,12 +89,11 @@ async fn main(spawner: Spawner) -> ! {
|
|||||||
//});
|
//});
|
||||||
|
|
||||||
// Init network stack
|
// Init network stack
|
||||||
static STACK: StaticCell<Stack<Device>> = StaticCell::new();
|
|
||||||
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
||||||
let stack = &*STACK.init(Stack::new(device, config, RESOURCES.init(StackResources::new()), seed));
|
let (stack, runner) = embassy_net::new(device, config, RESOURCES.init(StackResources::new()), seed);
|
||||||
|
|
||||||
// Launch network task
|
// Launch network task
|
||||||
unwrap!(spawner.spawn(net_task(stack)));
|
unwrap!(spawner.spawn(net_task(runner)));
|
||||||
|
|
||||||
// Ensure DHCP configuration is up before trying connect
|
// Ensure DHCP configuration is up before trying connect
|
||||||
stack.wait_config_up().await;
|
stack.wait_config_up().await;
|
||||||
@ -106,7 +105,7 @@ async fn main(spawner: Spawner) -> ! {
|
|||||||
let mut tx_buffer = [0; 4096];
|
let mut tx_buffer = [0; 4096];
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let mut socket = TcpSocket::new(&stack, &mut rx_buffer, &mut tx_buffer);
|
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(embassy_time::Duration::from_secs(10)));
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
use defmt::*;
|
use defmt::*;
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_net::tcp::TcpSocket;
|
use embassy_net::tcp::TcpSocket;
|
||||||
use embassy_net::{Ipv4Address, Stack, StackResources};
|
use embassy_net::{Ipv4Address, StackResources};
|
||||||
use embassy_stm32::eth::generic_smi::GenericSMI;
|
use embassy_stm32::eth::generic_smi::GenericSMI;
|
||||||
use embassy_stm32::eth::{Ethernet, PacketQueue};
|
use embassy_stm32::eth::{Ethernet, PacketQueue};
|
||||||
use embassy_stm32::peripherals::ETH;
|
use embassy_stm32::peripherals::ETH;
|
||||||
@ -28,8 +28,8 @@ bind_interrupts!(struct Irqs {
|
|||||||
type Device = Ethernet<'static, ETH, GenericSMI>;
|
type Device = Ethernet<'static, ETH, GenericSMI>;
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn net_task(stack: &'static Stack<Device>) -> ! {
|
async fn net_task(mut runner: embassy_net::Runner<'static, Device>) -> ! {
|
||||||
stack.run().await
|
runner.run().await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
@ -92,12 +92,11 @@ async fn main(spawner: Spawner) -> ! {
|
|||||||
//});
|
//});
|
||||||
|
|
||||||
// Init network stack
|
// Init network stack
|
||||||
static STACK: StaticCell<Stack<Device>> = StaticCell::new();
|
|
||||||
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
||||||
let stack = &*STACK.init(Stack::new(device, config, RESOURCES.init(StackResources::new()), seed));
|
let (stack, runner) = embassy_net::new(device, config, RESOURCES.init(StackResources::new()), seed);
|
||||||
|
|
||||||
// Launch network task
|
// Launch network task
|
||||||
unwrap!(spawner.spawn(net_task(&stack)));
|
unwrap!(spawner.spawn(net_task(runner)));
|
||||||
|
|
||||||
// Ensure DHCP configuration is up before trying connect
|
// Ensure DHCP configuration is up before trying connect
|
||||||
stack.wait_config_up().await;
|
stack.wait_config_up().await;
|
||||||
@ -109,7 +108,7 @@ async fn main(spawner: Spawner) -> ! {
|
|||||||
let mut tx_buffer = [0; 1024];
|
let mut tx_buffer = [0; 1024];
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let mut socket = TcpSocket::new(&stack, &mut rx_buffer, &mut tx_buffer);
|
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(embassy_time::Duration::from_secs(10)));
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
use defmt::*;
|
use defmt::*;
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_net::tcp::TcpSocket;
|
use embassy_net::tcp::TcpSocket;
|
||||||
use embassy_net::{Ipv4Address, Stack, StackResources};
|
use embassy_net::{Ipv4Address, StackResources};
|
||||||
use embassy_stm32::eth::generic_smi::GenericSMI;
|
use embassy_stm32::eth::generic_smi::GenericSMI;
|
||||||
use embassy_stm32::eth::{Ethernet, PacketQueue};
|
use embassy_stm32::eth::{Ethernet, PacketQueue};
|
||||||
use embassy_stm32::peripherals::ETH;
|
use embassy_stm32::peripherals::ETH;
|
||||||
@ -24,8 +24,8 @@ bind_interrupts!(struct Irqs {
|
|||||||
type Device = Ethernet<'static, ETH, GenericSMI>;
|
type Device = Ethernet<'static, ETH, GenericSMI>;
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn net_task(stack: &'static Stack<Device>) -> ! {
|
async fn net_task(mut runner: embassy_net::Runner<'static, Device>) -> ! {
|
||||||
stack.run().await
|
runner.run().await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
@ -91,12 +91,11 @@ async fn main(spawner: Spawner) -> ! {
|
|||||||
//});
|
//});
|
||||||
|
|
||||||
// Init network stack
|
// Init network stack
|
||||||
static STACK: StaticCell<Stack<Device>> = StaticCell::new();
|
|
||||||
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
||||||
let stack = &*STACK.init(Stack::new(device, config, RESOURCES.init(StackResources::new()), seed));
|
let (stack, runner) = embassy_net::new(device, config, RESOURCES.init(StackResources::new()), seed);
|
||||||
|
|
||||||
// Launch network task
|
// Launch network task
|
||||||
unwrap!(spawner.spawn(net_task(&stack)));
|
unwrap!(spawner.spawn(net_task(runner)));
|
||||||
|
|
||||||
// Ensure DHCP configuration is up before trying connect
|
// Ensure DHCP configuration is up before trying connect
|
||||||
stack.wait_config_up().await;
|
stack.wait_config_up().await;
|
||||||
@ -108,7 +107,7 @@ async fn main(spawner: Spawner) -> ! {
|
|||||||
let mut tx_buffer = [0; 1024];
|
let mut tx_buffer = [0; 1024];
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let mut socket = TcpSocket::new(&stack, &mut rx_buffer, &mut tx_buffer);
|
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(embassy_time::Duration::from_secs(10)));
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
use defmt::*;
|
use defmt::*;
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_net::tcp::client::{TcpClient, TcpClientState};
|
use embassy_net::tcp::client::{TcpClient, TcpClientState};
|
||||||
use embassy_net::{Stack, StackResources};
|
use embassy_net::StackResources;
|
||||||
use embassy_stm32::eth::generic_smi::GenericSMI;
|
use embassy_stm32::eth::generic_smi::GenericSMI;
|
||||||
use embassy_stm32::eth::{Ethernet, PacketQueue};
|
use embassy_stm32::eth::{Ethernet, PacketQueue};
|
||||||
use embassy_stm32::peripherals::ETH;
|
use embassy_stm32::peripherals::ETH;
|
||||||
@ -25,8 +25,8 @@ bind_interrupts!(struct Irqs {
|
|||||||
type Device = Ethernet<'static, ETH, GenericSMI>;
|
type Device = Ethernet<'static, ETH, GenericSMI>;
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn net_task(stack: &'static Stack<Device>) -> ! {
|
async fn net_task(mut runner: embassy_net::Runner<'static, Device>) -> ! {
|
||||||
stack.run().await
|
runner.run().await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
@ -91,12 +91,11 @@ async fn main(spawner: Spawner) -> ! {
|
|||||||
//});
|
//});
|
||||||
|
|
||||||
// Init network stack
|
// Init network stack
|
||||||
static STACK: StaticCell<Stack<Device>> = StaticCell::new();
|
|
||||||
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
||||||
let stack = &*STACK.init(Stack::new(device, config, RESOURCES.init(StackResources::new()), seed));
|
let (stack, runner) = embassy_net::new(device, config, RESOURCES.init(StackResources::new()), seed);
|
||||||
|
|
||||||
// Launch network task
|
// Launch network task
|
||||||
unwrap!(spawner.spawn(net_task(stack)));
|
unwrap!(spawner.spawn(net_task(runner)));
|
||||||
|
|
||||||
// Ensure DHCP configuration is up before trying connect
|
// Ensure DHCP configuration is up before trying connect
|
||||||
stack.wait_config_up().await;
|
stack.wait_config_up().await;
|
||||||
@ -104,7 +103,7 @@ async fn main(spawner: Spawner) -> ! {
|
|||||||
info!("Network task initialized");
|
info!("Network task initialized");
|
||||||
|
|
||||||
let state: TcpClientState<1, 1024, 1024> = TcpClientState::new();
|
let state: TcpClientState<1, 1024, 1024> = TcpClientState::new();
|
||||||
let client = TcpClient::new(&stack, &state);
|
let client = TcpClient::new(stack, &state);
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
// You need to start a server on the host machine, for example: `nc -l 8000`
|
// You need to start a server on the host machine, for example: `nc -l 8000`
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
use defmt::*;
|
use defmt::*;
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_net::tcp::client::{TcpClient, TcpClientState};
|
use embassy_net::tcp::client::{TcpClient, TcpClientState};
|
||||||
use embassy_net::{Stack, StackResources};
|
use embassy_net::StackResources;
|
||||||
use embassy_stm32::eth::generic_smi::GenericSMI;
|
use embassy_stm32::eth::generic_smi::GenericSMI;
|
||||||
use embassy_stm32::eth::{Ethernet, PacketQueue};
|
use embassy_stm32::eth::{Ethernet, PacketQueue};
|
||||||
use embassy_stm32::peripherals::ETH;
|
use embassy_stm32::peripherals::ETH;
|
||||||
@ -25,8 +25,8 @@ bind_interrupts!(struct Irqs {
|
|||||||
type Device = Ethernet<'static, ETH, GenericSMI>;
|
type Device = Ethernet<'static, ETH, GenericSMI>;
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn net_task(stack: &'static Stack<Device>) -> ! {
|
async fn net_task(mut runner: embassy_net::Runner<'static, Device>) -> ! {
|
||||||
stack.run().await
|
runner.run().await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
@ -97,12 +97,11 @@ async fn main(spawner: Spawner) -> ! {
|
|||||||
//});
|
//});
|
||||||
|
|
||||||
// Init network stack
|
// Init network stack
|
||||||
static STACK: StaticCell<Stack<Device>> = StaticCell::new();
|
|
||||||
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
||||||
let stack = &*STACK.init(Stack::new(device, config, RESOURCES.init(StackResources::new()), seed));
|
let (stack, runner) = embassy_net::new(device, config, RESOURCES.init(StackResources::new()), seed);
|
||||||
|
|
||||||
// Launch network task
|
// Launch network task
|
||||||
unwrap!(spawner.spawn(net_task(stack)));
|
unwrap!(spawner.spawn(net_task(runner)));
|
||||||
|
|
||||||
// Ensure DHCP configuration is up before trying connect
|
// Ensure DHCP configuration is up before trying connect
|
||||||
stack.wait_config_up().await;
|
stack.wait_config_up().await;
|
||||||
@ -110,7 +109,7 @@ async fn main(spawner: Spawner) -> ! {
|
|||||||
info!("Network task initialized");
|
info!("Network task initialized");
|
||||||
|
|
||||||
let state: TcpClientState<1, 1024, 1024> = TcpClientState::new();
|
let state: TcpClientState<1, 1024, 1024> = TcpClientState::new();
|
||||||
let client = TcpClient::new(&stack, &state);
|
let client = TcpClient::new(stack, &state);
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
// You need to start a server on the host machine, for example: `nc -l 8000`
|
// You need to start a server on the host machine, for example: `nc -l 8000`
|
||||||
|
@ -206,12 +206,11 @@ async fn main(spawner: Spawner) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Init network stack
|
// Init network stack
|
||||||
static STACK: StaticCell<Stack<Device<'static>>> = StaticCell::new();
|
|
||||||
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
||||||
let stack = &*STACK.init(Stack::new(device, ip_cfg, RESOURCES.init(StackResources::new()), seed));
|
let (stack, runner) = embassy_net::new(device, ip_cfg, RESOURCES.init(StackResources::new()), seed);
|
||||||
|
|
||||||
// Launch network task
|
// Launch network task
|
||||||
unwrap!(spawner.spawn(net_task(stack)));
|
unwrap!(spawner.spawn(net_task(runner)));
|
||||||
|
|
||||||
let cfg = wait_for_config(stack).await;
|
let cfg = wait_for_config(stack).await;
|
||||||
let local_addr = cfg.address.address();
|
let local_addr = cfg.address.address();
|
||||||
@ -274,7 +273,7 @@ async fn main(spawner: Spawner) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn wait_for_config(stack: &'static Stack<Device<'static>>) -> embassy_net::StaticConfigV4 {
|
async fn wait_for_config(stack: Stack<'static>) -> embassy_net::StaticConfigV4 {
|
||||||
loop {
|
loop {
|
||||||
if let Some(config) = stack.config_v4() {
|
if let Some(config) = stack.config_v4() {
|
||||||
return config;
|
return config;
|
||||||
@ -323,8 +322,8 @@ async fn ethernet_task(runner: Runner<'static, SpeSpiCs, SpeInt, SpeRst>) -> ! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn net_task(stack: &'static Stack<Device<'static>>) -> ! {
|
async fn net_task(mut runner: embassy_net::Runner<'static, Device<'static>>) -> ! {
|
||||||
stack.run().await
|
runner.run().await
|
||||||
}
|
}
|
||||||
|
|
||||||
// same panicking *behavior* as `panic-probe` but doesn't print a panic message
|
// same panicking *behavior* as `panic-probe` but doesn't print a panic message
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
use defmt::*;
|
use defmt::*;
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_net::tcp::TcpSocket;
|
use embassy_net::tcp::TcpSocket;
|
||||||
use embassy_net::{Stack, StackResources};
|
use embassy_net::StackResources;
|
||||||
use embassy_stm32::rng::Rng;
|
use embassy_stm32::rng::Rng;
|
||||||
use embassy_stm32::usb::Driver;
|
use embassy_stm32::usb::Driver;
|
||||||
use embassy_stm32::{bind_interrupts, peripherals, rng, usb, Config};
|
use embassy_stm32::{bind_interrupts, peripherals, rng, usb, Config};
|
||||||
@ -36,8 +36,8 @@ async fn usb_ncm_task(class: Runner<'static, MyDriver, MTU>) -> ! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn net_task(stack: &'static Stack<Device<'static, MTU>>) -> ! {
|
async fn net_task(mut runner: embassy_net::Runner<'static, Device<'static, MTU>>) -> ! {
|
||||||
stack.run().await
|
runner.run().await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
@ -121,11 +121,10 @@ async fn main(spawner: Spawner) {
|
|||||||
let seed = rng.next_u64();
|
let seed = rng.next_u64();
|
||||||
|
|
||||||
// Init network stack
|
// Init network stack
|
||||||
static STACK: StaticCell<Stack<Device<'static, MTU>>> = StaticCell::new();
|
|
||||||
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
||||||
let stack = &*STACK.init(Stack::new(device, config, RESOURCES.init(StackResources::new()), seed));
|
let (stack, runner) = embassy_net::new(device, config, RESOURCES.init(StackResources::new()), seed);
|
||||||
|
|
||||||
unwrap!(spawner.spawn(net_task(stack)));
|
unwrap!(spawner.spawn(net_task(runner)));
|
||||||
|
|
||||||
// And now we can use it!
|
// And now we can use it!
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ teleprobe_meta::timeout!(120);
|
|||||||
|
|
||||||
use defmt::{info, unwrap};
|
use defmt::{info, unwrap};
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_net::{Stack, StackResources};
|
use embassy_net::StackResources;
|
||||||
use embassy_net_enc28j60::Enc28j60;
|
use embassy_net_enc28j60::Enc28j60;
|
||||||
use embassy_nrf::gpio::{Level, Output, OutputDrive};
|
use embassy_nrf::gpio::{Level, Output, OutputDrive};
|
||||||
use embassy_nrf::rng::Rng;
|
use embassy_nrf::rng::Rng;
|
||||||
@ -25,8 +25,8 @@ bind_interrupts!(struct Irqs {
|
|||||||
type MyDriver = Enc28j60<ExclusiveDevice<Spim<'static, peripherals::SPI3>, Output<'static>, Delay>, Output<'static>>;
|
type MyDriver = Enc28j60<ExclusiveDevice<Spim<'static, peripherals::SPI3>, Output<'static>, Delay>, Output<'static>>;
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn net_task(stack: &'static Stack<MyDriver>) -> ! {
|
async fn net_task(mut runner: embassy_net::Runner<'static, MyDriver>) -> ! {
|
||||||
stack.run().await
|
runner.run().await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
@ -65,11 +65,10 @@ async fn main(spawner: Spawner) {
|
|||||||
let seed = u64::from_le_bytes(seed);
|
let seed = u64::from_le_bytes(seed);
|
||||||
|
|
||||||
// Init network stack
|
// Init network stack
|
||||||
static STACK: StaticCell<Stack<MyDriver>> = StaticCell::new();
|
|
||||||
static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new();
|
static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new();
|
||||||
let stack = &*STACK.init(Stack::new(device, config, RESOURCES.init(StackResources::new()), seed));
|
let (stack, runner) = embassy_net::new(device, config, RESOURCES.init(StackResources::new()), seed);
|
||||||
|
|
||||||
unwrap!(spawner.spawn(net_task(stack)));
|
unwrap!(spawner.spawn(net_task(runner)));
|
||||||
|
|
||||||
perf_client::run(
|
perf_client::run(
|
||||||
stack,
|
stack,
|
||||||
|
@ -6,7 +6,7 @@ teleprobe_meta::timeout!(120);
|
|||||||
|
|
||||||
use defmt::{info, unwrap};
|
use defmt::{info, unwrap};
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_net::{Config, Stack, StackResources};
|
use embassy_net::{Config, StackResources};
|
||||||
use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull};
|
use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull};
|
||||||
use embassy_nrf::rng::Rng;
|
use embassy_nrf::rng::Rng;
|
||||||
use embassy_nrf::spim::{self, Spim};
|
use embassy_nrf::spim::{self, Spim};
|
||||||
@ -40,8 +40,8 @@ async fn wifi_task(
|
|||||||
type MyDriver = hosted::NetDriver<'static>;
|
type MyDriver = hosted::NetDriver<'static>;
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn net_task(stack: &'static Stack<MyDriver>) -> ! {
|
async fn net_task(mut runner: embassy_net::Runner<'static, MyDriver>) -> ! {
|
||||||
stack.run().await
|
runner.run().await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
@ -86,16 +86,15 @@ async fn main(spawner: Spawner) {
|
|||||||
let seed = u64::from_le_bytes(seed);
|
let seed = u64::from_le_bytes(seed);
|
||||||
|
|
||||||
// Init network stack
|
// Init network stack
|
||||||
static STACK: StaticCell<Stack<MyDriver>> = StaticCell::new();
|
|
||||||
static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new();
|
static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new();
|
||||||
let stack = &*STACK.init(Stack::new(
|
let (stack, runner) = embassy_net::new(
|
||||||
device,
|
device,
|
||||||
Config::dhcpv4(Default::default()),
|
Config::dhcpv4(Default::default()),
|
||||||
RESOURCES.init(StackResources::new()),
|
RESOURCES.init(StackResources::new()),
|
||||||
seed,
|
seed,
|
||||||
));
|
);
|
||||||
|
|
||||||
unwrap!(spawner.spawn(net_task(stack)));
|
unwrap!(spawner.spawn(net_task(runner)));
|
||||||
|
|
||||||
perf_client::run(
|
perf_client::run(
|
||||||
stack,
|
stack,
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
use defmt::{assert, *};
|
use defmt::{assert, *};
|
||||||
use embassy_futures::join::join;
|
use embassy_futures::join::join;
|
||||||
use embassy_net::driver::Driver;
|
|
||||||
use embassy_net::tcp::TcpSocket;
|
use embassy_net::tcp::TcpSocket;
|
||||||
use embassy_net::{Ipv4Address, Stack};
|
use embassy_net::{Ipv4Address, Stack};
|
||||||
use embassy_time::{with_timeout, Duration, Timer};
|
use embassy_time::{with_timeout, Duration, Timer};
|
||||||
@ -13,7 +12,7 @@ pub struct Expected {
|
|||||||
pub updown_kbps: usize,
|
pub updown_kbps: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn run<D: Driver>(stack: &Stack<D>, expected: Expected) {
|
pub async fn run(stack: Stack<'_>, expected: Expected) {
|
||||||
info!("Waiting for DHCP up...");
|
info!("Waiting for DHCP up...");
|
||||||
while stack.config_v4().is_none() {
|
while stack.config_v4().is_none() {
|
||||||
Timer::after_millis(100).await;
|
Timer::after_millis(100).await;
|
||||||
@ -38,7 +37,7 @@ const DOWNLOAD_PORT: u16 = 4321;
|
|||||||
const UPLOAD_PORT: u16 = 4322;
|
const UPLOAD_PORT: u16 = 4322;
|
||||||
const UPLOAD_DOWNLOAD_PORT: u16 = 4323;
|
const UPLOAD_DOWNLOAD_PORT: u16 = 4323;
|
||||||
|
|
||||||
async fn test_download<D: Driver>(stack: &Stack<D>) -> usize {
|
async fn test_download(stack: Stack<'_>) -> usize {
|
||||||
info!("Testing download...");
|
info!("Testing download...");
|
||||||
|
|
||||||
let mut rx_buffer = [0; RX_BUFFER_SIZE];
|
let mut rx_buffer = [0; RX_BUFFER_SIZE];
|
||||||
@ -78,7 +77,7 @@ async fn test_download<D: Driver>(stack: &Stack<D>) -> usize {
|
|||||||
kbps
|
kbps
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn test_upload<D: Driver>(stack: &Stack<D>) -> usize {
|
async fn test_upload(stack: Stack<'_>) -> usize {
|
||||||
info!("Testing upload...");
|
info!("Testing upload...");
|
||||||
|
|
||||||
let mut rx_buffer = [0; RX_BUFFER_SIZE];
|
let mut rx_buffer = [0; RX_BUFFER_SIZE];
|
||||||
@ -118,7 +117,7 @@ async fn test_upload<D: Driver>(stack: &Stack<D>) -> usize {
|
|||||||
kbps
|
kbps
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn test_upload_download<D: Driver>(stack: &Stack<D>) -> usize {
|
async fn test_upload_download(stack: Stack<'_>) -> usize {
|
||||||
info!("Testing upload+download...");
|
info!("Testing upload+download...");
|
||||||
|
|
||||||
let mut rx_buffer = [0; RX_BUFFER_SIZE];
|
let mut rx_buffer = [0; RX_BUFFER_SIZE];
|
||||||
|
@ -6,7 +6,7 @@ use cyw43::JoinOptions;
|
|||||||
use cyw43_pio::PioSpi;
|
use cyw43_pio::PioSpi;
|
||||||
use defmt::{panic, *};
|
use defmt::{panic, *};
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_net::{Config, Stack, StackResources};
|
use embassy_net::{Config, StackResources};
|
||||||
use embassy_rp::gpio::{Level, Output};
|
use embassy_rp::gpio::{Level, Output};
|
||||||
use embassy_rp::peripherals::{DMA_CH0, PIO0};
|
use embassy_rp::peripherals::{DMA_CH0, PIO0};
|
||||||
use embassy_rp::pio::{InterruptHandler, Pio};
|
use embassy_rp::pio::{InterruptHandler, Pio};
|
||||||
@ -30,8 +30,8 @@ async fn wifi_task(runner: cyw43::Runner<'static, Output<'static>, PioSpi<'stati
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn net_task(stack: &'static Stack<cyw43::NetDriver<'static>>) -> ! {
|
async fn net_task(mut runner: embassy_net::Runner<'static, cyw43::NetDriver<'static>>) -> ! {
|
||||||
stack.run().await
|
runner.run().await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
@ -70,16 +70,15 @@ async fn main(spawner: Spawner) {
|
|||||||
let seed = 0x0123_4567_89ab_cdef; // chosen by fair dice roll. guarenteed to be random.
|
let seed = 0x0123_4567_89ab_cdef; // chosen by fair dice roll. guarenteed to be random.
|
||||||
|
|
||||||
// Init network stack
|
// Init network stack
|
||||||
static STACK: StaticCell<Stack<cyw43::NetDriver<'static>>> = StaticCell::new();
|
|
||||||
static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new();
|
static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new();
|
||||||
let stack = &*STACK.init(Stack::new(
|
let (stack, runner) = embassy_net::new(
|
||||||
net_device,
|
net_device,
|
||||||
Config::dhcpv4(Default::default()),
|
Config::dhcpv4(Default::default()),
|
||||||
RESOURCES.init(StackResources::new()),
|
RESOURCES.init(StackResources::new()),
|
||||||
seed,
|
seed,
|
||||||
));
|
);
|
||||||
|
|
||||||
unwrap!(spawner.spawn(net_task(stack)));
|
unwrap!(spawner.spawn(net_task(runner)));
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
match control
|
match control
|
||||||
|
@ -5,7 +5,7 @@ teleprobe_meta::timeout!(120);
|
|||||||
|
|
||||||
use defmt::*;
|
use defmt::*;
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_net::{Stack, StackResources};
|
use embassy_net::StackResources;
|
||||||
use embassy_net_wiznet::chip::W5100S;
|
use embassy_net_wiznet::chip::W5100S;
|
||||||
use embassy_net_wiznet::*;
|
use embassy_net_wiznet::*;
|
||||||
use embassy_rp::clocks::RoscRng;
|
use embassy_rp::clocks::RoscRng;
|
||||||
@ -32,8 +32,8 @@ async fn ethernet_task(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn net_task(stack: &'static Stack<Device<'static>>) -> ! {
|
async fn net_task(mut runner: embassy_net::Runner<'static, Device<'static>>) -> ! {
|
||||||
stack.run().await
|
runner.run().await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
@ -67,17 +67,16 @@ async fn main(spawner: Spawner) {
|
|||||||
let seed = rng.next_u64();
|
let seed = rng.next_u64();
|
||||||
|
|
||||||
// Init network stack
|
// Init network stack
|
||||||
static STACK: StaticCell<Stack<Device<'static>>> = StaticCell::new();
|
|
||||||
static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new();
|
static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new();
|
||||||
let stack = &*STACK.init(Stack::new(
|
let (stack, runner) = embassy_net::new(
|
||||||
device,
|
device,
|
||||||
embassy_net::Config::dhcpv4(Default::default()),
|
embassy_net::Config::dhcpv4(Default::default()),
|
||||||
RESOURCES.init(StackResources::new()),
|
RESOURCES.init(StackResources::new()),
|
||||||
seed,
|
seed,
|
||||||
));
|
);
|
||||||
|
|
||||||
// Launch network task
|
// Launch network task
|
||||||
unwrap!(spawner.spawn(net_task(&stack)));
|
unwrap!(spawner.spawn(net_task(runner)));
|
||||||
|
|
||||||
perf_client::run(
|
perf_client::run(
|
||||||
stack,
|
stack,
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
mod common;
|
mod common;
|
||||||
use common::*;
|
use common::*;
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_net::{Stack, StackResources};
|
use embassy_net::StackResources;
|
||||||
use embassy_stm32::eth::generic_smi::GenericSMI;
|
use embassy_stm32::eth::generic_smi::GenericSMI;
|
||||||
use embassy_stm32::eth::{Ethernet, PacketQueue};
|
use embassy_stm32::eth::{Ethernet, PacketQueue};
|
||||||
use embassy_stm32::peripherals::ETH;
|
use embassy_stm32::peripherals::ETH;
|
||||||
@ -32,8 +32,8 @@ bind_interrupts!(struct Irqs {
|
|||||||
type Device = Ethernet<'static, ETH, GenericSMI>;
|
type Device = Ethernet<'static, ETH, GenericSMI>;
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn net_task(stack: &'static Stack<Device>) -> ! {
|
async fn net_task(mut runner: embassy_net::Runner<'static, Device>) -> ! {
|
||||||
stack.run().await
|
runner.run().await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
@ -99,12 +99,11 @@ async fn main(spawner: Spawner) {
|
|||||||
//});
|
//});
|
||||||
|
|
||||||
// Init network stack
|
// Init network stack
|
||||||
static STACK: StaticCell<Stack<Device>> = StaticCell::new();
|
|
||||||
static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new();
|
static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new();
|
||||||
let stack = &*STACK.init(Stack::new(device, config, RESOURCES.init(StackResources::new()), seed));
|
let (stack, runner) = embassy_net::new(device, config, RESOURCES.init(StackResources::new()), seed);
|
||||||
|
|
||||||
// Launch network task
|
// Launch network task
|
||||||
unwrap!(spawner.spawn(net_task(&stack)));
|
unwrap!(spawner.spawn(net_task(runner)));
|
||||||
|
|
||||||
perf_client::run(
|
perf_client::run(
|
||||||
stack,
|
stack,
|
||||||
|
Loading…
Reference in New Issue
Block a user