@@ -11,7 +11,7 @@ use defmt_rtt as _;
11
11
use panic_probe as _;
12
12
13
13
use smoltcp:: {
14
- iface:: { self , SocketStorage } ,
14
+ iface:: { self } ,
15
15
wire:: { self , IpAddress , Ipv4Address } ,
16
16
} ;
17
17
@@ -27,21 +27,25 @@ mod app {
27
27
28
28
use systick_monotonic:: Systick ;
29
29
30
+ use core:: mem:: MaybeUninit ;
31
+
30
32
use stm32_eth:: { EthernetDMA , RxRingEntry , TxRingEntry } ;
31
33
32
34
use smoltcp:: {
33
- iface:: { self , Interface , SocketHandle } ,
34
- socket:: TcpSocket ,
35
- socket:: { TcpSocketBuffer , TcpState } ,
35
+ iface:: { self , Interface , SocketHandle , SocketSet , SocketStorage } ,
36
+ socket:: tcp :: Socket as TcpSocket ,
37
+ socket:: tcp :: { SocketBuffer as TcpSocketBuffer , State as TcpState } ,
36
38
wire:: EthernetAddress ,
37
39
} ;
38
40
39
41
use crate :: NetworkStorage ;
40
42
41
43
#[ local]
42
44
struct Local {
43
- interface : Interface < ' static , & ' static mut EthernetDMA < ' static , ' static > > ,
45
+ interface : Interface < ' static > ,
44
46
tcp_handle : SocketHandle ,
47
+ sockets : SocketSet < ' static > ,
48
+ dma : EthernetDMA < ' static , ' static > ,
45
49
}
46
50
47
51
#[ shared]
@@ -58,8 +62,8 @@ mod app {
58
62
#[ init( local = [
59
63
rx_ring: [ RxRingEntry ; 2 ] = [ RxRingEntry :: new( ) , RxRingEntry :: new( ) ] ,
60
64
tx_ring: [ TxRingEntry ; 2 ] = [ TxRingEntry :: new( ) , TxRingEntry :: new( ) ] ,
61
- storage : NetworkStorage = NetworkStorage :: new ( ) ,
62
- dma : core :: mem :: MaybeUninit <EthernetDMA < ' static , ' static >> = core :: mem :: MaybeUninit :: uninit( ) ,
65
+ socket_storage : [ SocketStorage < ' static > ; 4 ] = [ SocketStorage :: EMPTY , SocketStorage :: EMPTY , SocketStorage :: EMPTY , SocketStorage :: EMPTY ] ,
66
+ storage_store : MaybeUninit <NetworkStorage > = MaybeUninit :: uninit( ) ,
63
67
] ) ]
64
68
fn init ( cx : init:: Context ) -> ( Shared , Local , init:: Monotonics ) {
65
69
defmt:: info!( "Pre-init" ) ;
@@ -72,12 +76,15 @@ mod app {
72
76
let ( clocks, gpio, ethernet) = crate :: common:: setup_peripherals ( p) ;
73
77
let mono = Systick :: new ( core. SYST , clocks. hclk ( ) . raw ( ) ) ;
74
78
79
+ let sockets = cx. local . socket_storage ;
80
+ let mut sockets = SocketSet :: new ( & mut sockets[ ..] ) ;
81
+
75
82
defmt:: info!( "Setting up pins" ) ;
76
83
let ( pins, mdio, mdc) = crate :: common:: setup_pins ( gpio) ;
77
84
78
85
defmt:: info!( "Configuring ethernet" ) ;
79
86
80
- let ( dma, mac) = stm32_eth:: new_with_mii (
87
+ let ( mut dma, mac) = stm32_eth:: new_with_mii (
81
88
ethernet. mac ,
82
89
ethernet. mmc ,
83
90
ethernet. dma ,
@@ -92,13 +99,11 @@ mod app {
92
99
)
93
100
. unwrap ( ) ;
94
101
95
- let dma = cx. local . dma . write ( dma) ;
96
-
97
102
defmt:: info!( "Enabling interrupts" ) ;
98
103
dma. enable_interrupt ( ) ;
99
104
100
105
defmt:: info!( "Setting up smoltcp" ) ;
101
- let store = cx. local . storage ;
106
+ let store = cx. local . storage_store . write ( NetworkStorage :: new ( ) ) ;
102
107
103
108
let mut routes = smoltcp:: iface:: Routes :: new ( & mut store. routes_cache [ ..] ) ;
104
109
routes
@@ -112,19 +117,21 @@ mod app {
112
117
113
118
let socket = TcpSocket :: new ( rx_buffer, tx_buffer) ;
114
119
115
- let mut interface = iface:: InterfaceBuilder :: new ( dma , & mut store . sockets [ .. ] )
120
+ let mut interface = iface:: InterfaceBuilder :: new ( )
116
121
. hardware_addr ( EthernetAddress :: from_bytes ( & crate :: MAC ) . into ( ) )
117
122
. neighbor_cache ( neighbor_cache)
118
123
. ip_addrs ( & mut store. ip_addrs [ ..] )
119
124
. routes ( routes)
120
- . finalize ( ) ;
125
+ . finalize ( & mut & mut dma ) ;
121
126
122
- let tcp_handle = interface . add_socket ( socket) ;
127
+ let tcp_handle = sockets . add ( socket) ;
123
128
124
- let socket = interface . get_socket :: < TcpSocket > ( tcp_handle) ;
129
+ let socket = sockets . get_mut :: < TcpSocket > ( tcp_handle) ;
125
130
socket. listen ( crate :: ADDRESS ) . ok ( ) ;
126
131
127
- interface. poll ( now_fn ( ) ) . unwrap ( ) ;
132
+ interface
133
+ . poll ( now_fn ( ) , & mut & mut dma, & mut sockets)
134
+ . unwrap ( ) ;
128
135
129
136
if let Ok ( mut phy) = EthernetPhy :: from_miim ( mac, 0 ) {
130
137
defmt:: info!(
@@ -144,21 +151,29 @@ mod app {
144
151
Local {
145
152
interface,
146
153
tcp_handle,
154
+ sockets,
155
+ dma,
147
156
} ,
148
157
init:: Monotonics ( mono) ,
149
158
)
150
159
}
151
160
152
- #[ task( binds = ETH , local = [ interface, tcp_handle, data: [ u8 ; 512 ] = [ 0u8 ; 512 ] ] , priority = 2 ) ]
161
+ #[ task( binds = ETH , local = [ interface, tcp_handle, sockets , dma , data: [ u8 ; 512 ] = [ 0u8 ; 512 ] ] , priority = 2 ) ]
153
162
fn eth_interrupt ( cx : eth_interrupt:: Context ) {
154
- let ( iface, tcp_handle, buffer) = ( cx. local . interface , cx. local . tcp_handle , cx. local . data ) ;
155
-
156
- let interrupt_reason = iface. device_mut ( ) . interrupt_handler ( ) ;
163
+ let ( iface, tcp_handle, buffer, sockets, mut dma) = (
164
+ cx. local . interface ,
165
+ cx. local . tcp_handle ,
166
+ cx. local . data ,
167
+ cx. local . sockets ,
168
+ cx. local . dma ,
169
+ ) ;
170
+
171
+ let interrupt_reason = dma. interrupt_handler ( ) ;
157
172
defmt:: debug!( "Got an ethernet interrupt! Reason: {}" , interrupt_reason) ;
158
173
159
- iface. poll ( now_fn ( ) ) . ok ( ) ;
174
+ iface. poll ( now_fn ( ) , & mut dma , sockets ) . ok ( ) ;
160
175
161
- let socket = iface . get_socket :: < TcpSocket > ( * tcp_handle) ;
176
+ let socket = sockets . get_mut :: < TcpSocket > ( * tcp_handle) ;
162
177
if let Ok ( recv_bytes) = socket. recv_slice ( buffer) {
163
178
if recv_bytes > 0 {
164
179
socket. send_slice ( & buffer[ ..recv_bytes] ) . ok ( ) ;
@@ -172,14 +187,13 @@ mod app {
172
187
defmt:: warn!( "Disconnected... Reopening listening socket." ) ;
173
188
}
174
189
175
- iface. poll ( now_fn ( ) ) . ok ( ) ;
190
+ iface. poll ( now_fn ( ) , & mut dma , sockets ) . ok ( ) ;
176
191
}
177
192
}
178
193
179
194
/// All storage required for networking
180
195
pub struct NetworkStorage {
181
196
pub ip_addrs : [ wire:: IpCidr ; 1 ] ,
182
- pub sockets : [ iface:: SocketStorage < ' static > ; 1 ] ,
183
197
pub tcp_socket_storage : TcpSocketStorage ,
184
198
pub neighbor_cache : [ Option < ( wire:: IpAddress , iface:: Neighbor ) > ; 8 ] ,
185
199
pub routes_cache : [ Option < ( wire:: IpCidr , iface:: Route ) > ; 8 ] ,
@@ -194,7 +208,6 @@ impl NetworkStorage {
194
208
ip_addrs : [ Self :: IP_INIT ] ,
195
209
neighbor_cache : [ None ; 8 ] ,
196
210
routes_cache : [ None ; 8 ] ,
197
- sockets : [ SocketStorage :: EMPTY ; 1 ] ,
198
211
tcp_socket_storage : TcpSocketStorage :: new ( ) ,
199
212
}
200
213
}
0 commit comments