Updating constructors

This commit is contained in:
Ryan Summers 2021-05-05 16:16:54 +02:00
parent 4a656eedd2
commit 8144b3acf2
6 changed files with 145 additions and 79 deletions

1
Cargo.lock generated
View File

@ -763,6 +763,7 @@ dependencies = [
"panic-semihosting", "panic-semihosting",
"paste", "paste",
"serde", "serde",
"serde-json-core",
"shared-bus", "shared-bus",
"smoltcp-nal", "smoltcp-nal",
"stm32h7xx-hal", "stm32h7xx-hal",

View File

@ -46,6 +46,7 @@ ad9959 = { path = "ad9959" }
generic-array = "0.14" generic-array = "0.14"
miniconf = "0.1.0" miniconf = "0.1.0"
shared-bus = {version = "0.2.2", features = ["cortex-m"] } shared-bus = {version = "0.2.2", features = ["cortex-m"] }
serde-json-core = "0.3"
[dependencies.mcp23017] [dependencies.mcp23017]
git = "https://github.com/mrd0ll4r/mcp23017.git" git = "https://github.com/mrd0ll4r/mcp23017.git"

View File

@ -13,10 +13,7 @@ use hardware::{
DigitalInput1, InputPin, SystemTimer, AFE0, AFE1, DigitalInput1, InputPin, SystemTimer, AFE0, AFE1,
}; };
use net::{ use net::{NetworkUsers, Telemetry, TelemetryBuffer, UpdateState};
MiniconfClient, NetworkManager, NetworkProcessor, NetworkUsers,
TelemetryBuffer, UpdateState,
};
const SCALE: f32 = i16::MAX as _; const SCALE: f32 = i16::MAX as _;
@ -59,7 +56,7 @@ const APP: () = {
digital_inputs: (DigitalInput0, DigitalInput1), digital_inputs: (DigitalInput0, DigitalInput1),
adcs: (Adc0Input, Adc1Input), adcs: (Adc0Input, Adc1Input),
dacs: (Dac0Output, Dac1Output), dacs: (Dac0Output, Dac1Output),
network: NetworkUsers<Settings>, network: NetworkUsers<Settings, Telemetry>,
settings: Settings, settings: Settings,
telemetry: TelemetryBuffer, telemetry: TelemetryBuffer,
@ -73,33 +70,14 @@ const APP: () = {
// Configure the microcontroller // Configure the microcontroller
let (mut stabilizer, _pounder) = hardware::setup(c.core, c.device); let (mut stabilizer, _pounder) = hardware::setup(c.core, c.device);
let network = { let network = NetworkUsers::new(
let stack = stabilizer.net.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.net.phy,
stabilizer.cycle_counter, stabilizer.cycle_counter,
);
let settings = MiniconfClient::new(
stack_manager.acquire_stack(),
"",
&net::get_device_prefix(
env!("CARGO_BIN_NAME"), env!("CARGO_BIN_NAME"),
stabilizer.net.mac_address, stabilizer.net.mac_address,
),
); );
// TODO: Add telemetry client
NetworkUsers {
miniconf: settings,
processor,
}
};
// Spawn a settings update for default settings. // Spawn a settings update for default settings.
c.spawn.settings_update().unwrap(); c.spawn.settings_update().unwrap();
c.spawn.telemetry().unwrap(); c.spawn.telemetry().unwrap();
@ -223,15 +201,15 @@ const APP: () = {
#[task(priority = 1, resources=[network, settings, telemetry], schedule=[telemetry])] #[task(priority = 1, resources=[network, settings, telemetry], schedule=[telemetry])]
fn telemetry(mut c: telemetry::Context) { fn telemetry(mut c: telemetry::Context) {
let _telemetry = let telemetry =
c.resources.telemetry.lock(|telemetry| telemetry.clone()); 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
//c.resources .network
// .mqtt .telemetry
// .publish_telemetry(&telemetry.to_telemetry(gains[0], gains[1])); .publish(&telemetry.to_telemetry(gains[0], gains[1]));
let telemetry_period = c let telemetry_period = c
.resources .resources

View File

@ -18,9 +18,7 @@ use stabilizer::hardware::{
}; };
use miniconf::Miniconf; use miniconf::Miniconf;
use stabilizer::net::{ use net::{NetworkUsers, Telemetry, TelemetryBuffer, UpdateState};
MiniconfClient, NetworkManager, NetworkProcessor, NetworkUsers, UpdateState,
};
#[derive(Copy, Clone, Debug, Deserialize, Miniconf)] #[derive(Copy, Clone, Debug, Deserialize, Miniconf)]
enum Conf { enum Conf {
@ -66,9 +64,9 @@ const APP: () = {
afes: (AFE0, AFE1), afes: (AFE0, AFE1),
adcs: (Adc0Input, Adc1Input), adcs: (Adc0Input, Adc1Input),
dacs: (Dac0Output, Dac1Output), dacs: (Dac0Output, Dac1Output),
network: NetworkUsers<Settings>, network: NetworkUsers<Settings, Telemetry>,
settings: Settings, settings: Settings,
telemetry: net::TelemetryBuffer, telemetry: TelemetryBuffer,
digital_inputs: (DigitalInput0, DigitalInput1), digital_inputs: (DigitalInput0, DigitalInput1),
timestamper: InputStamper, timestamper: InputStamper,
@ -81,33 +79,14 @@ const APP: () = {
// Configure the microcontroller // Configure the microcontroller
let (mut stabilizer, _pounder) = setup(c.core, c.device); let (mut stabilizer, _pounder) = setup(c.core, c.device);
let network = { let network = NetworkUsers::new(
let stack = stabilizer.net.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.net.phy,
stabilizer.cycle_counter, stabilizer.cycle_counter,
);
let settings = MiniconfClient::new(
stack_manager.acquire_stack(),
"",
&net::get_device_prefix(
env!("CARGO_BIN_NAME"), env!("CARGO_BIN_NAME"),
stabilizer.net.mac_address, stabilizer.net.mac_address,
),
); );
// TODO: Add telemetry client
NetworkUsers {
miniconf: settings,
processor,
}
};
let settings = Settings::default(); let settings = Settings::default();
let pll = RPLL::new( let pll = RPLL::new(
@ -271,12 +250,12 @@ const APP: () = {
c.resources.digital_inputs.1.is_high().unwrap(), c.resources.digital_inputs.1.is_high().unwrap(),
]; ];
let _gains = c.resources.settings.lock(|settings| settings.afe.clone()); let gains = c.resources.settings.lock(|settings| settings.afe.clone());
// TODO: Publish telemetry. c.resources
//c.resources .network
// .mqtt .telemetry
// .publish_telemetry(&telemetry.to_telemetry(gains[0], gains[1])); .publish(&telemetry.to_telemetry(gains[0], gains[1]));
let telemetry_period = c let telemetry_period = c
.resources .resources

View File

@ -1,3 +1,4 @@
use core::fmt::Write;
///! Stabilizer network management module ///! Stabilizer network management module
///! ///!
///! # Design ///! # Design
@ -6,8 +7,8 @@
///! streaming over raw UDP/TCP sockets. This module encompasses the main processing routines ///! streaming over raw UDP/TCP sockets. This module encompasses the main processing routines
///! related to Stabilizer networking operations. ///! related to Stabilizer networking operations.
use heapless::{consts, String}; use heapless::{consts, String};
use miniconf::Miniconf;
use core::fmt::Write; use serde::Serialize;
mod messages; mod messages;
mod mqtt_interface; mod mqtt_interface;
@ -15,14 +16,13 @@ mod shared;
mod stack_manager; mod stack_manager;
mod telemetry; mod telemetry;
use crate::hardware::NetworkStack; use crate::hardware::{CycleCounter, EthernetPhy, NetworkStack};
use messages::{MqttMessage, SettingsResponse}; use messages::{MqttMessage, SettingsResponse};
use miniconf::Miniconf;
pub use mqtt_interface::MiniconfClient; pub use mqtt_interface::MiniconfClient;
pub use shared::NetworkManager; pub use shared::NetworkManager;
pub use stack_manager::NetworkProcessor; pub use stack_manager::NetworkProcessor;
pub use telemetry::{Telemetry, TelemetryBuffer}; pub use telemetry::{Telemetry, TelemetryBuffer, TelemetryClient};
pub type NetworkReference = shared::NetworkStackProxy<'static, NetworkStack>; pub type NetworkReference = shared::NetworkStackProxy<'static, NetworkStack>;
@ -32,9 +32,80 @@ pub enum UpdateState {
Updated, Updated,
} }
pub struct NetworkUsers<S: Default + Clone + Miniconf> { pub struct NetworkUsers<S: Default + Clone + Miniconf, T: Serialize> {
pub miniconf: MiniconfClient<S>, pub miniconf: MiniconfClient<S>,
pub processor: NetworkProcessor, pub processor: NetworkProcessor,
pub telemetry: TelemetryClient<T>,
}
impl<S, T> NetworkUsers<S, T>
where
S: Default + Clone + Miniconf,
T: Serialize,
{
pub fn new(
stack: NetworkStack,
phy: EthernetPhy,
cycle_counter: CycleCounter,
app: &str,
mac: smoltcp_nal::smoltcp::wire::EthernetAddress,
) -> Self {
let stack_manager =
cortex_m::singleton!(: NetworkManager = NetworkManager::new(stack))
.unwrap();
let processor = NetworkProcessor::new(
stack_manager.acquire_stack(),
phy,
cycle_counter,
);
let prefix = get_device_prefix(app, mac);
let settings = MiniconfClient::new(
stack_manager.acquire_stack(),
&get_client_id(app, "settings", mac),
&prefix,
);
let telemetry = TelemetryClient::new(
stack_manager.acquire_stack(),
&get_client_id(app, "tlm", mac),
&prefix,
);
NetworkUsers {
miniconf: settings,
processor,
telemetry,
}
}
}
fn get_client_id(
app: &str,
client: &str,
mac: smoltcp_nal::smoltcp::wire::EthernetAddress,
) -> String<consts::U64> {
let mac_string = {
let mut mac_string: String<consts::U32> = String::new();
let mac = mac.as_bytes();
// Note(unwrap): 32-bytes is guaranteed to be valid for any mac address, as the address has
// a fixed length.
write!(
&mut mac_string,
"{:02x}-{:02x}-{:02x}-{:02x}-{:02x}-{:02x}",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]
)
.unwrap();
mac_string
};
let mut identifier = String::new();
write!(&mut identifier, "{}-{}-{}", app, mac_string, client).unwrap();
identifier
} }
/// Get the MQTT prefix of a device. /// Get the MQTT prefix of a device.

View File

@ -1,5 +1,10 @@
use heapless::{consts, String, Vec};
use serde::Serialize; use serde::Serialize;
use super::NetworkReference;
use crate::hardware::design_parameters::MQTT_BROKER;
use minimq::QoS;
use crate::hardware::AfeGain; use crate::hardware::AfeGain;
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
@ -51,3 +56,34 @@ impl TelemetryBuffer {
} }
} }
} }
pub struct TelemetryClient<T: Serialize> {
mqtt: minimq::MqttClient<minimq::consts::U256, NetworkReference>,
telemetry_topic: String<consts::U128>,
_telemetry: core::marker::PhantomData<T>,
}
impl<T: Serialize> TelemetryClient<T> {
pub fn new(stack: NetworkReference, client_id: &str, prefix: &str) -> Self {
let mqtt =
minimq::MqttClient::new(MQTT_BROKER.into(), client_id, stack)
.unwrap();
let mut telemetry_topic: String<consts::U128> = String::from(prefix);
telemetry_topic.push_str("/telemetry").unwrap();
Self {
mqtt,
telemetry_topic,
_telemetry: core::marker::PhantomData::default(),
}
}
pub fn publish(&mut self, telemetry: &T) {
let telemetry: Vec<u8, consts::U256> =
serde_json_core::to_vec(telemetry).unwrap();
self.mqtt
.publish(&self.telemetry_topic, &telemetry, QoS::AtMostOnce, &[])
.ok();
}
}