aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2023-08-17 00:57:54 +0200
committerDario Nieuwenhuis <[email protected]>2023-08-17 01:03:12 +0200
commit1cb76e0d99f8da12891491b31176c8247a7a81a4 (patch)
treeb8a4e7f1969cb836cd52c2aa54f7e7b4d0371a90
parentef7523e5b7a36f0f15b77d4e673afdda0df51f3a (diff)
net-esp-hosted: enable heartbeats from esp32 to detect if it crashes.
-rw-r--r--embassy-net-esp-hosted/src/control.rs10
-rw-r--r--embassy-net-esp-hosted/src/lib.rs21
2 files changed, 25 insertions, 6 deletions
diff --git a/embassy-net-esp-hosted/src/control.rs b/embassy-net-esp-hosted/src/control.rs
index b722bdd71..6cd57f68a 100644
--- a/embassy-net-esp-hosted/src/control.rs
+++ b/embassy-net-esp-hosted/src/control.rs
@@ -53,6 +53,9 @@ impl<'a> Control<'a> {
53 debug!("wait for init event..."); 53 debug!("wait for init event...");
54 self.shared.init_wait().await; 54 self.shared.init_wait().await;
55 55
56 debug!("set heartbeat");
57 self.set_heartbeat(10).await?;
58
56 debug!("set wifi mode"); 59 debug!("set wifi mode");
57 self.set_wifi_mode(WifiMode::Sta as _).await?; 60 self.set_wifi_mode(WifiMode::Sta as _).await?;
58 61
@@ -83,6 +86,13 @@ impl<'a> Control<'a> {
83 Ok(()) 86 Ok(())
84 } 87 }
85 88
89 /// duration in seconds, clamped to [10, 3600]
90 async fn set_heartbeat(&mut self, duration: u32) -> Result<(), Error> {
91 let req = proto::CtrlMsgReqConfigHeartbeat { enable: true, duration };
92 ioctl!(self, ReqConfigHeartbeat, RespConfigHeartbeat, req, resp);
93 Ok(())
94 }
95
86 async fn get_mac_addr(&mut self) -> Result<[u8; 6], Error> { 96 async fn get_mac_addr(&mut self) -> Result<[u8; 6], Error> {
87 let req = proto::CtrlMsgReqGetMacAddress { 97 let req = proto::CtrlMsgReqGetMacAddress {
88 mode: WifiMode::Sta as _, 98 mode: WifiMode::Sta as _,
diff --git a/embassy-net-esp-hosted/src/lib.rs b/embassy-net-esp-hosted/src/lib.rs
index c2d9d6097..4a318b20d 100644
--- a/embassy-net-esp-hosted/src/lib.rs
+++ b/embassy-net-esp-hosted/src/lib.rs
@@ -1,7 +1,8 @@
1#![no_std] 1#![no_std]
2 2
3use embassy_futures::select::{select3, Either3}; 3use embassy_futures::select::{select4, Either4};
4use embassy_net_driver_channel as ch; 4use embassy_net_driver_channel as ch;
5use embassy_net_driver_channel::driver::LinkState;
5use embassy_time::{Duration, Instant, Timer}; 6use embassy_time::{Duration, Instant, Timer};
6use embedded_hal::digital::{InputPin, OutputPin}; 7use embedded_hal::digital::{InputPin, OutputPin};
7use embedded_hal_async::digital::Wait; 8use embedded_hal_async::digital::Wait;
@@ -94,6 +95,7 @@ enum InterfaceType {
94} 95}
95 96
96const MAX_SPI_BUFFER_SIZE: usize = 1600; 97const MAX_SPI_BUFFER_SIZE: usize = 1600;
98const HEARTBEAT_MAX_GAP: Duration = Duration::from_secs(20);
97 99
98pub struct State { 100pub struct State {
99 shared: Shared, 101 shared: Shared,
@@ -135,6 +137,7 @@ where
135 ready, 137 ready,
136 reset, 138 reset,
137 spi, 139 spi,
140 heartbeat_deadline: Instant::now() + HEARTBEAT_MAX_GAP,
138 }; 141 };
139 runner.init().await; 142 runner.init().await;
140 143
@@ -147,6 +150,7 @@ pub struct Runner<'a, SPI, IN, OUT> {
147 shared: &'a Shared, 150 shared: &'a Shared,
148 151
149 next_seq: u16, 152 next_seq: u16,
153 heartbeat_deadline: Instant,
150 154
151 spi: SPI, 155 spi: SPI,
152 handshake: IN, 156 handshake: IN,
@@ -178,9 +182,10 @@ where
178 let ioctl = self.shared.ioctl_wait_pending(); 182 let ioctl = self.shared.ioctl_wait_pending();
179 let tx = self.ch.tx_buf(); 183 let tx = self.ch.tx_buf();
180 let ev = async { self.ready.wait_for_high().await.unwrap() }; 184 let ev = async { self.ready.wait_for_high().await.unwrap() };
185 let hb = Timer::at(self.heartbeat_deadline);
181 186
182 match select3(ioctl, tx, ev).await { 187 match select4(ioctl, tx, ev, hb).await {
183 Either3::First(PendingIoctl { buf, req_len }) => { 188 Either4::First(PendingIoctl { buf, req_len }) => {
184 tx_buf[12..24].copy_from_slice(b"\x01\x08\x00ctrlResp\x02"); 189 tx_buf[12..24].copy_from_slice(b"\x01\x08\x00ctrlResp\x02");
185 tx_buf[24..26].copy_from_slice(&(req_len as u16).to_le_bytes()); 190 tx_buf[24..26].copy_from_slice(&(req_len as u16).to_le_bytes());
186 tx_buf[26..][..req_len].copy_from_slice(&unsafe { &*buf }[..req_len]); 191 tx_buf[26..][..req_len].copy_from_slice(&unsafe { &*buf }[..req_len]);
@@ -199,7 +204,7 @@ where
199 header.checksum = checksum(&tx_buf[..26 + req_len]); 204 header.checksum = checksum(&tx_buf[..26 + req_len]);
200 tx_buf[0..12].copy_from_slice(&header.to_bytes()); 205 tx_buf[0..12].copy_from_slice(&header.to_bytes());
201 } 206 }
202 Either3::Second(packet) => { 207 Either4::Second(packet) => {
203 tx_buf[12..][..packet.len()].copy_from_slice(packet); 208 tx_buf[12..][..packet.len()].copy_from_slice(packet);
204 209
205 let mut header = PayloadHeader { 210 let mut header = PayloadHeader {
@@ -218,9 +223,12 @@ where
218 223
219 self.ch.tx_done(); 224 self.ch.tx_done();
220 } 225 }
221 Either3::Third(()) => { 226 Either4::Third(()) => {
222 tx_buf[..PayloadHeader::SIZE].fill(0); 227 tx_buf[..PayloadHeader::SIZE].fill(0);
223 } 228 }
229 Either4::Fourth(()) => {
230 panic!("heartbeat from esp32 stopped")
231 }
224 } 232 }
225 233
226 if tx_buf[0] != 0 { 234 if tx_buf[0] != 0 {
@@ -309,7 +317,7 @@ where
309 } 317 }
310 } 318 }
311 319
312 fn handle_event(&self, data: &[u8]) { 320 fn handle_event(&mut self, data: &[u8]) {
313 let Ok(event) = noproto::read::<CtrlMsg>(data) else { 321 let Ok(event) = noproto::read::<CtrlMsg>(data) else {
314 warn!("failed to parse event"); 322 warn!("failed to parse event");
315 return; 323 return;
@@ -324,6 +332,7 @@ where
324 332
325 match payload { 333 match payload {
326 CtrlMsgPayload::EventEspInit(_) => self.shared.init_done(), 334 CtrlMsgPayload::EventEspInit(_) => self.shared.init_done(),
335 CtrlMsgPayload::EventHeartbeat(_) => self.heartbeat_deadline = Instant::now() + HEARTBEAT_MAX_GAP,
327 CtrlMsgPayload::EventStationDisconnectFromAp(e) => { 336 CtrlMsgPayload::EventStationDisconnectFromAp(e) => {
328 info!("disconnected, code {}", e.resp); 337 info!("disconnected, code {}", e.resp);
329 self.state_ch.set_link_state(LinkState::Down); 338 self.state_ch.set_link_state(LinkState::Down);