Attempt then Try, try again WTF lifetime again

This commit is contained in:
atse 2024-01-11 12:26:43 +08:00
parent aeba19bca2
commit c8ceb2dbad
3 changed files with 75 additions and 64 deletions

View File

@ -172,8 +172,8 @@ fn main() -> ! {
let hwaddr = EthernetAddress(eui48);
info!("EEPROM MAC address: {}", hwaddr);
net::run(clocks, dp.ETHERNET_MAC, dp.ETHERNET_DMA, eth_pins, hwaddr, ipv4_config.clone(), |iface| {
Server::<Session>::run(iface, |server| {
net::run::<_, Session>(clocks, dp.ETHERNET_MAC, dp.ETHERNET_DMA, eth_pins, hwaddr, ipv4_config.clone(), |iface, states| {
Server::run(iface, states, |server| {
leds.r1.off();
let mut should_reset = false;

View File

@ -8,14 +8,44 @@ use stm32f4xx_hal::{
pac::{interrupt, Peripherals, ETHERNET_MAC, ETHERNET_DMA},
};
use smoltcp::wire::{EthernetAddress, Ipv4Address, Ipv4Cidr};
use smoltcp::iface::{
EthernetInterfaceBuilder, EthernetInterface,
NeighborCache, Routes,
use smoltcp::{
iface::{
InterfaceBuilder, Interface,
NeighborCache, Routes,
SocketHandle
},
socket::{TcpSocket, TcpSocketBuffer}
};
use stm32_eth::{Eth, RingEntry, RxDescriptor, TxDescriptor};
use crate::command_parser::Ipv4Config;
use crate::pins::EthernetPins;
pub struct SocketState<S> {
pub handle: SocketHandle,
pub state: S,
}
impl<'a, S: Default> SocketState<S>{
fn new(net: &mut Interface<'a, &'a mut stm32_eth::Eth<'static, 'static>>, tcp_rx_storage: &'a mut [u8; TCP_RX_BUFFER_SIZE], tcp_tx_storage: &'a mut [u8; TCP_TX_BUFFER_SIZE]) -> SocketState<S> {
let tcp_rx_buffer = TcpSocketBuffer::new(&mut tcp_rx_storage[..]);
let tcp_tx_buffer = TcpSocketBuffer::new(&mut tcp_tx_storage[..]);
let tcp_socket = TcpSocket::new(tcp_rx_buffer, tcp_tx_buffer);
SocketState::<S> {
handle: net.add_socket(tcp_socket),
state: S::default()
}
}
}
/// Number of server sockets and therefore concurrent client
/// sessions. Many data structures in `Server::run()` correspond to
/// this const.
const SOCKET_COUNT: usize = 4;
const TCP_RX_BUFFER_SIZE: usize = 2048;
const TCP_TX_BUFFER_SIZE: usize = 2048;
/// Not on the stack so that stack can be placed in CCMRAM (which the
/// ethernet peripheral cannot access)
static mut RX_RING: Option<[RingEntry<RxDescriptor>; 8]> = None;
@ -28,7 +58,7 @@ static mut TX_RING: Option<[RingEntry<TxDescriptor>; 2]> = None;
static NET_PENDING: Mutex<RefCell<bool>> = Mutex::new(RefCell::new(false));
/// Run callback `f` with ethernet driver and TCP/IP stack
pub fn run<F>(
pub fn run<'a, F, S: Default>(
clocks: Clocks,
ethernet_mac: ETHERNET_MAC, ethernet_dma: ETHERNET_DMA,
eth_pins: EthernetPins,
@ -36,7 +66,7 @@ pub fn run<F>(
ipv4_config: Ipv4Config,
f: F
) where
F: FnOnce(EthernetInterface<&mut stm32_eth::Eth<'static, 'static>>),
F: FnOnce(Interface<'a, &mut stm32_eth::Eth<'static, 'static>>, [SocketState<S>; SOCKET_COUNT]),
{
let rx_ring = unsafe {
RX_RING.get_or_insert(Default::default())
@ -61,14 +91,36 @@ pub fn run<F>(
let mut routes_storage = [None; 1];
let mut routes = Routes::new(&mut routes_storage[..]);
gateway.map(|gateway| routes.add_default_ipv4_route(gateway).unwrap());
let iface = EthernetInterfaceBuilder::new(&mut eth_dev)
.ethernet_addr(ethernet_addr)
let mut sockets: [_; SOCKET_COUNT] = Default::default();
macro_rules! create_rtx_storage {
($rx_storage:ident, $tx_storage:ident) => {
let mut $rx_storage = [0; TCP_RX_BUFFER_SIZE];
let mut $tx_storage = [0; TCP_TX_BUFFER_SIZE];
}
}
create_rtx_storage!(tcp_rx_storage0, tcp_tx_storage0);
create_rtx_storage!(tcp_rx_storage1, tcp_tx_storage1);
create_rtx_storage!(tcp_rx_storage2, tcp_tx_storage2);
create_rtx_storage!(tcp_rx_storage3, tcp_tx_storage3);
let mut iface = InterfaceBuilder::new(&mut eth_dev, &mut sockets[..])
.hardware_addr(ethernet_addr.into())
.ip_addrs(&mut ip_addrs[..])
.neighbor_cache(neighbor_cache)
.routes(routes)
.finalize();
f(iface);
let states: [SocketState<S>; SOCKET_COUNT] = [
SocketState::<S>::new(&mut iface, &mut tcp_rx_storage0, &mut tcp_tx_storage0),
SocketState::<S>::new(&mut iface, &mut tcp_rx_storage1, &mut tcp_tx_storage1),
SocketState::<S>::new(&mut iface, &mut tcp_rx_storage2, &mut tcp_tx_storage2),
SocketState::<S>::new(&mut iface, &mut tcp_rx_storage3, &mut tcp_tx_storage3),
];
f(iface, states);
}
/// Potentially wake up from `wfi()`, set the interrupt pending flag,

View File

@ -1,28 +1,11 @@
use smoltcp::{
iface::EthernetInterface,
socket::{SocketSet, SocketHandle, TcpSocket, TcpSocketBuffer, SocketRef},
iface::Interface,
socket::TcpSocket,
time::Instant,
wire::{IpAddress, IpCidr, Ipv4Address, Ipv4Cidr},
};
use crate::command_parser::Ipv4Config;
use crate::net::split_ipv4_config;
pub struct SocketState<S> {
handle: SocketHandle,
state: S,
}
impl<'a, S: Default> SocketState<S>{
fn new(sockets: &mut SocketSet<'a>, tcp_rx_storage: &'a mut [u8; TCP_RX_BUFFER_SIZE], tcp_tx_storage: &'a mut [u8; TCP_TX_BUFFER_SIZE]) -> SocketState<S> {
let tcp_rx_buffer = TcpSocketBuffer::new(&mut tcp_rx_storage[..]);
let tcp_tx_buffer = TcpSocketBuffer::new(&mut tcp_tx_storage[..]);
let tcp_socket = TcpSocket::new(tcp_rx_buffer, tcp_tx_buffer);
SocketState::<S> {
handle: sockets.add(tcp_socket),
state: S::default()
}
}
}
use crate::net::{split_ipv4_config, SocketState};
/// Number of server sockets and therefore concurrent client
/// sessions. Many data structures in `Server::run()` correspond to
@ -34,44 +17,20 @@ const TCP_TX_BUFFER_SIZE: usize = 2048;
/// Contains a number of server sockets that get all sent the same
/// data (through `fmt::Write`).
pub struct Server<'a, 'b, S> {
net: EthernetInterface<'a, &'a mut stm32_eth::Eth<'static, 'static>>,
sockets: SocketSet<'b>,
pub struct Server<'a, S> {
net: Interface<'a, &'a mut stm32_eth::Eth<'static, 'static>>,
states: [SocketState<S>; SOCKET_COUNT],
}
impl<'a, 'b, S: Default> Server<'a, 'b, S> {
impl<'a, S: Default> Server<'a, S> {
/// Run a server with stack-allocated sockets
pub fn run<F>(net: EthernetInterface<'a, &'a mut stm32_eth::Eth<'static, 'static>>, f: F)
pub fn run<F>(net: Interface<'a, &'a mut stm32_eth::Eth<'static, 'static>>, states: [SocketState<S>; SOCKET_COUNT], f: F)
where
F: FnOnce(&mut Server<'a, '_, S>),
F: FnOnce(&mut Server<'a, S>),
{
macro_rules! create_rtx_storage {
($rx_storage:ident, $tx_storage:ident) => {
let mut $rx_storage = [0; TCP_RX_BUFFER_SIZE];
let mut $tx_storage = [0; TCP_TX_BUFFER_SIZE];
}
}
create_rtx_storage!(tcp_rx_storage0, tcp_tx_storage0);
create_rtx_storage!(tcp_rx_storage1, tcp_tx_storage1);
create_rtx_storage!(tcp_rx_storage2, tcp_tx_storage2);
create_rtx_storage!(tcp_rx_storage3, tcp_tx_storage3);
let mut sockets_storage: [_; SOCKET_COUNT] = Default::default();
let mut sockets = SocketSet::new(&mut sockets_storage[..]);
let states: [SocketState<S>; SOCKET_COUNT] = [
SocketState::<S>::new(&mut sockets, &mut tcp_rx_storage0, &mut tcp_tx_storage0),
SocketState::<S>::new(&mut sockets, &mut tcp_rx_storage1, &mut tcp_tx_storage1),
SocketState::<S>::new(&mut sockets, &mut tcp_rx_storage2, &mut tcp_tx_storage2),
SocketState::<S>::new(&mut sockets, &mut tcp_rx_storage3, &mut tcp_tx_storage3),
];
let mut server = Server {
states,
sockets,
net,
net
};
f(&mut server);
}
@ -80,7 +39,7 @@ impl<'a, 'b, S: Default> Server<'a, 'b, S> {
pub fn poll(&mut self, now: Instant) -> Result<(), smoltcp::Error> {
// Poll smoltcp EthernetInterface,
// pass only unexpected smoltcp errors to the caller
match self.net.poll(&mut self.sockets, now) {
match self.net.poll(now) {
Ok(_) => Ok(()),
Err(smoltcp::Error::Malformed) => Ok(()),
Err(smoltcp::Error::Unrecognized) => Ok(()),
@ -89,10 +48,10 @@ impl<'a, 'b, S: Default> Server<'a, 'b, S> {
}
/// Iterate over all sockets managed by this server
pub fn for_each<F: FnMut(SocketRef<TcpSocket>, &mut S)>(&mut self, mut callback: F) {
pub fn for_each<F: FnMut(&mut TcpSocket, &mut S)>(&mut self, mut callback: F) {
for state in &mut self.states {
let socket = self.sockets.get::<TcpSocket>(state.handle);
callback(socket, &mut state.state);
let mut socket = self.net.get_socket::<TcpSocket>(state.handle);
callback(&mut socket, &mut state.state);
}
}