Updating constructors

master
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",
"paste",
"serde",
"serde-json-core",
"shared-bus",
"smoltcp-nal",
"stm32h7xx-hal",

View File

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

View File

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

View File

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

View File

@ -1,3 +1,4 @@
use core::fmt::Write;
///! Stabilizer network management module
///!
///! # Design
@ -6,8 +7,8 @@
///! streaming over raw UDP/TCP sockets. This module encompasses the main processing routines
///! related to Stabilizer networking operations.
use heapless::{consts, String};
use core::fmt::Write;
use miniconf::Miniconf;
use serde::Serialize;
mod messages;
mod mqtt_interface;
@ -15,14 +16,13 @@ mod shared;
mod stack_manager;
mod telemetry;
use crate::hardware::NetworkStack;
use crate::hardware::{CycleCounter, EthernetPhy, NetworkStack};
use messages::{MqttMessage, SettingsResponse};
use miniconf::Miniconf;
pub use mqtt_interface::MiniconfClient;
pub use shared::NetworkManager;
pub use stack_manager::NetworkProcessor;
pub use telemetry::{Telemetry, TelemetryBuffer};
pub use telemetry::{Telemetry, TelemetryBuffer, TelemetryClient};
pub type NetworkReference = shared::NetworkStackProxy<'static, NetworkStack>;
@ -32,9 +32,80 @@ pub enum UpdateState {
Updated,
}
pub struct NetworkUsers<S: Default + Clone + Miniconf> {
pub struct NetworkUsers<S: Default + Clone + Miniconf, T: Serialize> {
pub miniconf: MiniconfClient<S>,
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.

View File

@ -1,5 +1,10 @@
use heapless::{consts, String, Vec};
use serde::Serialize;
use super::NetworkReference;
use crate::hardware::design_parameters::MQTT_BROKER;
use minimq::QoS;
use crate::hardware::AfeGain;
#[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();
}
}