From 5655c6093f8938c5ba637785b8bd572345f4c42e Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 26 Dec 2022 02:42:54 +0100 Subject: net: use atomic-polyfill on tcp client pool, for thumbv6m support. --- embassy-net/src/tcp.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'embassy-net/src') diff --git a/embassy-net/src/tcp.rs b/embassy-net/src/tcp.rs index 55cbda455..0dc8da73a 100644 --- a/embassy-net/src/tcp.rs +++ b/embassy-net/src/tcp.rs @@ -329,8 +329,8 @@ pub mod client { use core::cell::UnsafeCell; use core::mem::MaybeUninit; use core::ptr::NonNull; - use core::sync::atomic::{AtomicBool, Ordering}; + use atomic_polyfill::{AtomicBool, Ordering}; use embedded_nal_async::IpAddr; use super::*; -- cgit From 1f033d509afb4e590a81896de66af683fda4e706 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 26 Dec 2022 03:33:49 +0100 Subject: net: split driver trait to a separate crate. --- embassy-net/src/device.rs | 117 +++++++++++++++------------------------------- embassy-net/src/lib.rs | 17 ++++--- embassy-net/src/tcp.rs | 12 ++--- embassy-net/src/udp.rs | 5 +- 4 files changed, 55 insertions(+), 96 deletions(-) (limited to 'embassy-net/src') diff --git a/embassy-net/src/device.rs b/embassy-net/src/device.rs index 5d86ca91e..44f7dc7bd 100644 --- a/embassy-net/src/device.rs +++ b/embassy-net/src/device.rs @@ -1,93 +1,20 @@ use core::task::Context; +use embassy_net_driver::{Capabilities, Checksum, Driver, Medium, RxToken, TxToken}; use smoltcp::phy; -pub use smoltcp::phy::{Checksum, ChecksumCapabilities, DeviceCapabilities, Medium}; -#[derive(PartialEq, Eq, Clone, Copy)] -pub enum LinkState { - Down, - Up, -} - -pub trait Device { - type RxToken<'a>: RxToken - where - Self: 'a; - type TxToken<'a>: TxToken - where - Self: 'a; - - fn receive(&mut self, cx: &mut Context) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)>; - fn transmit(&mut self, cx: &mut Context) -> Option>; - fn link_state(&mut self, cx: &mut Context) -> LinkState; - - fn capabilities(&self) -> phy::DeviceCapabilities; - fn ethernet_address(&self) -> [u8; 6]; -} - -impl Device for &mut T { - type RxToken<'a> = T::RxToken<'a> - where - Self: 'a; - type TxToken<'a> = T::TxToken<'a> - where - Self: 'a; - - fn transmit(&mut self, cx: &mut Context) -> Option> { - T::transmit(self, cx) - } - fn receive(&mut self, cx: &mut Context) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> { - T::receive(self, cx) - } - fn capabilities(&self) -> phy::DeviceCapabilities { - T::capabilities(self) - } - fn link_state(&mut self, cx: &mut Context) -> LinkState { - T::link_state(self, cx) - } - fn ethernet_address(&self) -> [u8; 6] { - T::ethernet_address(self) - } -} - -/// A token to receive a single network packet. -pub trait RxToken { - /// Consumes the token to receive a single network packet. - /// - /// This method receives a packet and then calls the given closure `f` with the raw - /// packet bytes as argument. - fn consume(self, f: F) -> R - where - F: FnOnce(&mut [u8]) -> R; -} - -/// A token to transmit a single network packet. -pub trait TxToken { - /// Consumes the token to send a single network packet. - /// - /// This method constructs a transmit buffer of size `len` and calls the passed - /// closure `f` with a mutable reference to that buffer. The closure should construct - /// a valid network packet (e.g. an ethernet packet) in the buffer. When the closure - /// returns, the transmit buffer is sent out. - fn consume(self, len: usize, f: F) -> R - where - F: FnOnce(&mut [u8]) -> R; -} - -/////////////////////////// - -pub(crate) struct DeviceAdapter<'d, 'c, T> +pub(crate) struct DriverAdapter<'d, 'c, T> where - T: Device, + T: Driver, { // must be Some when actually using this to rx/tx pub cx: Option<&'d mut Context<'c>>, pub inner: &'d mut T, } -impl<'d, 'c, T> phy::Device for DeviceAdapter<'d, 'c, T> +impl<'d, 'c, T> phy::Device for DriverAdapter<'d, 'c, T> where - T: Device, + T: Driver, { type RxToken<'a> = RxTokenAdapter> where Self: 'a; type TxToken<'a> = TxTokenAdapter> where Self: 'a; @@ -105,7 +32,39 @@ where /// Get a description of device capabilities. fn capabilities(&self) -> phy::DeviceCapabilities { - self.inner.capabilities() + fn convert(c: Checksum) -> phy::Checksum { + match c { + Checksum::Both => phy::Checksum::Both, + Checksum::Tx => phy::Checksum::Tx, + Checksum::Rx => phy::Checksum::Rx, + Checksum::None => phy::Checksum::None, + } + } + let caps: Capabilities = self.inner.capabilities(); + let mut smolcaps = phy::DeviceCapabilities::default(); + + smolcaps.max_transmission_unit = caps.max_transmission_unit; + smolcaps.max_burst_size = caps.max_burst_size; + smolcaps.medium = match caps.medium { + #[cfg(feature = "medium-ethernet")] + Medium::Ethernet => phy::Medium::Ethernet, + #[cfg(feature = "medium-ip")] + Medium::Ip => phy::Medium::Ip, + _ => panic!( + "Unsupported medium {:?}. MAke sure to enable it in embassy-net's Cargo features.", + caps.medium + ), + }; + smolcaps.checksum.ipv4 = convert(caps.checksum.ipv4); + #[cfg(feature = "proto-ipv6")] + { + smolcaps.checksum.ipv6 = convert(caps.checksum.ipv6); + } + smolcaps.checksum.tcp = convert(caps.checksum.tcp); + smolcaps.checksum.udp = convert(caps.checksum.udp); + smolcaps.checksum.icmpv4 = convert(caps.checksum.icmpv4); + + smolcaps } } diff --git a/embassy-net/src/lib.rs b/embassy-net/src/lib.rs index afe0d6da0..b58c9cf36 100644 --- a/embassy-net/src/lib.rs +++ b/embassy-net/src/lib.rs @@ -18,6 +18,7 @@ use core::cell::RefCell; use core::future::{poll_fn, Future}; use core::task::{Context, Poll}; +use embassy_net_driver::{Driver, LinkState, Medium}; use embassy_sync::waitqueue::WakerRegistration; use embassy_time::{Instant, Timer}; use futures::pin_mut; @@ -27,8 +28,6 @@ use smoltcp::iface::SocketHandle; use smoltcp::iface::{Interface, InterfaceBuilder, SocketSet, SocketStorage}; #[cfg(feature = "medium-ethernet")] use smoltcp::iface::{Neighbor, NeighborCache, Route, Routes}; -#[cfg(feature = "medium-ethernet")] -use smoltcp::phy::Medium; #[cfg(feature = "dhcpv4")] use smoltcp::socket::dhcpv4; // smoltcp reexports @@ -41,7 +40,7 @@ pub use smoltcp::wire::{Ipv6Address, Ipv6Cidr}; #[cfg(feature = "udp")] pub use smoltcp::{socket::udp::PacketMetadata, wire::IpListenEndpoint}; -use crate::device::{Device, DeviceAdapter, LinkState}; +use crate::device::DriverAdapter; const LOCAL_PORT_MIN: u16 = 1025; const LOCAL_PORT_MAX: u16 = 65535; @@ -82,12 +81,12 @@ pub enum ConfigStrategy { Dhcp, } -pub struct Stack { +pub struct Stack { pub(crate) socket: RefCell, inner: RefCell>, } -struct Inner { +struct Inner { device: D, link_up: bool, config: Option, @@ -102,7 +101,7 @@ pub(crate) struct SocketStack { next_local_port: u16, } -impl Stack { +impl Stack { pub fn new( mut device: D, config: ConfigStrategy, @@ -130,7 +129,7 @@ impl Stack { b = b.routes(Routes::new(&mut resources.routes[..])); } - let iface = b.finalize(&mut DeviceAdapter { + let iface = b.finalize(&mut DriverAdapter { inner: &mut device, cx: None, }); @@ -211,7 +210,7 @@ impl SocketStack { } } -impl Inner { +impl Inner { fn apply_config(&mut self, s: &mut SocketStack, config: Config) { #[cfg(feature = "medium-ethernet")] let medium = self.device.capabilities().medium; @@ -263,7 +262,7 @@ impl Inner { s.waker.register(cx.waker()); let timestamp = instant_to_smoltcp(Instant::now()); - let mut smoldev = DeviceAdapter { + let mut smoldev = DriverAdapter { cx: Some(cx), inner: &mut self.device, }; diff --git a/embassy-net/src/tcp.rs b/embassy-net/src/tcp.rs index 0dc8da73a..0fbf0c91b 100644 --- a/embassy-net/src/tcp.rs +++ b/embassy-net/src/tcp.rs @@ -3,12 +3,12 @@ use core::future::poll_fn; use core::mem; use core::task::Poll; +use embassy_net_driver::Driver; use smoltcp::iface::{Interface, SocketHandle}; use smoltcp::socket::tcp; use smoltcp::time::Duration; use smoltcp::wire::{IpEndpoint, IpListenEndpoint}; -use crate::device::Device; use crate::{SocketStack, Stack}; #[derive(PartialEq, Eq, Clone, Copy, Debug)] @@ -66,7 +66,7 @@ impl<'a> TcpWriter<'a> { } impl<'a> TcpSocket<'a> { - pub fn new(stack: &'a Stack, rx_buffer: &'a mut [u8], tx_buffer: &'a mut [u8]) -> Self { + pub fn new(stack: &'a Stack, rx_buffer: &'a mut [u8], tx_buffer: &'a mut [u8]) -> Self { let s = &mut *stack.socket.borrow_mut(); let rx_buffer: &'static mut [u8] = unsafe { mem::transmute(rx_buffer) }; let tx_buffer: &'static mut [u8] = unsafe { mem::transmute(tx_buffer) }; @@ -336,19 +336,19 @@ pub mod client { use super::*; /// TCP client capable of creating up to N multiple connections with tx and rx buffers according to TX_SZ and RX_SZ. - pub struct TcpClient<'d, D: Device, const N: usize, const TX_SZ: usize = 1024, const RX_SZ: usize = 1024> { + pub struct TcpClient<'d, D: Driver, const N: usize, const TX_SZ: usize = 1024, const RX_SZ: usize = 1024> { stack: &'d Stack, state: &'d TcpClientState, } - impl<'d, D: Device, const N: usize, const TX_SZ: usize, const RX_SZ: usize> TcpClient<'d, D, N, TX_SZ, RX_SZ> { + impl<'d, D: Driver, const N: usize, const TX_SZ: usize, const RX_SZ: usize> TcpClient<'d, D, N, TX_SZ, RX_SZ> { /// Create a new TcpClient pub fn new(stack: &'d Stack, state: &'d TcpClientState) -> Self { Self { stack, state } } } - impl<'d, D: Device, const N: usize, const TX_SZ: usize, const RX_SZ: usize> embedded_nal_async::TcpConnect + impl<'d, D: Driver, const N: usize, const TX_SZ: usize, const RX_SZ: usize> embedded_nal_async::TcpConnect for TcpClient<'d, D, N, TX_SZ, RX_SZ> { type Error = Error; @@ -386,7 +386,7 @@ pub mod client { } impl<'d, const N: usize, const TX_SZ: usize, const RX_SZ: usize> TcpConnection<'d, N, TX_SZ, RX_SZ> { - fn new(stack: &'d Stack, state: &'d TcpClientState) -> Result { + fn new(stack: &'d Stack, state: &'d TcpClientState) -> Result { let mut bufs = state.pool.alloc().ok_or(Error::ConnectionReset)?; Ok(Self { socket: unsafe { TcpSocket::new(stack, &mut bufs.as_mut().0, &mut bufs.as_mut().1) }, diff --git a/embassy-net/src/udp.rs b/embassy-net/src/udp.rs index 2f5334df3..0ee8c6e19 100644 --- a/embassy-net/src/udp.rs +++ b/embassy-net/src/udp.rs @@ -3,11 +3,12 @@ use core::future::poll_fn; use core::mem; use core::task::Poll; +use embassy_net_driver::Driver; use smoltcp::iface::{Interface, SocketHandle}; use smoltcp::socket::udp::{self, PacketMetadata}; use smoltcp::wire::{IpEndpoint, IpListenEndpoint}; -use crate::{Device, SocketStack, Stack}; +use crate::{SocketStack, Stack}; #[derive(PartialEq, Eq, Clone, Copy, Debug)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] @@ -31,7 +32,7 @@ pub struct UdpSocket<'a> { } impl<'a> UdpSocket<'a> { - pub fn new( + pub fn new( stack: &'a Stack, rx_meta: &'a mut [PacketMetadata], rx_buffer: &'a mut [u8], -- cgit