Adding refactor for telemetry
This commit is contained in:
parent
06b328ff52
commit
4a656eedd2
|
@ -13,7 +13,10 @@ use hardware::{
|
|||
DigitalInput1, InputPin, SystemTimer, AFE0, AFE1,
|
||||
};
|
||||
|
||||
use net::{UpdateState, MiniconfClient, NetworkProcessor};
|
||||
use net::{
|
||||
MiniconfClient, NetworkManager, NetworkProcessor, NetworkUsers,
|
||||
TelemetryBuffer, UpdateState,
|
||||
};
|
||||
|
||||
const SCALE: f32 = i16::MAX as _;
|
||||
|
||||
|
@ -49,11 +52,6 @@ impl Default for Settings {
|
|||
}
|
||||
}
|
||||
|
||||
struct NetworkUsers {
|
||||
miniconf: MiniconfClient<Settings>,
|
||||
processor: NetworkProcessor,
|
||||
}
|
||||
|
||||
#[rtic::app(device = stm32h7xx_hal::stm32, peripherals = true, monotonic = stabilizer::hardware::SystemTimer)]
|
||||
const APP: () = {
|
||||
struct Resources {
|
||||
|
@ -61,9 +59,10 @@ const APP: () = {
|
|||
digital_inputs: (DigitalInput0, DigitalInput1),
|
||||
adcs: (Adc0Input, Adc1Input),
|
||||
dacs: (Dac0Output, Dac1Output),
|
||||
network: NetworkUsers,
|
||||
network: NetworkUsers<Settings>,
|
||||
|
||||
settings: Settings,
|
||||
telemetry: TelemetryBuffer,
|
||||
|
||||
#[init([[[0.; 5]; IIR_CASCADE_LENGTH]; 2])]
|
||||
iir_state: [[iir::Vec5; IIR_CASCADE_LENGTH]; 2],
|
||||
|
@ -75,7 +74,8 @@ const APP: () = {
|
|||
let (mut stabilizer, _pounder) = hardware::setup(c.core, c.device);
|
||||
|
||||
let network = {
|
||||
let stack_manager = cortex_m::singleton!(: NetworkManager = NetworkManager::new(stabilizer.net.stack)).unwrap();
|
||||
let stack = stabilizer.net.stack;
|
||||
let stack_manager = cortex_m::singleton!(: NetworkManager = NetworkManager::new(stack)).unwrap();
|
||||
|
||||
let processor = NetworkProcessor::new(
|
||||
stack_manager.acquire_stack(),
|
||||
|
@ -83,7 +83,7 @@ const APP: () = {
|
|||
stabilizer.cycle_counter,
|
||||
);
|
||||
|
||||
let settings = MqttInterface::new(
|
||||
let settings = MiniconfClient::new(
|
||||
stack_manager.acquire_stack(),
|
||||
"",
|
||||
&net::get_device_prefix(
|
||||
|
@ -113,7 +113,6 @@ const APP: () = {
|
|||
// Start sampling ADCs.
|
||||
stabilizer.adc_dac_timer.start();
|
||||
|
||||
|
||||
init::LateResources {
|
||||
afes: stabilizer.afes,
|
||||
adcs: stabilizer.adcs,
|
||||
|
@ -193,12 +192,19 @@ const APP: () = {
|
|||
fn idle(mut c: idle::Context) -> ! {
|
||||
loop {
|
||||
// Update the smoltcp network stack.
|
||||
let poll_result = c.resources.network.lock(|network| network.processor.poll());
|
||||
let poll_result = c
|
||||
.resources
|
||||
.network
|
||||
.lock(|network| network.processor.update());
|
||||
|
||||
// Service the MQTT configuration client.
|
||||
if c.resources.miniconf_client.lock(|client| client.update()) == UpdateStatus::Updated {
|
||||
if c.resources
|
||||
.network
|
||||
.lock(|network| network.miniconf.update())
|
||||
== UpdateState::Updated
|
||||
{
|
||||
c.spawn.settings_update().unwrap()
|
||||
} else if poll_result == UpdateStatus::NoChange {
|
||||
} else if poll_result == UpdateState::NoChange {
|
||||
cortex_m::asm::wfi();
|
||||
}
|
||||
}
|
||||
|
@ -217,10 +223,10 @@ const APP: () = {
|
|||
|
||||
#[task(priority = 1, resources=[network, settings, telemetry], schedule=[telemetry])]
|
||||
fn telemetry(mut c: telemetry::Context) {
|
||||
let telemetry =
|
||||
let _telemetry =
|
||||
c.resources.telemetry.lock(|telemetry| telemetry.clone());
|
||||
|
||||
let gains = c.resources.settings.lock(|settings| settings.afe.clone());
|
||||
let _gains = c.resources.settings.lock(|settings| settings.afe.clone());
|
||||
|
||||
// TODO: Publish telemetry through the telemetry client here.
|
||||
//c.resources
|
||||
|
|
|
@ -18,7 +18,9 @@ use stabilizer::hardware::{
|
|||
};
|
||||
|
||||
use miniconf::Miniconf;
|
||||
use stabilizer::net::{Action, MqttInterface};
|
||||
use stabilizer::net::{
|
||||
MiniconfClient, NetworkManager, NetworkProcessor, NetworkUsers, UpdateState,
|
||||
};
|
||||
|
||||
#[derive(Copy, Clone, Debug, Deserialize, Miniconf)]
|
||||
enum Conf {
|
||||
|
@ -64,7 +66,7 @@ const APP: () = {
|
|||
afes: (AFE0, AFE1),
|
||||
adcs: (Adc0Input, Adc1Input),
|
||||
dacs: (Dac0Output, Dac1Output),
|
||||
mqtt: MqttInterface<Settings>,
|
||||
network: NetworkUsers<Settings>,
|
||||
settings: Settings,
|
||||
telemetry: net::TelemetryBuffer,
|
||||
digital_inputs: (DigitalInput0, DigitalInput1),
|
||||
|
@ -79,16 +81,32 @@ const APP: () = {
|
|||
// Configure the microcontroller
|
||||
let (mut stabilizer, _pounder) = setup(c.core, c.device);
|
||||
|
||||
let mqtt = MqttInterface::new(
|
||||
stabilizer.net.stack,
|
||||
"",
|
||||
&net::get_device_prefix(
|
||||
env!("CARGO_BIN_NAME"),
|
||||
stabilizer.net.mac_address,
|
||||
),
|
||||
stabilizer.net.phy,
|
||||
stabilizer.cycle_counter,
|
||||
);
|
||||
let network = {
|
||||
let stack = stabilizer.net.stack;
|
||||
let stack_manager = cortex_m::singleton!(: NetworkManager = NetworkManager::new(stack)).unwrap();
|
||||
|
||||
let processor = NetworkProcessor::new(
|
||||
stack_manager.acquire_stack(),
|
||||
stabilizer.net.phy,
|
||||
stabilizer.cycle_counter,
|
||||
);
|
||||
|
||||
let settings = MiniconfClient::new(
|
||||
stack_manager.acquire_stack(),
|
||||
"",
|
||||
&net::get_device_prefix(
|
||||
env!("CARGO_BIN_NAME"),
|
||||
stabilizer.net.mac_address,
|
||||
),
|
||||
);
|
||||
|
||||
// TODO: Add telemetry client
|
||||
|
||||
NetworkUsers {
|
||||
miniconf: settings,
|
||||
processor,
|
||||
}
|
||||
};
|
||||
|
||||
let settings = Settings::default();
|
||||
|
||||
|
@ -120,7 +138,7 @@ const APP: () = {
|
|||
afes: stabilizer.afes,
|
||||
adcs: stabilizer.adcs,
|
||||
dacs: stabilizer.dacs,
|
||||
mqtt,
|
||||
network,
|
||||
digital_inputs: stabilizer.digital_inputs,
|
||||
timestamper: stabilizer.timestamper,
|
||||
telemetry: net::TelemetryBuffer::default(),
|
||||
|
@ -211,22 +229,31 @@ const APP: () = {
|
|||
[dac_samples[0][0], dac_samples[1][0]];
|
||||
}
|
||||
|
||||
#[idle(resources=[mqtt], spawn=[settings_update])]
|
||||
#[idle(resources=[network], spawn=[settings_update])]
|
||||
fn idle(mut c: idle::Context) -> ! {
|
||||
loop {
|
||||
match c.resources.mqtt.lock(|mqtt| mqtt.update()) {
|
||||
Some(Action::Sleep) => cortex_m::asm::wfi(),
|
||||
Some(Action::UpdateSettings) => {
|
||||
c.spawn.settings_update().unwrap()
|
||||
}
|
||||
_ => {}
|
||||
// Update the smoltcp network stack.
|
||||
let poll_result = c
|
||||
.resources
|
||||
.network
|
||||
.lock(|network| network.processor.update());
|
||||
|
||||
// Service the MQTT configuration client.
|
||||
if c.resources
|
||||
.network
|
||||
.lock(|network| network.miniconf.update())
|
||||
== UpdateState::Updated
|
||||
{
|
||||
c.spawn.settings_update().unwrap()
|
||||
} else if poll_result == UpdateState::NoChange {
|
||||
cortex_m::asm::wfi();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[task(priority = 1, resources=[mqtt, settings, afes])]
|
||||
#[task(priority = 1, resources=[network, settings, afes])]
|
||||
fn settings_update(mut c: settings_update::Context) {
|
||||
let settings = c.resources.mqtt.settings();
|
||||
let settings = c.resources.network.miniconf.settings();
|
||||
|
||||
c.resources.afes.0.set_gain(settings.afe[0]);
|
||||
c.resources.afes.1.set_gain(settings.afe[1]);
|
||||
|
@ -234,7 +261,7 @@ const APP: () = {
|
|||
c.resources.settings.lock(|current| *current = *settings);
|
||||
}
|
||||
|
||||
#[task(priority = 1, resources=[mqtt, digital_inputs, settings, telemetry], schedule=[telemetry])]
|
||||
#[task(priority = 1, resources=[network, digital_inputs, settings, telemetry], schedule=[telemetry])]
|
||||
fn telemetry(mut c: telemetry::Context) {
|
||||
let mut telemetry =
|
||||
c.resources.telemetry.lock(|telemetry| telemetry.clone());
|
||||
|
@ -244,10 +271,12 @@ const APP: () = {
|
|||
c.resources.digital_inputs.1.is_high().unwrap(),
|
||||
];
|
||||
|
||||
let gains = c.resources.settings.lock(|settings| settings.afe.clone());
|
||||
c.resources
|
||||
.mqtt
|
||||
.publish_telemetry(&telemetry.to_telemetry(gains[0], gains[1]));
|
||||
let _gains = c.resources.settings.lock(|settings| settings.afe.clone());
|
||||
|
||||
// TODO: Publish telemetry.
|
||||
//c.resources
|
||||
// .mqtt
|
||||
// .publish_telemetry(&telemetry.to_telemetry(gains[0], gains[1]));
|
||||
|
||||
let telemetry_period = c
|
||||
.resources
|
||||
|
|
|
@ -13,23 +13,30 @@ mod messages;
|
|||
mod mqtt_interface;
|
||||
mod shared;
|
||||
mod stack_manager;
|
||||
use messages::{MqttMessage, SettingsResponse};
|
||||
pub use mqtt_interface::MiniconfClient;
|
||||
pub use stack_manager::NetworkProcessor;
|
||||
|
||||
pub use shared::NetworkManager;
|
||||
mod telemetry;
|
||||
|
||||
use crate::hardware::NetworkStack;
|
||||
pub type NetworkReference = shared::NetworkStackProxy<'static, NetworkStack>;
|
||||
use messages::{MqttMessage, SettingsResponse};
|
||||
use miniconf::Miniconf;
|
||||
|
||||
mod telemetry;
|
||||
pub use mqtt_interface::MiniconfClient;
|
||||
pub use shared::NetworkManager;
|
||||
pub use stack_manager::NetworkProcessor;
|
||||
pub use telemetry::{Telemetry, TelemetryBuffer};
|
||||
|
||||
pub type NetworkReference = shared::NetworkStackProxy<'static, NetworkStack>;
|
||||
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
pub enum UpdateState {
|
||||
NoChange,
|
||||
Updated,
|
||||
}
|
||||
|
||||
pub struct NetworkUsers<S: Default + Clone + Miniconf> {
|
||||
pub miniconf: MiniconfClient<S>,
|
||||
pub processor: NetworkProcessor,
|
||||
}
|
||||
|
||||
/// Get the MQTT prefix of a device.
|
||||
///
|
||||
/// # Args
|
||||
|
|
|
@ -2,7 +2,7 @@ use crate::hardware::design_parameters::MQTT_BROKER;
|
|||
|
||||
use heapless::{consts, String};
|
||||
|
||||
use super::{UpdateState, MqttMessage, SettingsResponse, NetworkReference};
|
||||
use super::{MqttMessage, NetworkReference, SettingsResponse, UpdateState};
|
||||
|
||||
/// MQTT settings interface.
|
||||
pub struct MiniconfClient<S>
|
||||
|
@ -26,11 +26,7 @@ where
|
|||
/// * `stack` - The network stack to use for communication.
|
||||
/// * `client_id` - The ID of the MQTT client. May be an empty string for auto-assigning.
|
||||
/// * `prefix` - The MQTT device prefix to use for this device.
|
||||
pub fn new(
|
||||
stack: NetworkReference,
|
||||
client_id: &str,
|
||||
prefix: &str,
|
||||
) -> Self {
|
||||
pub fn new(stack: NetworkReference, client_id: &str, prefix: &str) -> Self {
|
||||
let mqtt =
|
||||
minimq::MqttClient::new(MQTT_BROKER.into(), client_id, stack)
|
||||
.unwrap();
|
||||
|
@ -55,7 +51,6 @@ where
|
|||
/// # Returns
|
||||
/// An option containing an action that should be completed as a result of network servicing.
|
||||
pub fn update(&mut self) -> UpdateState {
|
||||
|
||||
let mqtt_connected = match self.mqtt.is_connected() {
|
||||
Ok(connected) => connected,
|
||||
Err(minimq::Error::Network(
|
||||
|
|
|
@ -1,19 +1,15 @@
|
|||
use shared_bus::{AtomicCheckMutex, BusMutex};
|
||||
use minimq::embedded_nal;
|
||||
use smoltcp_nal::smoltcp;
|
||||
use shared_bus::{AtomicCheckMutex, BusMutex};
|
||||
|
||||
use crate::hardware::NetworkStack;
|
||||
|
||||
pub struct NetworkStackProxy<'a, S> {
|
||||
mutex: &'a AtomicCheckMutex<S>
|
||||
mutex: &'a AtomicCheckMutex<S>,
|
||||
}
|
||||
|
||||
impl<'a> NetworkStackProxy<'a, NetworkStack> {
|
||||
pub fn poll(&mut self, now: u32) -> Result<bool, smoltcp::Error> {
|
||||
self.mutex.lock(|stack| stack.poll(now))
|
||||
}
|
||||
pub fn handle_link_reset(&mut self) {
|
||||
self.mutex.lock(|stack| stack.handle_link_reset())
|
||||
impl<'a, S> NetworkStackProxy<'a, S> {
|
||||
pub fn lock<R, F: FnOnce(&mut S) -> R>(&mut self, f: F) -> R {
|
||||
self.mutex.lock(|stack| f(stack))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,7 +23,7 @@ macro_rules! forward {
|
|||
|
||||
impl<'a, S> embedded_nal::TcpStack for NetworkStackProxy<'a, S>
|
||||
where
|
||||
S: embedded_nal::TcpStack
|
||||
S: embedded_nal::TcpStack,
|
||||
{
|
||||
type TcpSocket = S::TcpSocket;
|
||||
type Error = S::Error;
|
||||
|
@ -41,17 +37,17 @@ where
|
|||
}
|
||||
|
||||
pub struct NetworkManager {
|
||||
mutex: AtomicCheckMutex<NetworkStack>
|
||||
mutex: AtomicCheckMutex<NetworkStack>,
|
||||
}
|
||||
|
||||
impl NetworkManager {
|
||||
pub fn new(stack: NetworkStack) -> Self {
|
||||
Self { mutex: AtomicCheckMutex::create(stack) }
|
||||
Self {
|
||||
mutex: AtomicCheckMutex::create(stack),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn acquire_stack<'a>(&'a self) -> NetworkStackProxy<'a, NetworkStack> {
|
||||
NetworkStackProxy {
|
||||
mutex: &self.mutex
|
||||
}
|
||||
NetworkStackProxy { mutex: &self.mutex }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use super::{UpdateState, NetworkReference};
|
||||
use super::{NetworkReference, UpdateState};
|
||||
|
||||
use crate::hardware::{EthernetPhy, CycleCounter};
|
||||
use crate::hardware::{CycleCounter, EthernetPhy};
|
||||
|
||||
pub struct NetworkProcessor {
|
||||
stack: NetworkReference,
|
||||
|
@ -10,13 +10,24 @@ pub struct NetworkProcessor {
|
|||
}
|
||||
|
||||
impl NetworkProcessor {
|
||||
pub fn new(stack: NetworkReference, phy: EthernetPhy, clock: CycleCounter) -> Self {
|
||||
Self { stack, phy, clock, network_was_reset: false }
|
||||
pub fn new(
|
||||
stack: NetworkReference,
|
||||
phy: EthernetPhy,
|
||||
clock: CycleCounter,
|
||||
) -> Self {
|
||||
Self {
|
||||
stack,
|
||||
phy,
|
||||
clock,
|
||||
network_was_reset: false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update(&mut self) -> UpdateState {
|
||||
// Service the network stack to process any inbound and outbound traffic.
|
||||
let result = match self.stack.poll(self.clock.current_ms()) {
|
||||
let now = self.clock.current_ms();
|
||||
|
||||
let result = match self.stack.lock(|stack| stack.poll(now)) {
|
||||
Ok(true) => UpdateState::Updated,
|
||||
Ok(false) => UpdateState::NoChange,
|
||||
Err(err) => {
|
||||
|
@ -34,9 +45,9 @@ impl NetworkProcessor {
|
|||
// sending an excessive number of DHCP requests.
|
||||
false if !self.network_was_reset => {
|
||||
self.network_was_reset = true;
|
||||
self.stack.handle_link_reset();
|
||||
self.stack.lock(|stack| stack.handle_link_reset());
|
||||
}
|
||||
_ => {},
|
||||
_ => {}
|
||||
};
|
||||
|
||||
result
|
||||
|
|
Loading…
Reference in New Issue