10
10
use defmt_rtt as _;
11
11
use panic_probe as _;
12
12
13
- use smoltcp:: {
14
- iface:: { self , SocketStorage } ,
15
- wire:: { self , IpAddress , Ipv4Address } ,
16
- } ;
13
+ use smoltcp:: wire:: { IpAddress , Ipv4Address } ;
17
14
18
15
mod common;
19
16
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 ) ;
21
19
const MAC : [ u8 ; 6 ] = [ 0x00 , 0x01 , 0x02 , 0x03 , 0x04 , 0x05 ] ;
22
20
23
21
#[ rtic:: app( device = stm32_eth:: stm32, dispatchers = [ SPI1 ] ) ]
@@ -35,18 +33,17 @@ mod app {
35
33
} ;
36
34
37
35
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 } ,
42
39
} ;
43
40
44
- use crate :: NetworkStorage ;
45
-
46
41
#[ local]
47
42
struct Local {
48
- interface : Interface < ' static , & ' static mut EthernetDMA < ' static , ' static > > ,
43
+ interface : Interface ,
49
44
tcp_handle : SocketHandle ,
45
+ dma : EthernetDMA < ' static , ' static > ,
46
+ sockets : SocketSet < ' static > ,
50
47
}
51
48
52
49
#[ shared]
@@ -63,8 +60,9 @@ mod app {
63
60
#[ init( local = [
64
61
rx_ring: [ RxRingEntry ; 2 ] = [ RxRingEntry :: new( ) , RxRingEntry :: new( ) ] ,
65
62
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 ] ,
68
66
] ) ]
69
67
fn init ( cx : init:: Context ) -> ( Shared , Local , init:: Monotonics ) {
70
68
defmt:: info!( "Pre-init" ) ;
@@ -77,51 +75,56 @@ mod app {
77
75
let ( clocks, gpio, ethernet) = crate :: common:: setup_peripherals ( p) ;
78
76
let mono = Systick :: new ( core. SYST , clocks. hclk ( ) . raw ( ) ) ;
79
77
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
+
80
84
defmt:: info!( "Setting up pins" ) ;
81
85
let ( pins, mdio, mdc, _) = crate :: common:: setup_pins ( gpio) ;
82
86
83
87
defmt:: info!( "Configuring ethernet" ) ;
84
88
85
89
let Parts {
86
- dma,
90
+ mut dma,
87
91
mac,
88
92
#[ cfg( feature = "ptp" ) ]
89
93
ptp: _,
90
94
} = stm32_eth:: new_with_mii ( ethernet, rx_ring, tx_ring, clocks, pins, mdio, mdc) . unwrap ( ) ;
91
95
92
- let dma = cx. local . dma . write ( dma) ;
93
-
94
96
defmt:: info!( "Enabling interrupts" ) ;
95
97
dma. enable_interrupt ( ) ;
96
98
97
99
defmt:: info!( "Setting up smoltcp" ) ;
98
- let store = cx. local . storage ;
99
100
100
- let mut routes = smoltcp:: iface:: Routes :: new ( & mut store . routes_cache [ .. ] ) ;
101
+ let mut routes = smoltcp:: iface:: Routes :: new ( ) ;
101
102
routes
102
103
. add_default_ipv4_route ( smoltcp:: wire:: Ipv4Address :: UNSPECIFIED )
103
104
. ok ( ) ;
104
105
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[ ..] ) ;
109
108
110
109
let socket = TcpSocket :: new ( rx_buffer, tx_buffer) ;
111
110
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
+ } ) ;
118
119
119
- let tcp_handle = interface . add_socket ( socket ) ;
120
+ let mut sockets = SocketSet :: new ( & mut socket_storage [ .. ] ) ;
120
121
121
- let socket = interface. get_socket :: < TcpSocket > ( tcp_handle) ;
122
- socket. listen ( crate :: ADDRESS ) . ok ( ) ;
122
+ let tcp_handle = sockets. add ( socket) ;
123
123
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) ;
125
128
126
129
if let Ok ( mut phy) = EthernetPhy :: from_miim ( mac, 0 ) {
127
130
defmt:: info!(
@@ -152,28 +155,36 @@ mod app {
152
155
defmt:: info!( "Not resetting unsupported PHY. Cannot detect link speed." ) ;
153
156
}
154
157
155
- defmt:: info!( "Setup done. Listening at {}" , crate :: ADDRESS ) ;
158
+ defmt:: info!( "Setup done. Listening at {}" , crate :: SOCKET_ADDRESS ) ;
156
159
157
160
(
158
161
Shared { } ,
159
162
Local {
160
163
interface,
161
164
tcp_handle,
165
+ dma,
166
+ sockets,
162
167
} ,
163
168
init:: Monotonics ( mono) ,
164
169
)
165
170
}
166
171
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 ) ]
168
173
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 ( ) ;
172
183
defmt:: debug!( "Got an ethernet interrupt! Reason: {}" , interrupt_reason) ;
173
184
174
- iface. poll ( now_fn ( ) ) . ok ( ) ;
185
+ iface. poll ( now_fn ( ) , & mut dma , sockets ) ;
175
186
176
- let socket = iface . get_socket :: < TcpSocket > ( * tcp_handle) ;
187
+ let socket = sockets . get_mut :: < TcpSocket > ( * tcp_handle) ;
177
188
if let Ok ( recv_bytes) = socket. recv_slice ( buffer) {
178
189
if recv_bytes > 0 {
179
190
socket. send_slice ( & buffer[ ..recv_bytes] ) . ok ( ) ;
@@ -183,50 +194,10 @@ mod app {
183
194
184
195
if !socket. is_listening ( ) && !socket. is_open ( ) || socket. state ( ) == TcpState :: CloseWait {
185
196
socket. abort ( ) ;
186
- socket. listen ( crate :: ADDRESS ) . ok ( ) ;
197
+ socket. listen ( crate :: SOCKET_ADDRESS ) . ok ( ) ;
187
198
defmt:: warn!( "Disconnected... Reopening listening socket." ) ;
188
199
}
189
200
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) ;
231
202
}
232
203
}
0 commit comments