Start adding stop logic #3
@ -6,6 +6,8 @@ use satrs_mib::resultcode;
|
|||||||
use std::{collections::HashSet, net::Ipv4Addr};
|
use std::{collections::HashSet, net::Ipv4Addr};
|
||||||
use strum::IntoEnumIterator;
|
use strum::IntoEnumIterator;
|
||||||
|
|
||||||
|
pub const STOP_FILE_NAME: &str = "stop-experiment";
|
||||||
|
|
||||||
pub const OBSW_SERVER_ADDR: Ipv4Addr = Ipv4Addr::UNSPECIFIED;
|
pub const OBSW_SERVER_ADDR: Ipv4Addr = Ipv4Addr::UNSPECIFIED;
|
||||||
pub const SERVER_PORT: u16 = 7301;
|
pub const SERVER_PORT: u16 = 7301;
|
||||||
|
|
||||||
@ -124,4 +126,5 @@ pub mod tasks {
|
|||||||
pub const FREQ_MS_EVENT_HANDLING: u64 = 400;
|
pub const FREQ_MS_EVENT_HANDLING: u64 = 400;
|
||||||
pub const FREQ_MS_AOCS: u64 = 500;
|
pub const FREQ_MS_AOCS: u64 = 500;
|
||||||
pub const FREQ_MS_PUS_STACK: u64 = 200;
|
pub const FREQ_MS_PUS_STACK: u64 = 200;
|
||||||
|
pub const FREQ_MS_CTRL: u64 = 400;
|
||||||
}
|
}
|
||||||
|
@ -82,6 +82,7 @@ mod tests {
|
|||||||
sync::{Arc, Mutex},
|
sync::{Arc, Mutex},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use ops_sat_rs::config::{components, OBSW_SERVER_ADDR};
|
||||||
use satrs::{
|
use satrs::{
|
||||||
spacepackets::{
|
spacepackets::{
|
||||||
ecss::{tc::PusTcCreator, WritablePusPacket},
|
ecss::{tc::PusTcCreator, WritablePusPacket},
|
||||||
@ -89,7 +90,6 @@ mod tests {
|
|||||||
},
|
},
|
||||||
tmtc::ReceivesTcCore,
|
tmtc::ReceivesTcCore,
|
||||||
};
|
};
|
||||||
use ops_sat_rs::config::{components, OBSW_SERVER_ADDR};
|
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
44
src/main.rs
44
src/main.rs
@ -1,15 +1,18 @@
|
|||||||
use std::{
|
use std::{
|
||||||
net::{IpAddr, SocketAddr},
|
net::{IpAddr, SocketAddr},
|
||||||
sync::mpsc,
|
sync::{atomic::AtomicBool, mpsc, Arc},
|
||||||
thread,
|
thread,
|
||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
|
|
||||||
use log::info;
|
use log::info;
|
||||||
use ops_sat_rs::config::tasks::FREQ_MS_PUS_STACK;
|
|
||||||
use ops_sat_rs::config::{
|
use ops_sat_rs::config::{
|
||||||
tasks::FREQ_MS_UDP_TMTC, OBSW_SERVER_ADDR, PACKET_ID_VALIDATOR, SERVER_PORT,
|
tasks::FREQ_MS_UDP_TMTC, OBSW_SERVER_ADDR, PACKET_ID_VALIDATOR, SERVER_PORT,
|
||||||
};
|
};
|
||||||
|
use ops_sat_rs::config::{
|
||||||
|
tasks::{FREQ_MS_CTRL, FREQ_MS_PUS_STACK},
|
||||||
|
STOP_FILE_NAME,
|
||||||
|
};
|
||||||
use satrs::{
|
use satrs::{
|
||||||
hal::std::{tcp_server::ServerConfig, udp_server::UdpTcServer},
|
hal::std::{tcp_server::ServerConfig, udp_server::UdpTcServer},
|
||||||
tmtc::CcsdsDistributor,
|
tmtc::CcsdsDistributor,
|
||||||
@ -36,10 +39,11 @@ mod requests;
|
|||||||
mod tm_funnel;
|
mod tm_funnel;
|
||||||
mod tmtc;
|
mod tmtc;
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
fn main() {
|
fn main() {
|
||||||
setup_logger().expect("setting up logging with fern failed");
|
setup_logger().expect("setting up logging with fern failed");
|
||||||
println!("OPS-SAT Rust experiment OBSW");
|
println!("OPS-SAT Rust Experiment OBSW");
|
||||||
|
|
||||||
|
let stop_signal = Arc::new(AtomicBool::new(false));
|
||||||
|
|
||||||
let (tc_source_tx, tc_source_rx) = mpsc::channel();
|
let (tc_source_tx, tc_source_rx) = mpsc::channel();
|
||||||
let (tm_funnel_tx, tm_funnel_rx) = mpsc::channel();
|
let (tm_funnel_tx, tm_funnel_rx) = mpsc::channel();
|
||||||
@ -152,6 +156,23 @@ fn main() {
|
|||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
let ctrl_stop_signal = stop_signal.clone();
|
||||||
|
let jh_ctrl_thread = thread::Builder::new()
|
||||||
|
.name("CTRL".to_string())
|
||||||
|
.spawn(move || loop {
|
||||||
|
// TODO: Check stop file status regularly. If it exists, set the stop signal.
|
||||||
|
if std::path::Path::new(STOP_FILE_NAME).exists() {
|
||||||
|
log::warn!(
|
||||||
|
"Detected stop file name at {}. Initiating experiment shutdown",
|
||||||
|
STOP_FILE_NAME
|
||||||
|
);
|
||||||
|
ctrl_stop_signal.store(true, std::sync::atomic::Ordering::Relaxed);
|
||||||
|
}
|
||||||
|
thread::sleep(Duration::from_millis(FREQ_MS_CTRL));
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let tcp_stop_signal = stop_signal.clone();
|
||||||
info!("Starting TCP task");
|
info!("Starting TCP task");
|
||||||
let jh_tcp = thread::Builder::new()
|
let jh_tcp = thread::Builder::new()
|
||||||
.name("TCP".to_string())
|
.name("TCP".to_string())
|
||||||
@ -159,27 +180,42 @@ fn main() {
|
|||||||
info!("Running TCP server on port {SERVER_PORT}");
|
info!("Running TCP server on port {SERVER_PORT}");
|
||||||
loop {
|
loop {
|
||||||
tcp_server.periodic_operation();
|
tcp_server.periodic_operation();
|
||||||
|
if tcp_stop_signal.load(std::sync::atomic::Ordering::Relaxed) {
|
||||||
|
log::warn!("breaking0");
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
info!("Starting TM funnel task");
|
info!("Starting TM funnel task");
|
||||||
|
let funnel_stop_signal = stop_signal.clone();
|
||||||
let jh_tm_funnel = thread::Builder::new()
|
let jh_tm_funnel = thread::Builder::new()
|
||||||
.name("TM Funnel".to_string())
|
.name("TM Funnel".to_string())
|
||||||
.spawn(move || loop {
|
.spawn(move || loop {
|
||||||
tm_funnel.operation();
|
tm_funnel.operation();
|
||||||
|
if funnel_stop_signal.load(std::sync::atomic::Ordering::Relaxed) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
info!("Starting PUS handler thread");
|
info!("Starting PUS handler thread");
|
||||||
|
let pus_stop_signal = stop_signal.clone();
|
||||||
let jh_pus_handler = thread::Builder::new()
|
let jh_pus_handler = thread::Builder::new()
|
||||||
.name("PUS".to_string())
|
.name("PUS".to_string())
|
||||||
.spawn(move || loop {
|
.spawn(move || loop {
|
||||||
pus_stack.periodic_operation();
|
pus_stack.periodic_operation();
|
||||||
|
if pus_stop_signal.load(std::sync::atomic::Ordering::Relaxed) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
thread::sleep(Duration::from_millis(FREQ_MS_PUS_STACK));
|
thread::sleep(Duration::from_millis(FREQ_MS_PUS_STACK));
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
jh_ctrl_thread
|
||||||
|
.join()
|
||||||
|
.expect("Joining Controller thread failed");
|
||||||
jh_udp_tmtc
|
jh_udp_tmtc
|
||||||
.join()
|
.join()
|
||||||
.expect("Joining UDP TMTC server thread failed");
|
.expect("Joining UDP TMTC server thread failed");
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
use std::{
|
use std::time::Instant;
|
||||||
collections::HashMap,
|
use std::{collections::HashMap, sync::mpsc, time::Duration};
|
||||||
sync::mpsc::{self},
|
|
||||||
};
|
|
||||||
|
|
||||||
use log::info;
|
use log::info;
|
||||||
use satrs::pus::PusTmAsVec;
|
use satrs::pus::PusTmAsVec;
|
||||||
@ -76,6 +74,7 @@ impl TmFunnelCommon {
|
|||||||
|
|
||||||
pub struct TmFunnelDynamic {
|
pub struct TmFunnelDynamic {
|
||||||
common: TmFunnelCommon,
|
common: TmFunnelCommon,
|
||||||
|
last_ctrl_check: Instant,
|
||||||
tm_funnel_rx: mpsc::Receiver<PusTmAsVec>,
|
tm_funnel_rx: mpsc::Receiver<PusTmAsVec>,
|
||||||
tm_server_tx: mpsc::Sender<PusTmAsVec>,
|
tm_server_tx: mpsc::Sender<PusTmAsVec>,
|
||||||
}
|
}
|
||||||
@ -90,20 +89,47 @@ impl TmFunnelDynamic {
|
|||||||
common: TmFunnelCommon::new(sync_tm_tcp_source),
|
common: TmFunnelCommon::new(sync_tm_tcp_source),
|
||||||
tm_funnel_rx,
|
tm_funnel_rx,
|
||||||
tm_server_tx,
|
tm_server_tx,
|
||||||
|
last_ctrl_check: Instant::now(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn check_for_ctrl_check(&mut self) -> bool {
|
||||||
|
if Instant::now() - self.last_ctrl_check > Duration::from_millis(400) {
|
||||||
|
self.last_ctrl_check = Instant::now();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
pub fn operation(&mut self) {
|
pub fn operation(&mut self) {
|
||||||
if let Ok(mut tm) = self.tm_funnel_rx.recv() {
|
loop {
|
||||||
|
match self.tm_funnel_rx.recv_timeout(Duration::from_millis(100)) {
|
||||||
|
Ok(mut tm) => {
|
||||||
// Read the TM, set sequence counter and message counter, and finally update
|
// Read the TM, set sequence counter and message counter, and finally update
|
||||||
// the CRC.
|
// the CRC.
|
||||||
let zero_copy_writer = PusTmZeroCopyWriter::new(&mut tm.packet, MIN_CDS_FIELD_LEN)
|
let zero_copy_writer =
|
||||||
|
PusTmZeroCopyWriter::new(&mut tm.packet, MIN_CDS_FIELD_LEN)
|
||||||
.expect("Creating TM zero copy writer failed");
|
.expect("Creating TM zero copy writer failed");
|
||||||
self.common.apply_packet_processing(zero_copy_writer);
|
self.common.apply_packet_processing(zero_copy_writer);
|
||||||
self.common.sync_tm_tcp_source.add_tm(&tm.packet);
|
self.common.sync_tm_tcp_source.add_tm(&tm.packet);
|
||||||
self.tm_server_tx
|
self.tm_server_tx
|
||||||
.send(tm)
|
.send(tm)
|
||||||
.expect("Sending TM to server failed");
|
.expect("Sending TM to server failed");
|
||||||
|
if self.check_for_ctrl_check() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => match e {
|
||||||
|
mpsc::RecvTimeoutError::Timeout => {
|
||||||
|
if self.check_for_ctrl_check() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mpsc::RecvTimeoutError::Disconnected => {
|
||||||
|
log::warn!("All TM funnel senders have disconnected");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user