Skip to content

Commit b1616f7

Browse files
Merge pull request #71 from stm32-rs/update-smoltcp
Update smoltcp
2 parents 2ee46e1 + 967314e commit b1616f7

File tree

10 files changed

+196
-191
lines changed

10 files changed

+196
-191
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
## Unreleased
2-
No changes yet.
2+
* Update to `smoltcp` v0.9 [#71](https://github.com/stm32-rs/stm32-eth/pull/71).
33

44
## [0.4.0](https://github.com/stm32-rs/stm32-eth/tree/v0.4.0)
55
* Remove the `smi` feature and always enable miim/smi. Use `ieee802_3_miim` for SMI access [#45](https://github.com/stm32-rs/stm32-eth/pull/45)

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ log = { version = "0.4", optional = true }
3131
defmt = { version = "0.3", optional = true }
3232

3333
[dependencies.smoltcp]
34-
version = "0.8.2"
34+
version = "0.9"
3535
default-features = false
3636
optional = true
3737

@@ -72,7 +72,7 @@ cortex-m-rtic = "1.0"
7272
defmt-rtt = "0.4"
7373
panic-probe = { version = "0.3", features = [ "print-defmt" ] }
7474
systick-monotonic = "1.0"
75-
smoltcp = { version = "0.8", features = [ "medium-ethernet", "proto-ipv4", "socket-udp", "socket-tcp", "defmt" ], default-features = false }
75+
smoltcp = { version = "0.9", features = [ "medium-ethernet", "proto-ipv4", "socket-udp", "socket-tcp", "defmt" ], default-features = false }
7676

7777
[[example]]
7878
name = "pktgen"

examples/common.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ pub fn setup_peripherals(p: stm32_eth::stm32::Peripherals) -> (Clocks, Gpio, Par
3232
{
3333
let rcc = p.RCC.constrain();
3434

35-
let clocks = rcc.cfgr.sysclk(100.MHz()).hclk(100.MHz());
35+
let clocks = rcc.cfgr.sysclk(96.MHz()).hclk(96.MHz());
3636

3737
#[cfg(feature = "stm32f4xx-hal")]
3838
let clocks = {

examples/ip.rs

Lines changed: 35 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,21 @@
44
//! For build and run instructions, see README.md
55
//!
66
//! This example starts a TCP listening server at the address 10.0.0.1/24, on port 80, that
7-
//! should transmit `Hello` to any connecting client, and then close the connection.
7+
//! should transmit `hello` to any connecting client, and then close the connection.
88
99
use defmt_rtt as _;
1010
use panic_probe as _;
1111

1212
use cortex_m_rt::{entry, exception};
13+
use smoltcp::iface::{Config, Interface, SocketSet, SocketStorage};
1314
use stm32_eth::stm32::{interrupt, CorePeripherals, Peripherals, SYST};
1415

1516
use core::cell::RefCell;
1617
use cortex_m::interrupt::Mutex;
1718

18-
use smoltcp::iface::{InterfaceBuilder, NeighborCache};
19-
use smoltcp::socket::{TcpSocket, TcpSocketBuffer};
19+
use smoltcp::socket::tcp::{Socket as TcpSocket, SocketBuffer as TcpSocketBuffer};
2020
use smoltcp::time::Instant;
21-
use smoltcp::wire::{EthernetAddress, IpAddress, IpCidr, Ipv4Address};
21+
use smoltcp::wire::{EthernetAddress, IpCidr, Ipv4Address, Ipv4Cidr};
2222

2323
pub mod common;
2424

@@ -27,6 +27,7 @@ use stm32_eth::{
2727
Parts,
2828
};
2929

30+
const IP_ADDRESS: Ipv4Address = Ipv4Address::new(10, 0, 0, 1);
3031
const SRC_MAC: [u8; 6] = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF];
3132

3233
static TIME: Mutex<RefCell<u64>> = Mutex::new(RefCell::new(0));
@@ -62,27 +63,26 @@ fn main() -> ! {
6263
.unwrap();
6364
dma.enable_interrupt();
6465

65-
let local_addr = Ipv4Address::new(10, 0, 0, 1);
66-
let ip_addr = IpCidr::new(IpAddress::from(local_addr), 24);
67-
let mut ip_addrs = [ip_addr];
68-
let mut neighbor_storage = [None; 16];
69-
let neighbor_cache = NeighborCache::new(&mut neighbor_storage[..]);
7066
let ethernet_addr = EthernetAddress(SRC_MAC);
7167

72-
let mut sockets: [_; 1] = Default::default();
73-
let mut iface = InterfaceBuilder::new(&mut dma, &mut sockets[..])
74-
.hardware_addr(ethernet_addr.into())
75-
.ip_addrs(&mut ip_addrs[..])
76-
.neighbor_cache(neighbor_cache)
77-
.finalize();
68+
let mut config = Config::new();
69+
config.hardware_addr = Some(ethernet_addr.into());
70+
let mut iface = Interface::new(config, &mut &mut dma);
71+
72+
iface.update_ip_addrs(|addr| {
73+
addr.push(IpCidr::Ipv4(Ipv4Cidr::new(IP_ADDRESS, 24))).ok();
74+
});
75+
76+
let mut sockets = [SocketStorage::EMPTY];
77+
let mut sockets = SocketSet::new(&mut sockets[..]);
7878

7979
let mut server_rx_buffer = [0; 512];
8080
let mut server_tx_buffer = [0; 512];
8181
let server_socket = TcpSocket::new(
8282
TcpSocketBuffer::new(&mut server_rx_buffer[..]),
8383
TcpSocketBuffer::new(&mut server_tx_buffer[..]),
8484
);
85-
let server_handle = iface.add_socket(server_socket);
85+
let server_handle = sockets.add(server_socket);
8686

8787
loop {
8888
let time: u64 = cortex_m::interrupt::free(|cs| *TIME.borrow(cs).borrow());
@@ -91,31 +91,43 @@ fn main() -> ! {
9191
*eth_pending = false;
9292
});
9393

94-
iface.poll(Instant::from_millis(time as i64)).ok();
94+
iface.poll(
95+
Instant::from_millis(time as i64),
96+
&mut &mut dma,
97+
&mut sockets,
98+
);
9599

96-
let socket = iface.get_socket::<TcpSocket>(server_handle);
100+
let socket = sockets.get_mut::<TcpSocket>(server_handle);
97101

98102
if !socket.is_listening() && !socket.is_open() {
99103
socket.abort();
100104
if let Err(e) = socket.listen(80) {
101105
defmt::error!("TCP listen error: {:?}", e)
102106
} else {
103-
defmt::info!("Listening at {}:80...", ip_addr);
107+
defmt::info!("Listening at {}:80...", IP_ADDRESS);
104108
}
105109
} else {
106110
match socket.send_slice(b"hello\n") {
107111
Ok(_) => {
108-
while iface.get_socket::<TcpSocket>(server_handle).send_queue() != 0 {
112+
while sockets.get::<TcpSocket>(server_handle).send_queue() != 0 {
109113
// Poll to get the message out of the door
110-
iface.poll(Instant::from_millis(time as i64 + 1)).ok();
114+
iface.poll(
115+
Instant::from_millis(time as i64 + 1),
116+
&mut &mut dma,
117+
&mut sockets,
118+
);
111119
}
112120

113121
// Abort the connection
114-
let socket = iface.get_socket::<TcpSocket>(server_handle);
122+
let socket = sockets.get_mut::<TcpSocket>(server_handle);
115123
socket.abort();
116124
defmt::info!("Transmitted hello! Closing socket...");
117125

118-
iface.poll(Instant::from_millis(time as i64 + 1)).ok();
126+
iface.poll(
127+
Instant::from_millis(time as i64),
128+
&mut &mut dma,
129+
&mut sockets,
130+
);
119131
}
120132
Err(_) => {}
121133
}

examples/rtic-echo.rs

Lines changed: 53 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,12 @@
1010
use defmt_rtt as _;
1111
use panic_probe as _;
1212

13-
use smoltcp::{
14-
iface::{self, SocketStorage},
15-
wire::{self, IpAddress, Ipv4Address},
16-
};
13+
use smoltcp::wire::{IpAddress, Ipv4Address};
1714

1815
mod common;
1916

20-
const ADDRESS: (IpAddress, u16) = (IpAddress::Ipv4(Ipv4Address::new(10, 0, 0, 1)), 1337);
17+
const IP_ADDRESS: Ipv4Address = Ipv4Address::new(10, 0, 0, 1);
18+
const SOCKET_ADDRESS: (IpAddress, u16) = (IpAddress::Ipv4(IP_ADDRESS), 1337);
2119
const MAC: [u8; 6] = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05];
2220

2321
#[rtic::app(device = stm32_eth::stm32, dispatchers = [SPI1])]
@@ -35,18 +33,17 @@ mod app {
3533
};
3634

3735
use smoltcp::{
38-
iface::{self, Interface, SocketHandle},
39-
socket::TcpSocket,
40-
socket::{TcpSocketBuffer, TcpState},
41-
wire::EthernetAddress,
36+
iface::{self, Interface, SocketHandle, SocketSet, SocketStorage},
37+
socket::tcp::{Socket as TcpSocket, SocketBuffer as TcpSocketBuffer, State as TcpState},
38+
wire::{EthernetAddress, IpCidr, Ipv4Cidr},
4239
};
4340

44-
use crate::NetworkStorage;
45-
4641
#[local]
4742
struct Local {
48-
interface: Interface<'static, &'static mut EthernetDMA<'static, 'static>>,
43+
interface: Interface,
4944
tcp_handle: SocketHandle,
45+
dma: EthernetDMA<'static, 'static>,
46+
sockets: SocketSet<'static>,
5047
}
5148

5249
#[shared]
@@ -63,8 +60,9 @@ mod app {
6360
#[init(local = [
6461
rx_ring: [RxRingEntry; 2] = [RxRingEntry::new(),RxRingEntry::new()],
6562
tx_ring: [TxRingEntry; 2] = [TxRingEntry::new(),TxRingEntry::new()],
66-
storage: NetworkStorage = NetworkStorage::new(),
67-
dma: core::mem::MaybeUninit<EthernetDMA<'static, 'static>> = core::mem::MaybeUninit::uninit(),
63+
rx_storage: [u8; 512] = [0u8; 512],
64+
tx_storage: [u8; 512] = [0u8; 512],
65+
socket_storage: [SocketStorage<'static>; 1] = [SocketStorage::EMPTY; 1],
6866
])]
6967
fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) {
7068
defmt::info!("Pre-init");
@@ -77,51 +75,56 @@ mod app {
7775
let (clocks, gpio, ethernet) = crate::common::setup_peripherals(p);
7876
let mono = Systick::new(core.SYST, clocks.hclk().raw());
7977

78+
let (rx_storage, tx_storage, socket_storage) = (
79+
cx.local.rx_storage,
80+
cx.local.tx_storage,
81+
cx.local.socket_storage,
82+
);
83+
8084
defmt::info!("Setting up pins");
8185
let (pins, mdio, mdc, _) = crate::common::setup_pins(gpio);
8286

8387
defmt::info!("Configuring ethernet");
8488

8589
let Parts {
86-
dma,
90+
mut dma,
8791
mac,
8892
#[cfg(feature = "ptp")]
8993
ptp: _,
9094
} = stm32_eth::new_with_mii(ethernet, rx_ring, tx_ring, clocks, pins, mdio, mdc).unwrap();
9195

92-
let dma = cx.local.dma.write(dma);
93-
9496
defmt::info!("Enabling interrupts");
9597
dma.enable_interrupt();
9698

9799
defmt::info!("Setting up smoltcp");
98-
let store = cx.local.storage;
99100

100-
let mut routes = smoltcp::iface::Routes::new(&mut store.routes_cache[..]);
101+
let mut routes = smoltcp::iface::Routes::new();
101102
routes
102103
.add_default_ipv4_route(smoltcp::wire::Ipv4Address::UNSPECIFIED)
103104
.ok();
104105

105-
let neighbor_cache = smoltcp::iface::NeighborCache::new(&mut store.neighbor_cache[..]);
106-
107-
let rx_buffer = TcpSocketBuffer::new(&mut store.tcp_socket_storage.rx_storage[..]);
108-
let tx_buffer = TcpSocketBuffer::new(&mut store.tcp_socket_storage.tx_storage[..]);
106+
let rx_buffer = TcpSocketBuffer::new(&mut rx_storage[..]);
107+
let tx_buffer = TcpSocketBuffer::new(&mut tx_storage[..]);
109108

110109
let socket = TcpSocket::new(rx_buffer, tx_buffer);
111110

112-
let mut interface = iface::InterfaceBuilder::new(dma, &mut store.sockets[..])
113-
.hardware_addr(EthernetAddress::from_bytes(&crate::MAC).into())
114-
.neighbor_cache(neighbor_cache)
115-
.ip_addrs(&mut store.ip_addrs[..])
116-
.routes(routes)
117-
.finalize();
111+
let mut config = iface::Config::new();
112+
config.hardware_addr = Some(EthernetAddress::from_bytes(&crate::MAC).into());
113+
114+
let mut interface = Interface::new(config, &mut &mut dma);
115+
interface.update_ip_addrs(|addr| {
116+
addr.push(IpCidr::Ipv4(Ipv4Cidr::new(crate::IP_ADDRESS, 24)))
117+
.ok();
118+
});
118119

119-
let tcp_handle = interface.add_socket(socket);
120+
let mut sockets = SocketSet::new(&mut socket_storage[..]);
120121

121-
let socket = interface.get_socket::<TcpSocket>(tcp_handle);
122-
socket.listen(crate::ADDRESS).ok();
122+
let tcp_handle = sockets.add(socket);
123123

124-
interface.poll(now_fn()).unwrap();
124+
let socket = sockets.get_mut::<TcpSocket>(tcp_handle);
125+
socket.listen(crate::SOCKET_ADDRESS).ok();
126+
127+
interface.poll(now_fn(), &mut &mut dma, &mut sockets);
125128

126129
if let Ok(mut phy) = EthernetPhy::from_miim(mac, 0) {
127130
defmt::info!(
@@ -152,28 +155,36 @@ mod app {
152155
defmt::info!("Not resetting unsupported PHY. Cannot detect link speed.");
153156
}
154157

155-
defmt::info!("Setup done. Listening at {}", crate::ADDRESS);
158+
defmt::info!("Setup done. Listening at {}", crate::SOCKET_ADDRESS);
156159

157160
(
158161
Shared {},
159162
Local {
160163
interface,
161164
tcp_handle,
165+
dma,
166+
sockets,
162167
},
163168
init::Monotonics(mono),
164169
)
165170
}
166171

167-
#[task(binds = ETH, local = [interface, tcp_handle, data: [u8; 512] = [0u8; 512]], priority = 2)]
172+
#[task(binds = ETH, local = [interface, tcp_handle, dma, sockets, data: [u8; 512] = [0u8; 512]], priority = 2)]
168173
fn eth_interrupt(cx: eth_interrupt::Context) {
169-
let (iface, tcp_handle, buffer) = (cx.local.interface, cx.local.tcp_handle, cx.local.data);
170-
171-
let interrupt_reason = iface.device_mut().interrupt_handler();
174+
let (iface, tcp_handle, buffer, sockets, mut dma) = (
175+
cx.local.interface,
176+
cx.local.tcp_handle,
177+
cx.local.data,
178+
cx.local.sockets,
179+
cx.local.dma,
180+
);
181+
182+
let interrupt_reason = dma.interrupt_handler();
172183
defmt::debug!("Got an ethernet interrupt! Reason: {}", interrupt_reason);
173184

174-
iface.poll(now_fn()).ok();
185+
iface.poll(now_fn(), &mut dma, sockets);
175186

176-
let socket = iface.get_socket::<TcpSocket>(*tcp_handle);
187+
let socket = sockets.get_mut::<TcpSocket>(*tcp_handle);
177188
if let Ok(recv_bytes) = socket.recv_slice(buffer) {
178189
if recv_bytes > 0 {
179190
socket.send_slice(&buffer[..recv_bytes]).ok();
@@ -183,50 +194,10 @@ mod app {
183194

184195
if !socket.is_listening() && !socket.is_open() || socket.state() == TcpState::CloseWait {
185196
socket.abort();
186-
socket.listen(crate::ADDRESS).ok();
197+
socket.listen(crate::SOCKET_ADDRESS).ok();
187198
defmt::warn!("Disconnected... Reopening listening socket.");
188199
}
189200

190-
iface.poll(now_fn()).ok();
191-
}
192-
}
193-
194-
/// All storage required for networking
195-
pub struct NetworkStorage {
196-
pub ip_addrs: [wire::IpCidr; 1],
197-
pub sockets: [iface::SocketStorage<'static>; 1],
198-
pub tcp_socket_storage: TcpSocketStorage,
199-
pub neighbor_cache: [Option<(wire::IpAddress, iface::Neighbor)>; 8],
200-
pub routes_cache: [Option<(wire::IpCidr, iface::Route)>; 8],
201-
}
202-
203-
impl NetworkStorage {
204-
const IP_INIT: wire::IpCidr =
205-
wire::IpCidr::Ipv4(wire::Ipv4Cidr::new(wire::Ipv4Address::new(10, 0, 0, 1), 24));
206-
207-
pub const fn new() -> Self {
208-
NetworkStorage {
209-
ip_addrs: [Self::IP_INIT],
210-
neighbor_cache: [None; 8],
211-
routes_cache: [None; 8],
212-
sockets: [SocketStorage::EMPTY; 1],
213-
tcp_socket_storage: TcpSocketStorage::new(),
214-
}
215-
}
216-
}
217-
218-
/// Storage of TCP sockets
219-
#[derive(Copy, Clone)]
220-
pub struct TcpSocketStorage {
221-
rx_storage: [u8; 512],
222-
tx_storage: [u8; 512],
223-
}
224-
225-
impl TcpSocketStorage {
226-
const fn new() -> Self {
227-
Self {
228-
rx_storage: [0; 512],
229-
tx_storage: [0; 512],
230-
}
201+
iface.poll(now_fn(), &mut dma, sockets);
231202
}
232203
}

0 commit comments

Comments
 (0)