From 14bfbbe2a1e14cf0c5a3824e72b2aec712dd29fb Mon Sep 17 00:00:00 2001 From: Ryan Summers Date: Mon, 31 May 2021 14:28:57 +0200 Subject: [PATCH] Refactoring link status polling --- src/bin/dual-iir.rs | 11 ++++++++++- src/bin/lockin.rs | 11 ++++++++++- src/net/mod.rs | 8 +++----- src/net/network_processor.rs | 38 ++++++++++++++++++------------------ 4 files changed, 42 insertions(+), 26 deletions(-) diff --git a/src/bin/dual-iir.rs b/src/bin/dual-iir.rs index a6017fb..aa2d305 100644 --- a/src/bin/dual-iir.rs +++ b/src/bin/dual-iir.rs @@ -69,7 +69,7 @@ const APP: () = { iir_state: [[iir::Vec5; IIR_CASCADE_LENGTH]; 2], } - #[init(spawn=[telemetry, settings_update])] + #[init(spawn=[telemetry, settings_update, ethernet_link])] fn init(c: init::Context) -> init::LateResources { // Configure the microcontroller let (mut stabilizer, _pounder) = hardware::setup(c.core, c.device); @@ -91,6 +91,9 @@ const APP: () = { c.spawn.settings_update().unwrap(); c.spawn.telemetry().unwrap(); + // Spawn the ethernet link period check task. + c.spawn.ethernet_link().unwrap(); + // Enable ADC/DAC events stabilizer.adcs.0.start(); stabilizer.adcs.1.start(); @@ -227,6 +230,12 @@ const APP: () = { .unwrap(); } + #[task(priority = 1, resources=[network], schedule=[ethernet_link])] + fn ethernet_link(c: ethernet_link::Context) { + c.resources.network.processor.handle_link(); + c.schedule.ethernet_link(c.scheduled + SystemTimer::ticks_from_secs(1)).unwrap(); + } + #[task(binds = ETH, priority = 1)] fn eth(_: eth::Context) { unsafe { stm32h7xx_hal::ethernet::interrupt_handler() } diff --git a/src/bin/lockin.rs b/src/bin/lockin.rs index 4864760..6c95959 100644 --- a/src/bin/lockin.rs +++ b/src/bin/lockin.rs @@ -94,7 +94,7 @@ const APP: () = { lockin: Lockin<4>, } - #[init(spawn=[settings_update, telemetry])] + #[init(spawn=[settings_update, telemetry, ethernet_link])] fn init(c: init::Context) -> init::LateResources { // Configure the microcontroller let (mut stabilizer, _pounder) = setup(c.core, c.device); @@ -118,6 +118,9 @@ const APP: () = { c.spawn.settings_update().unwrap(); c.spawn.telemetry().unwrap(); + // Spawn the ethernet link servicing task. + c.spawn.ethernet_link().unwrap(); + // Enable ADC/DAC events stabilizer.adcs.0.start(); stabilizer.adcs.1.start(); @@ -298,6 +301,12 @@ const APP: () = { .unwrap(); } + #[task(priority = 1, resources=[network], schedule=[ethernet_link])] + fn ethernet_link(c: ethernet_link::Context) { + c.resources.network.processor.handle_link(); + c.schedule.ethernet_link(c.scheduled + SystemTimer::ticks_from_secs(1)).unwrap(); + } + #[task(binds = ETH, priority = 1)] fn eth(_: eth::Context) { unsafe { stm32h7xx_hal::ethernet::interrupt_handler() } diff --git a/src/net/mod.rs b/src/net/mod.rs index 7c31bf0..0494db5 100644 --- a/src/net/mod.rs +++ b/src/net/mod.rs @@ -47,7 +47,7 @@ pub enum NetworkState { /// A structure of Stabilizer's default network users. pub struct NetworkUsers { pub miniconf: MiniconfClient, - processor: NetworkProcessor, + pub processor: NetworkProcessor, stream: DataStream, generator: Option, pub telemetry: TelemetryClient, @@ -143,12 +143,10 @@ where UpdateState::Updated => NetworkState::Updated, }; - let result = match self.miniconf.update() { + match self.miniconf.update() { UpdateState::Updated => NetworkState::SettingsChanged, UpdateState::NoChange => poll_result, - }; - - result + } } } diff --git a/src/net/network_processor.rs b/src/net/network_processor.rs index af00606..c5f37bf 100644 --- a/src/net/network_processor.rs +++ b/src/net/network_processor.rs @@ -37,9 +37,25 @@ impl NetworkProcessor { } } - pub fn egress(&mut self) { - let now = self.clock.current_ms(); - self.stack.lock(|stack| stack.poll(now)).ok(); + /// Handle ethernet link connection status. + /// + /// # Note + /// This may take non-trivial amounts of time to communicate with the PHY. As such, this should + /// only be called as often as necessary (e.g. once per second or so). + pub fn handle_link(&mut self) { + // If the PHY indicates there's no more ethernet link, reset the DHCP server in the network + // stack. + match self.phy.poll_link() { + true => self.network_was_reset = false, + + // Only reset the network stack once per link reconnection. This prevents us from + // sending an excessive number of DHCP requests. + false if !self.network_was_reset => { + self.network_was_reset = true; + self.stack.lock(|stack| stack.handle_link_reset()); + } + _ => {} + }; } /// Process and update the state of the network. @@ -63,22 +79,6 @@ impl NetworkProcessor { } }; - // If the PHY indicates there's no more ethernet link, reset the DHCP server in the network - // stack. - // TODO: Poll the link state in a task and handle resets. Polling this often is slow and - // uses necessary CPU time. - //match self.phy.poll_link() { - // true => self.network_was_reset = false, - - // // Only reset the network stack once per link reconnection. This prevents us from - // // sending an excessive number of DHCP requests. - // false if !self.network_was_reset => { - // self.network_was_reset = true; - // self.stack.lock(|stack| stack.handle_link_reset()); - // } - // _ => {} - //}; - result } }