sat-rs/satrs-example/src/main.rs

211 lines
7.5 KiB
Rust
Raw Normal View History

2022-09-03 13:47:25 +02:00
mod ccsds;
2022-12-19 17:03:26 +01:00
mod hk;
2022-08-29 01:33:32 +02:00
mod pus;
2022-12-19 17:03:26 +01:00
mod requests;
2022-08-29 01:33:32 +02:00
mod tmtc;
2022-12-19 17:03:26 +01:00
use crate::requests::Request;
use crate::tmtc::{core_tmtc_task, CoreTmtcArgs, RequestTargetId, TmStore, PUS_APID};
2022-11-20 19:54:14 +01:00
use satrs_core::event_man::{
EventManagerWithMpscQueue, MpscEventReceiver, MpscEventU32SendProvider, SendEventProvider,
};
2022-11-20 19:54:14 +01:00
use satrs_core::events::EventU32;
use satrs_core::hal::host::udp_server::UdpTcServer;
use satrs_core::pool::{LocalPool, PoolCfg, SharedPool, StoreAddr};
use satrs_core::pus::event_man::{
2022-11-13 21:07:16 +01:00
DefaultPusMgmtBackendProvider, EventReporter, EventRequest, EventRequestWithToken,
PusEventDispatcher,
};
2022-11-21 10:28:31 +01:00
use satrs_core::pus::verification::{
MpscVerifSender, VerificationReporterCfg, VerificationReporterWithSender,
};
2022-11-20 19:54:14 +01:00
use satrs_core::pus::{EcssTmError, EcssTmSender};
2022-11-21 10:28:31 +01:00
use satrs_core::seq_count::SimpleSeqCountProvider;
2022-11-20 19:54:14 +01:00
use satrs_core::tmtc::CcsdsError;
use satrs_example::{OBSW_SERVER_ADDR, SERVER_PORT};
2022-12-08 15:26:49 +01:00
use spacepackets::time::cds::TimeProvider;
use spacepackets::time::TimeWriter;
2022-11-13 21:07:16 +01:00
use spacepackets::tm::PusTm;
2022-12-19 17:03:26 +01:00
use std::collections::HashMap;
2022-08-29 01:33:32 +02:00
use std::net::{IpAddr, SocketAddr};
2022-12-21 09:47:27 +01:00
use std::sync::mpsc::{channel, TryRecvError};
use std::sync::{mpsc, Arc, RwLock};
2022-08-29 01:33:32 +02:00
use std::thread;
2022-12-20 15:33:00 +01:00
use std::time::Duration;
2022-08-29 01:33:32 +02:00
struct TmFunnel {
tm_funnel_rx: mpsc::Receiver<StoreAddr>,
tm_server_tx: mpsc::Sender<StoreAddr>,
}
struct UdpTmtcServer {
udp_tc_server: UdpTcServer<CcsdsError<()>>,
tm_rx: mpsc::Receiver<StoreAddr>,
2022-09-10 13:34:04 +02:00
tm_store: SharedPool,
2022-08-29 01:33:32 +02:00
}
unsafe impl Send for UdpTmtcServer {}
2022-11-21 10:28:31 +01:00
#[derive(Clone)]
2022-11-13 21:07:16 +01:00
struct EventTmSender {
store_helper: TmStore,
sender: mpsc::Sender<StoreAddr>,
}
impl EventTmSender {
fn new(store_helper: TmStore, sender: mpsc::Sender<StoreAddr>) -> Self {
Self {
store_helper,
sender,
}
}
}
impl EcssTmSender for EventTmSender {
type Error = mpsc::SendError<StoreAddr>;
fn send_tm(&mut self, tm: PusTm) -> Result<(), EcssTmError<Self::Error>> {
let addr = self.store_helper.add_pus_tm(&tm);
self.sender.send(addr).map_err(EcssTmError::SendError)
}
}
2022-08-29 01:33:32 +02:00
fn main() {
2022-09-03 13:47:25 +02:00
println!("Running OBSW example");
2022-08-29 01:33:32 +02:00
let pool_cfg = PoolCfg::new(vec![(8, 32), (4, 64), (2, 128)]);
let tm_pool = LocalPool::new(pool_cfg);
2022-09-10 13:34:04 +02:00
let tm_store: SharedPool = Arc::new(RwLock::new(Box::new(tm_pool)));
let tm_store_helper = TmStore {
pool: tm_store.clone(),
};
2022-08-29 01:33:32 +02:00
let addr = SocketAddr::new(IpAddr::V4(OBSW_SERVER_ADDR), SERVER_PORT);
2022-11-13 21:07:16 +01:00
let (tm_funnel_tx, tm_funnel_rx) = channel();
let (tm_server_tx, tm_server_rx) = channel();
2022-09-10 13:34:04 +02:00
let sender = MpscVerifSender::new(tm_store.clone(), tm_funnel_tx.clone());
2022-11-21 10:28:31 +01:00
let verif_cfg = VerificationReporterCfg::new(
PUS_APID,
2022-12-20 17:23:11 +01:00
#[allow(clippy::box_default)]
2022-11-21 10:28:31 +01:00
Box::new(SimpleSeqCountProvider::default()),
1,
2,
8,
)
.unwrap();
let reporter_with_sender_0 = VerificationReporterWithSender::new(&verif_cfg, Box::new(sender));
2022-11-13 21:07:16 +01:00
// Create event handling components
let (event_request_tx, event_request_rx) = channel::<EventRequestWithToken>();
let (event_sender, event_man_rx) = channel();
let event_recv = MpscEventReceiver::<EventU32>::new(event_man_rx);
let mut event_man = EventManagerWithMpscQueue::new(Box::new(event_recv));
let event_reporter = EventReporter::new(PUS_APID, 128).unwrap();
let pus_tm_backend = DefaultPusMgmtBackendProvider::<EventU32>::default();
2022-11-13 21:07:16 +01:00
let mut pus_event_dispatcher =
PusEventDispatcher::new(event_reporter, Box::new(pus_tm_backend));
let (pus_event_man_tx, pus_event_man_rx) = channel();
let pus_event_man_send_provider = MpscEventU32SendProvider::new(1, pus_event_man_tx);
let mut reporter1 = reporter_with_sender_0.clone();
event_man.subscribe_all(pus_event_man_send_provider.id());
2022-11-13 21:07:16 +01:00
2022-12-19 17:03:26 +01:00
let mut request_map = HashMap::new();
let (acs_thread_tx, acs_thread_rx) = channel::<Request>();
request_map.insert(RequestTargetId::AcsSubsystem as u32, acs_thread_tx);
2022-11-13 21:07:16 +01:00
// Create clones here to allow move for thread 0
let core_args = CoreTmtcArgs {
tm_store: tm_store_helper.clone(),
tm_sender: tm_funnel_tx.clone(),
event_sender,
event_request_tx,
2022-12-19 17:03:26 +01:00
request_map,
2022-11-13 21:07:16 +01:00
};
2022-11-20 18:45:11 +01:00
println!("Starting TMTC task");
2022-08-29 01:33:32 +02:00
let jh0 = thread::spawn(move || {
2022-11-13 21:07:16 +01:00
core_tmtc_task(core_args, tm_server_rx, addr, reporter_with_sender_0);
2022-08-29 01:33:32 +02:00
});
2022-11-20 18:45:11 +01:00
println!("Starting TM funnel task");
2022-08-29 01:33:32 +02:00
let jh1 = thread::spawn(move || {
let tm_funnel = TmFunnel {
tm_server_tx,
tm_funnel_rx,
};
loop {
if let Ok(addr) = tm_funnel.tm_funnel_rx.recv() {
tm_funnel
.tm_server_tx
.send(addr)
.expect("Sending TM to server failed");
}
}
});
2022-11-20 18:45:11 +01:00
println!("Starting event handling task");
2022-11-13 21:07:16 +01:00
let jh2 = thread::spawn(move || {
let mut timestamp: [u8; 7] = [0; 7];
let mut sender = EventTmSender::new(tm_store_helper, tm_funnel_tx);
2022-12-08 15:26:49 +01:00
let mut time_provider = TimeProvider::new_with_u16_days(0, 0);
let mut report_completion = |event_req: EventRequestWithToken, timestamp: &[u8]| {
reporter1
2022-11-13 21:07:16 +01:00
.completion_success(event_req.token, timestamp)
.expect("Sending completion success failed");
};
loop {
if let Ok(event_req) = event_request_rx.try_recv() {
match event_req.request {
EventRequest::Enable(event) => {
pus_event_dispatcher
.enable_tm_for_event(&event)
.expect("Enabling TM failed");
update_time(&mut time_provider, &mut timestamp);
report_completion(event_req, &timestamp);
}
EventRequest::Disable(event) => {
pus_event_dispatcher
.disable_tm_for_event(&event)
.expect("Disabling TM failed");
update_time(&mut time_provider, &mut timestamp);
report_completion(event_req, &timestamp);
}
}
}
if let Ok((event, _param)) = pus_event_man_rx.try_recv() {
update_time(&mut time_provider, &mut timestamp);
pus_event_dispatcher
.generate_pus_event_tm_generic(&mut sender, &timestamp, event, None)
.expect("Sending TM as event failed");
}
}
});
2022-12-20 15:33:00 +01:00
println!("Starting AOCS thread");
let jh3 = thread::spawn(move || loop {
match acs_thread_rx.try_recv() {
2022-12-21 09:47:27 +01:00
Ok(request) => {
println!("ACS thread: Received request {:?}", request)
}
Err(e) => match e {
TryRecvError::Empty => {}
TryRecvError::Disconnected => {
println!("ACS thread: Message Queue TX disconnected!")
}
},
2022-12-20 15:33:00 +01:00
}
thread::sleep(Duration::from_millis(500));
});
2022-08-29 01:33:32 +02:00
jh0.join().expect("Joining UDP TMTC server thread failed");
jh1.join().expect("Joining TM Funnel thread failed");
jh2.join().expect("Joining Event Manager thread failed");
2022-12-20 15:33:00 +01:00
jh3.join().expect("Joining AOCS thread failed");
2022-08-29 01:33:32 +02:00
}
2022-11-13 21:07:16 +01:00
2022-12-08 15:26:49 +01:00
pub fn update_time(time_provider: &mut TimeProvider, timestamp: &mut [u8]) {
2022-11-13 21:07:16 +01:00
time_provider
.update_from_now()
.expect("Could not get current time");
time_provider
.write_to_bytes(timestamp)
.expect("Writing timestamp failed");
}