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 ] ) ]
@@ -28,25 +26,20 @@ mod app {
28
26
use ieee802_3_miim:: { phy:: PhySpeed , Phy } ;
29
27
use systick_monotonic:: Systick ;
30
28
31
- use stm32_eth:: {
32
- dma:: { EthernetDMA , RxDescriptor , RxDescriptorRing , TxDescriptor , TxDescriptorRing } ,
33
- mac:: Speed ,
34
- Parts ,
35
- } ;
29
+ use stm32_eth:: { dma:: EthernetDMA , mac:: Speed , Parts } ;
36
30
37
31
use smoltcp:: {
38
- iface:: { self , Interface , SocketHandle } ,
39
- socket:: TcpSocket ,
40
- socket:: { TcpSocketBuffer , TcpState } ,
41
- wire:: EthernetAddress ,
32
+ iface:: { self , Interface , SocketHandle , SocketSet , SocketStorage } ,
33
+ socket:: tcp:: { Socket as TcpSocket , SocketBuffer as TcpSocketBuffer , State as TcpState } ,
34
+ wire:: { EthernetAddress , IpCidr , Ipv4Cidr } ,
42
35
} ;
43
36
44
- use crate :: NetworkStorage ;
45
-
46
37
#[ local]
47
38
struct Local {
48
- interface : Interface < ' static , & ' static mut EthernetDMA < ' static , ' static > > ,
39
+ interface : Interface ,
49
40
tcp_handle : SocketHandle ,
41
+ dma : EthernetDMA < ' static , ' static > ,
42
+ sockets : SocketSet < ' static > ,
50
43
}
51
44
52
45
#[ shared]
@@ -61,69 +54,70 @@ mod app {
61
54
}
62
55
63
56
#[ init( local = [
64
- rx_desc: [ RxDescriptor ; 2 ] = [ RxDescriptor :: new( ) ; 2 ] ,
65
- tx_desc: [ TxDescriptor ; 2 ] = [ TxDescriptor :: new( ) ; 2 ] ,
66
- rx_buffers: [ [ u8 ; 1522 ] ; 2 ] = [ [ 0u8 ; stm32_eth:: MTU ] ; 2 ] ,
67
- tx_buffers: [ [ u8 ; 1522 ] ; 2 ] = [ [ 0u8 ; stm32_eth:: MTU ] ; 2 ] ,
68
- storage: NetworkStorage = NetworkStorage :: new( ) ,
69
- dma: core:: mem:: MaybeUninit <EthernetDMA <' static , ' static >> = core:: mem:: MaybeUninit :: uninit( ) ,
57
+ rx_storage: [ u8 ; 512 ] = [ 0u8 ; 512 ] ,
58
+ tx_storage: [ u8 ; 512 ] = [ 0u8 ; 512 ] ,
59
+ socket_storage: [ SocketStorage <' static >; 1 ] = [ SocketStorage :: EMPTY ; 1 ] ,
70
60
] ) ]
71
61
fn init ( cx : init:: Context ) -> ( Shared , Local , init:: Monotonics ) {
72
62
defmt:: info!( "Pre-init" ) ;
73
63
let core = cx. core ;
74
64
let p = cx. device ;
75
65
76
- let rx_ring = RxDescriptorRing :: new ( cx. local . rx_desc , cx. local . rx_buffers ) ;
77
- let tx_ring = TxDescriptorRing :: new ( cx. local . tx_desc , cx. local . tx_buffers ) ;
66
+ let ( tx_ring, rx_ring) = crate :: common:: setup_rings ( ) ;
78
67
79
68
let ( clocks, gpio, ethernet) = crate :: common:: setup_peripherals ( p) ;
80
69
let mono = Systick :: new ( core. SYST , clocks. hclk ( ) . raw ( ) ) ;
81
70
71
+ let ( rx_storage, tx_storage, socket_storage) = (
72
+ cx. local . rx_storage ,
73
+ cx. local . tx_storage ,
74
+ cx. local . socket_storage ,
75
+ ) ;
76
+
82
77
defmt:: info!( "Setting up pins" ) ;
83
78
let ( pins, mdio, mdc, _) = crate :: common:: setup_pins ( gpio) ;
84
79
85
80
defmt:: info!( "Configuring ethernet" ) ;
86
81
87
82
let Parts {
88
- dma,
83
+ mut dma,
89
84
mac,
90
85
#[ cfg( feature = "ptp" ) ]
91
86
ptp: _,
92
87
} = stm32_eth:: new_with_mii ( ethernet, rx_ring, tx_ring, clocks, pins, mdio, mdc) . unwrap ( ) ;
93
88
94
- let dma = cx. local . dma . write ( dma) ;
95
-
96
89
defmt:: info!( "Enabling interrupts" ) ;
97
90
dma. enable_interrupt ( ) ;
98
91
99
92
defmt:: info!( "Setting up smoltcp" ) ;
100
- let store = cx. local . storage ;
101
93
102
- let mut routes = smoltcp:: iface:: Routes :: new ( & mut store . routes_cache [ .. ] ) ;
94
+ let mut routes = smoltcp:: iface:: Routes :: new ( ) ;
103
95
routes
104
96
. add_default_ipv4_route ( smoltcp:: wire:: Ipv4Address :: UNSPECIFIED )
105
97
. ok ( ) ;
106
98
107
- let neighbor_cache = smoltcp:: iface:: NeighborCache :: new ( & mut store. neighbor_cache [ ..] ) ;
108
-
109
- let rx_buffer = TcpSocketBuffer :: new ( & mut store. tcp_socket_storage . rx_storage [ ..] ) ;
110
- let tx_buffer = TcpSocketBuffer :: new ( & mut store. tcp_socket_storage . tx_storage [ ..] ) ;
99
+ let rx_buffer = TcpSocketBuffer :: new ( & mut rx_storage[ ..] ) ;
100
+ let tx_buffer = TcpSocketBuffer :: new ( & mut tx_storage[ ..] ) ;
111
101
112
102
let socket = TcpSocket :: new ( rx_buffer, tx_buffer) ;
113
103
114
- let mut interface = iface:: InterfaceBuilder :: new ( dma, & mut store. sockets [ ..] )
115
- . hardware_addr ( EthernetAddress :: from_bytes ( & crate :: MAC ) . into ( ) )
116
- . neighbor_cache ( neighbor_cache)
117
- . ip_addrs ( & mut store. ip_addrs [ ..] )
118
- . routes ( routes)
119
- . finalize ( ) ;
104
+ let mut config = iface:: Config :: new ( ) ;
105
+ config. hardware_addr = Some ( EthernetAddress :: from_bytes ( & crate :: MAC ) . into ( ) ) ;
120
106
121
- let tcp_handle = interface. add_socket ( socket) ;
107
+ let mut interface = Interface :: new ( config, & mut & mut dma) ;
108
+ interface. update_ip_addrs ( |addr| {
109
+ addr. push ( IpCidr :: Ipv4 ( Ipv4Cidr :: new ( crate :: IP_ADDRESS , 24 ) ) )
110
+ . ok ( ) ;
111
+ } ) ;
122
112
123
- let socket = interface. get_socket :: < TcpSocket > ( tcp_handle) ;
124
- socket. listen ( crate :: ADDRESS ) . ok ( ) ;
113
+ let mut sockets = SocketSet :: new ( & mut socket_storage[ ..] ) ;
125
114
126
- interface. poll ( now_fn ( ) ) . unwrap ( ) ;
115
+ let tcp_handle = sockets. add ( socket) ;
116
+
117
+ let socket = sockets. get_mut :: < TcpSocket > ( tcp_handle) ;
118
+ socket. listen ( crate :: SOCKET_ADDRESS ) . ok ( ) ;
119
+
120
+ interface. poll ( now_fn ( ) , & mut & mut dma, & mut sockets) ;
127
121
128
122
if let Ok ( mut phy) = EthernetPhy :: from_miim ( mac, 0 ) {
129
123
defmt:: info!(
@@ -154,28 +148,36 @@ mod app {
154
148
defmt:: info!( "Not resetting unsupported PHY. Cannot detect link speed." ) ;
155
149
}
156
150
157
- defmt:: info!( "Setup done. Listening at {}" , crate :: ADDRESS ) ;
151
+ defmt:: info!( "Setup done. Listening at {}" , crate :: SOCKET_ADDRESS ) ;
158
152
159
153
(
160
154
Shared { } ,
161
155
Local {
162
156
interface,
163
157
tcp_handle,
158
+ dma,
159
+ sockets,
164
160
} ,
165
161
init:: Monotonics ( mono) ,
166
162
)
167
163
}
168
164
169
- #[ task( binds = ETH , local = [ interface, tcp_handle, data: [ u8 ; 512 ] = [ 0u8 ; 512 ] ] , priority = 2 ) ]
165
+ #[ task( binds = ETH , local = [ interface, tcp_handle, dma , sockets , data: [ u8 ; 512 ] = [ 0u8 ; 512 ] ] , priority = 2 ) ]
170
166
fn eth_interrupt ( cx : eth_interrupt:: Context ) {
171
- let ( iface, tcp_handle, buffer) = ( cx. local . interface , cx. local . tcp_handle , cx. local . data ) ;
172
-
173
- let interrupt_reason = iface. device_mut ( ) . interrupt_handler ( ) ;
167
+ let ( iface, tcp_handle, buffer, sockets, mut dma) = (
168
+ cx. local . interface ,
169
+ cx. local . tcp_handle ,
170
+ cx. local . data ,
171
+ cx. local . sockets ,
172
+ cx. local . dma ,
173
+ ) ;
174
+
175
+ let interrupt_reason = dma. interrupt_handler ( ) ;
174
176
defmt:: debug!( "Got an ethernet interrupt! Reason: {}" , interrupt_reason) ;
175
177
176
- iface. poll ( now_fn ( ) ) . ok ( ) ;
178
+ iface. poll ( now_fn ( ) , & mut dma , sockets ) ;
177
179
178
- let socket = iface . get_socket :: < TcpSocket > ( * tcp_handle) ;
180
+ let socket = sockets . get_mut :: < TcpSocket > ( * tcp_handle) ;
179
181
if let Ok ( recv_bytes) = socket. recv_slice ( buffer) {
180
182
if recv_bytes > 0 {
181
183
socket. send_slice ( & buffer[ ..recv_bytes] ) . ok ( ) ;
@@ -185,50 +187,10 @@ mod app {
185
187
186
188
if !socket. is_listening ( ) && !socket. is_open ( ) || socket. state ( ) == TcpState :: CloseWait {
187
189
socket. abort ( ) ;
188
- socket. listen ( crate :: ADDRESS ) . ok ( ) ;
190
+ socket. listen ( crate :: SOCKET_ADDRESS ) . ok ( ) ;
189
191
defmt:: warn!( "Disconnected... Reopening listening socket." ) ;
190
192
}
191
193
192
- iface. poll ( now_fn ( ) ) . ok ( ) ;
193
- }
194
- }
195
-
196
- /// All storage required for networking
197
- pub struct NetworkStorage {
198
- pub ip_addrs : [ wire:: IpCidr ; 1 ] ,
199
- pub sockets : [ iface:: SocketStorage < ' static > ; 1 ] ,
200
- pub tcp_socket_storage : TcpSocketStorage ,
201
- pub neighbor_cache : [ Option < ( wire:: IpAddress , iface:: Neighbor ) > ; 8 ] ,
202
- pub routes_cache : [ Option < ( wire:: IpCidr , iface:: Route ) > ; 8 ] ,
203
- }
204
-
205
- impl NetworkStorage {
206
- const IP_INIT : wire:: IpCidr =
207
- wire:: IpCidr :: Ipv4 ( wire:: Ipv4Cidr :: new ( wire:: Ipv4Address :: new ( 10 , 0 , 0 , 1 ) , 24 ) ) ;
208
-
209
- pub const fn new ( ) -> Self {
210
- NetworkStorage {
211
- ip_addrs : [ Self :: IP_INIT ] ,
212
- neighbor_cache : [ None ; 8 ] ,
213
- routes_cache : [ None ; 8 ] ,
214
- sockets : [ SocketStorage :: EMPTY ; 1 ] ,
215
- tcp_socket_storage : TcpSocketStorage :: new ( ) ,
216
- }
217
- }
218
- }
219
-
220
- /// Storage of TCP sockets
221
- #[ derive( Copy , Clone ) ]
222
- pub struct TcpSocketStorage {
223
- rx_storage : [ u8 ; 512 ] ,
224
- tx_storage : [ u8 ; 512 ] ,
225
- }
226
-
227
- impl TcpSocketStorage {
228
- const fn new ( ) -> Self {
229
- Self {
230
- rx_storage : [ 0 ; 512 ] ,
231
- tx_storage : [ 0 ; 512 ] ,
232
- }
194
+ iface. poll ( now_fn ( ) , & mut dma, sockets) ;
233
195
}
234
196
}
0 commit comments