updated STM32F3 RTICv2 example
This commit is contained in:
17
embedded-examples/embedded-client/Cargo.toml
Normal file
17
embedded-examples/embedded-client/Cargo.toml
Normal file
@@ -0,0 +1,17 @@
|
||||
[package]
|
||||
name = "embedded-client"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
clap = { version = "4", features = ["derive"] }
|
||||
serialport = "4"
|
||||
toml = "0.9"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
satrs-stm32f3-disco-rtic = { path = "../stm32f3-disco-rtic" }
|
||||
spacepackets = { git = "https://egit.irs.uni-stuttgart.de/rust/spacepackets.git", version = "0.17" }
|
||||
postcard = { version = "1", features = ["alloc"] }
|
||||
cobs = "0.5"
|
||||
fern = "0.7"
|
||||
humantime = "2"
|
||||
log = "0.4"
|
||||
2
embedded-examples/embedded-client/config.toml
Normal file
2
embedded-examples/embedded-client/config.toml
Normal file
@@ -0,0 +1,2 @@
|
||||
[interface]
|
||||
serial_port = "/dev/ttyUSB0"
|
||||
126
embedded-examples/embedded-client/src/main.rs
Normal file
126
embedded-examples/embedded-client/src/main.rs
Normal file
@@ -0,0 +1,126 @@
|
||||
use std::{
|
||||
fs::File,
|
||||
io::Read,
|
||||
path::Path,
|
||||
time::{Duration, SystemTime},
|
||||
};
|
||||
|
||||
use clap::Parser;
|
||||
use cobs::CobsDecoderOwned;
|
||||
use satrs_stm32f3_disco_rtic::Request;
|
||||
use spacepackets::{CcsdsPacketCreator, CcsdsPacketReader, SpHeader};
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
struct Cli {
|
||||
#[arg(short, long)]
|
||||
ping: bool,
|
||||
|
||||
/// Set frequency in milliseconds.
|
||||
#[arg(short, long)]
|
||||
set_led_frequency: Option<u32>,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize)]
|
||||
struct Config {
|
||||
interface: Interface,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize)]
|
||||
struct Interface {
|
||||
serial_port: String,
|
||||
}
|
||||
|
||||
fn setup_logger() -> Result<(), fern::InitError> {
|
||||
fern::Dispatch::new()
|
||||
.format(|out, message, record| {
|
||||
out.finish(format_args!(
|
||||
"[{} {} {}] {}",
|
||||
humantime::format_rfc3339_seconds(SystemTime::now()),
|
||||
record.level(),
|
||||
record.target(),
|
||||
message
|
||||
))
|
||||
})
|
||||
.level(log::LevelFilter::Debug)
|
||||
.chain(std::io::stdout())
|
||||
.chain(fern::log_file("output.log")?)
|
||||
.apply()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn main() {
|
||||
setup_logger().expect("failed to initialize logger");
|
||||
println!("sat-rs embedded examples TMTC client");
|
||||
|
||||
let cli = Cli::parse();
|
||||
let mut config_file =
|
||||
File::open(Path::new("config.toml")).expect("opening config.toml file failed");
|
||||
let mut toml_str = String::new();
|
||||
config_file
|
||||
.read_to_string(&mut toml_str)
|
||||
.expect("reading config.toml file failed");
|
||||
let config: Config = toml::from_str(&toml_str).expect("parsing config.toml file failed");
|
||||
println!("Connecting to serial port {}", config.interface.serial_port);
|
||||
|
||||
let mut serial = serialport::new(config.interface.serial_port, 115200)
|
||||
.open()
|
||||
.expect("opening serial port failed");
|
||||
|
||||
if cli.ping {
|
||||
let request = Request::Ping;
|
||||
let tc_encoded_raw = create_stm32f3_tc(&request);
|
||||
log::info!("Sending ping request");
|
||||
serial.write_all(&tc_encoded_raw).unwrap();
|
||||
}
|
||||
|
||||
if let Some(freq_ms) = cli.set_led_frequency {
|
||||
let request = Request::ChangeBlinkFrequency(Duration::from_millis(freq_ms as u64));
|
||||
let tc_encoded_raw = create_stm32f3_tc(&request);
|
||||
log::info!("Sending change blink frequency request: {:?}", request);
|
||||
serial.write_all(&tc_encoded_raw).unwrap();
|
||||
}
|
||||
|
||||
let mut cobs_decoder = CobsDecoderOwned::new(1024);
|
||||
log::info!("Waiting for response...");
|
||||
loop {
|
||||
let mut reception_buffer = [0u8; 1024];
|
||||
let received_bytes = serial.read(&mut reception_buffer);
|
||||
match received_bytes {
|
||||
Ok(0) => {
|
||||
std::thread::sleep(std::time::Duration::from_millis(100));
|
||||
}
|
||||
Ok(n) => {
|
||||
for byte in &reception_buffer[..n] {
|
||||
match cobs_decoder.feed(*byte) {
|
||||
Ok(Some(packet_len)) => {
|
||||
let reader = CcsdsPacketReader::new_with_checksum(
|
||||
&cobs_decoder.dest()[0..packet_len],
|
||||
);
|
||||
log::debug!("Received packet: {:?}", reader);
|
||||
}
|
||||
Ok(None) => (),
|
||||
Err(e) => {
|
||||
log::error!("COBS decoding error {e}, resetting decoder");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
if e.kind() != std::io::ErrorKind::TimedOut
|
||||
&& e.kind() != std::io::ErrorKind::WouldBlock
|
||||
{
|
||||
log::error!("Error reading from serial port: {:?}", e);
|
||||
}
|
||||
std::thread::sleep(std::time::Duration::from_millis(100));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn create_stm32f3_tc(request: &Request) -> Vec<u8> {
|
||||
let req_raw = postcard::to_allocvec(&request).unwrap();
|
||||
let sp_header = SpHeader::new_from_apid(satrs_stm32f3_disco_rtic::APID);
|
||||
let ccsds_tc_packet = CcsdsPacketCreator::new_tc_with_checksum(sp_header, &req_raw).unwrap();
|
||||
let tc_raw = ccsds_tc_packet.to_vec();
|
||||
cobs::encode_vec_including_sentinels(&tc_raw)
|
||||
}
|
||||
Reference in New Issue
Block a user