try to update more chapters

This commit is contained in:
Robin Mueller
2026-08-26 15:24:08 +02:00
parent 2d9b14e69e
commit 4ba4d3e6a3
32 changed files with 2111 additions and 1901 deletions
+1 -1
View File
@@ -10,7 +10,7 @@ toml = "0.9"
serde = { version = "1", features = ["derive"] }
spacepackets = { version = "0.18" }
embedded-types = { path = "../types" }
tmtc-utils = { git = "https://egit.irs.uni-stuttgart.de/rust/tmtc-utils.git", version = "0.1", rev = "d8015379a45e77400dd9c71afbf22ca415ed67d1" }
tmtc-utils = { path = "../../tmtc-utils" }
postcard = { version = "1", features = ["alloc"] }
anyhow = "1"
cobs = "0.5"
+4 -5
View File
@@ -81,15 +81,14 @@ This is a protocol which already provides us with some useful fields:
- Basic sequence counter which can be used to determine missed packets
However, how does the actual payload that we want to send to or from the satellite actually look
like? While there are standards like the Packet Utilisation Standard (PUS), we recommend a payload
format which is created with the excellent [`serde`](https://serde.rs/) library. The
[TMTC modelling](./tmtc-modelling.md) chapter provides more information.
like? We recommend a payload format which is created with the excellent [`serde`](https://serde.rs/)
library. The [TMTC modelling](./tmtc-modelling.md) chapter provides more information.
# Low-level protocols and the bridge to the communcation subsystem
Many satellite systems usually use the lower levels of the OSI layer in addition to the application
layer covered by the PUS standard or the CCSDS space packets standard. This oftentimes requires
special hardware like dedicated FPGAs to handle forward error correction fast enough. `sat-rs`
layer. This oftentimes requires special hardware like dedicated FPGAs to handle forward error
correction fast enough. `sat-rs`
might provide components to handle standard like the Unified Space Data Link Standard (USLP) in
software but most of the time the handling of communication is performed through custom
software and hardware. Still, connecting this custom software and hardware to `sat-rs` can mostly
-20
View File
@@ -2,23 +2,3 @@
Events are an important mechanism used for remote systems to monitor unexpected
or expected anomalies and events occuring on these systems.
One common use case for events on remote systems is to offer a light-weight publish-subscribe
mechanism and IPC mechanism for software and hardware events which are also packaged as telemetry
(TM) or can trigger a system response. They can also be tied to
Fault Detection, Isolation and Recovery (FDIR) operations, which need to happen autonomously.
The PUS Service 5 standardizes how the ground interface for events might look like, but does not
specify how other software components might react to those events. There is the PUS Service 19,
which might be used for that purpose, but the event components recommended by this framework do not
rely on the present of this service.
The following images shows how the flow of events could look like in a system where components
can generate events, and where other system components might be interested in those events:
![Event flow](images/events/event_man_arch.png)
For the concrete implementation of your own event management and/or event routing system, you
can have a look at the event management documentation inside the
[API documentation](https://docs.rs/satrs/latest/satrs/event_man/index.html) where you can also
find references to all examples.
+68 -100
View File
@@ -12,10 +12,59 @@ The example project contains components which could also be expected to be part
On-Board Software. A structural diagram of the example application is given to provide
a brief high-level view of the components used inside the example application:
![satrs-example component structure](images/satrs-example/satrs-example-structure.png)
```mermaid
flowchart TD
subgraph TMTC[TMTC Infrastructure]
subgraph TMTCRow1[ ]
direction LR
Udp[UDP Server]
Tcp[TCP Server]
end
subgraph TMTCRow2[ ]
direction LR
Source[TC Source]
Sink[TM Sink]
end
end
The dotted lines are used to denote optional components. In this case, the static pool components
are optional because the heap can be used as a simpler mechanism to store TMTC packets as well.
subgraph AOCS[AOCS Stack]
subgraph AOCSRow1[ ]
direction LR
Mgm0[MGM 0 Handler]
Mgm1[MGM 1 Handler]
Assy[MGM Assembly]
end
subgraph AOCSRow2[ ]
direction LR
AcsCtrl[ACS Controller]
Mgt[MGT Handler]
AcsSub[ACS Subsystem]
end
end
subgraph EPS[EPS Stack]
Pcdu[PCDU Handler]
end
subgraph Core[Core]
direction LR
Ctrl[Core Controller]
Evt[Event Manager]
end
Sim[Sim Client]:::optional
TMTC ~~~ EPS
AOCS ~~~ Core
Core ~~~ Sim
classDef optional stroke-dasharray: 5 5;
classDef invisible fill:none,stroke:none;
class TMTCRow1,TMTCRow2,AOCSRow1,AOCSRow2 invisible;
```
The dotted lines are used to denote optional components. In this case, the simulation client is
optional because a dummy interface can be used instead to run the example without the simulator.
Some additional explanation is provided for the various components.
### TCP/IP server components
@@ -37,116 +86,35 @@ telecommands from the client.
The most important components of the TMTC infrastructure include the following components:
- A TC source component which demultiplexes and routes telecommands based on parameters like
packet APID or PUS service and subservice type.
packet APID and a target ID which is part of the packet payload.
- A TM sink sink component which is the target of all sent telemetry and sends it to downlink
handlers like the UDP and TCP server.
You can read the [Communications chapter](./communication.md) for more
background information on the chosen TMTC infrastructure approach.
### PUS Service Components
A PUS service stack is provided which exposes some functionality conformant with the ECSS PUS
services. This currently includes the following services:
- Service 1 for telecommand verification. The verification handling is handled locally: Each
component which generates verification telemetry in some shape or form receives a
[reporter](https://docs.rs/satrs/latest/satrs/pus/verification/struct.VerificationReporterWithSender.html)
object which can be used to send PUS 1 verification telemetry to the TM funnel.
- Service 3 for housekeeping telemetry handling.
- Service 5 for management and downlink of on-board events.
- Service 8 for handling on-board actions.
- Service 11 for scheduling telecommands to be released at a specific time. This component
uses the [PUS scheduler class](https://docs.rs/satrs/latest/satrs/pus/scheduler/alloc_mod/struct.PusScheduler.html)
which performs the core logic of scheduling telecommands. All telecommands released by the
scheduler are sent to the central TC source using a message.
- Service 17 for test purposes like pings.
### Event Management Component
An event manager based on the sat-rs
[event manager component](https://docs.rs/satrs/latest/satrs/event_man/index.html)
is provided to handle the event IPC and FDIR mechanism. The event message are converted to PUS 5
telemetry by the
[PUS event dispatcher](https://docs.rs/satrs/latest/satrs/pus/event_man/alloc_mod/struct.PusEventDispatcher.html).
You can read the [events](./events.md) chapter for more in-depth information about event management.
### Sample Application Components
These components are example mission specific. They provide an idea how mission specific modules
would look like the sat-rs context. It currently includes the following components:
- An Attitute and Orbit Control (AOCS) example task which can also process some PUS commands.
## Dataflow
The interaction of the various components is provided in the following diagram:
### TMTC component group
![satrs-example dataflow diagram](images/satrs-example/satrs-example-dataflow.png)
It should be noted that an arrow coming out of a component group refers to multiple components
in that group. An explanation for important component groups will be given.
#### TMTC component group
This groups is the primary interface for clients to communicate with the on-board software
using a standardized TMTC protocol. The example uses the
[ECSS PUS protocol](https://ecss.nl/standard/ecss-e-st-70-41c-space-engineering-telemetry-and-telecommand-packet-utilization-15-april-2016/).
This group is the primary interface for clients to communicate with the on-board software
using the combination of CCSDS space packets and `serde` serialized payloads.
In the future, this might be extended with the
[CCSDS File Delivery Protocol](https://public.ccsds.org/Pubs/727x0b5.pdf).
A client can connect to the UDP or TCP server to send these PUS packets to the on-board software.
These servers then forward the telecommads to a centralized TC source component using a dedicated
message abstraction.
A client can connect to the UDP or TCP server to send telecommands to the on-board software.
These servers forward all telecommands to a centralized TC source component, which demultiplexes
them and routes each one to its target component.
This TC source component then demultiplexes the message and forwards it to the relevant components.
Right now, it forwards all PUS requests to the respective PUS service handlers using the PUS
receiver component. The individual PUS services are running in a separate thread. In the future,
additional forwarding to components like a CFDP handler might be added as well. It should be noted
that PUS11 commands might contain other PUS commands which should be scheduled in the future.
These wrapped commands are forwarded to the PUS11 handler. When the schedule releases those
commands, it forwards the released commands to the TC source again. This allows the scheduler
and the TC source to run in separate threads and keeps them cleanly separated.
All telemetry generated by the on-board software is sent to a centralized TM sink. The core
controller also forwards events to the event manager, which converts them into telemetry and
sends it to the TM sink as well. The TM sink performs a demultiplexing step to forward all
telemetry to the relevant recipients, which in the example case are the last connected UDP
client and any connected TCP client.
All telemetry generated by the on-board software is sent to a centralized TM funnel. This component
also performs a demultiplexing step to forward all telemetry to the relevant TM recipients.
In the example case, this is the last UDP client, or a connected TCP client. In the future,
forwarding to a persistent telemetry store and a simulated communication component might be
added here as well. The centralized TM funnel also takes care of some packet processing steps which
need to be applied for each ECSS PUS packet, for example CCSDS specific APID incrementation and
PUS specific message counter incrementation.
### Application Group
#### Application Group
The application group contain some components you might also find in a real satellite software.
This includes an AOCS stack with various device handlers and system level objects.
The application components generally do not receive raw PUS packets directly, even though
this is certainly possible. Instead, they receive internalized messages from the PUS service
handlers. For example, instead of receiving a PUS 8 Action Telecommand directly, an application
component will receive a special `ActionRequest` message type reduced to the basic important
information required to execute a request. These special requests are denoted by the blue arrow
in the diagram.
It should be noted that the arrow pointing towards the event manager points in both directions.
This is because the application components might be interested in events generated by other
components as well. This mechanism is oftentimes used to implement the FDIR functionality on system
and component level.
#### Shared components and functional interfaces
It should be noted that sometimes, a functional interface is used instead of a message. This
is used for the generation of verification telemetry. The verification reporter is a clonable
component which generates and sends PUS1 verification telemetry directly to the TM funnel. This
introduces a loose coupling to the PUS standard but was considered the easiest solution for
a project which utilizes PUS as the main communication protocol. In the future, a generic
verification abstraction might be introduced to completely decouple the application layer from
PUS.
The same concept is applied if the backing store of TMTC packets are shared pools. Every
component which needs to read telecommands inside that shared pool or generate new telemetry
into that shared pool will received a clonable shared handle to that pool.
The same concept could be extended to power or thermal handling. For example, a shared power helper
component might be used to retrieve power state information and send power switch commands through
a functional interface. The actual implementation of the functional interface might still use
shared memory and/or messages, but the functional interface makes using and testing the interaction
with these components easier.
### Shared components and functional interfaces
+90 -7
View File
@@ -1,11 +1,12 @@
# Housekeeping Data
If you have not read [the TMTC modelling chapter](./tmtc-modelling.md) yet, it is recommended to
do that first.
Remote systems like satellites and rovers oftentimes generate data autonomously and periodically.
The most common example for this is temperature or attitude data. Data like this is commonly
An example for this could be temperature or attitude data. Data like this is commonly
referred to as housekeeping data, and is usually one of the most important and most resource heavy
data sources received from a satellite. Standards like the PUS Service 3 make recommendation how to
expose housekeeping data, but the applicability of the interface offered by PUS 3 has proven to be
partially difficult and clunky for modular systems.
data sources received from a satellite.
First, we are going to list some assumption and requirements about Housekeeping (HK) data:
@@ -18,7 +19,89 @@ First, we are going to list some assumption and requirements about Housekeeping
3. HK data often needs to be shared to other software components. For example, a thermal controller
wants to read the data samples of all sensor components.
A commonly required way to model HK data in a clean way is also to group related HK data into sets,
which can then dumped via a similar interface.
## Modelling our data
TODO: Write down `sat-rs` recommendations how to expose and work with HK data.
Generally, it makes sense to model the data with Rust data structures for various reasons. For
example, the sensor data received from a 3-axis magnetometer might me modelled like this:
```rust
#[derive(Debug, Copy, Clone, serde::Serialize, serde::Deserialize)]
pub struct MgmData {
pub x: i16,
pub y: i16,
pub z: i16,
}
```
You can then re-use this data structure for various purposes. Also note the `serde` implementations,
which are useful for generating the housekeeping data sent to ground.
We can model the housekeeping requests for a handler with a single data set like this:
```rust
#[derive(Debug, Copy, Clone, serde::Serialize, serde::Deserialize)]
pub enum HkRequest {
OneShot,
EnablePeriodic,
DisablePeriodic,
ModifyInterval(core::time::Duration)
}
```
which might then be a part of a top level request type, e.g.
```rust
#[derive(Debug, Copy, Clone, serde::Serialize, serde::Deserialize)]
pub enum Request {
Ping,
Hk(HkRequest)
}
```
A corresponding `Response` type might just include a HK data variant:
```rust
#[derive(Debug, Copy, Clone, serde::Serialize, serde::Deserialize)]
pub enum Response {
Ok,
Hk(MgmData)
}
```
If the software object managed multiple data sets, you could model it like this:
```rust
/// Example set ID.
#[derive(Debug, Copy, Clone, serde::Serialize, serde::Deserialize)]
pub enum SetId {
Data,
Config
}
#[derive(Debug, Copy, Clone, serde::Serialize, serde::Deserialize)]
pub enum Request {
Ping,
Hk {
set_id: SetId,
request: HkRequest
}
}
```
Sometimes, you need to share the generated data as well. Furthermore, it might make sense to
decouple the HK generation from the data acquisition and only return the latest snapshot
of the data. In this case, you can put the `MgmData` inside an appropriate lock structure for your
platform/runtime to share it safely with other software components. For example, in a `std` system,
you might simply use an `Arc<Mutex<MgmData>>` or a `Arc<RwLock<MgmData>>` for this.
Now, you can update that shared data structure when acquiring new data, and other software objects
or the HK generation routine can safely read from it.
## Helper components
You need some application logic to track whether periodic data generation is enabled, what
the current generation interval is and whether a HK set needs to be generated if the interval
period has elapsed.
`sat-rs` provides some simple helper components for this inside the [`hk`](https://docs.rs/satrs/latest/satrs/hk/index.html) module. The module documentation contains more information.
-4
View File
@@ -73,8 +73,6 @@ In summary, a component which has modes has to expose the following 4 capabiliti
3. Announce the mode
4. Announce the mode recursively
## Using ECSS PUS to perform mode commanding
# Health
Health is an important concept for systems and components which might fail.
@@ -99,5 +97,3 @@ could be power-cycled if there were multiple communication issues in the last ti
example, on operator might be interested in testing a component in isolation, and the interference
of the system is not desired. In that case, the `EXTERNAL CONTROL` health state might be used
to prevent mode commands from the system while allowing external mode commands.
+1 -1
View File
@@ -1,7 +1,7 @@
use arbitrary_int::u11;
use lazy_static::lazy_static;
use satrs::{
res_code::ResultU16,
legacy::res_code::ResultU16,
spacepackets::{PacketId, PacketType},
};
use satrs_mib::res_code::ResultU16Info;
@@ -5,7 +5,7 @@ use std::{
time::Duration,
};
use satrs::pus::HandlingStatus;
use satrs::HandlingStatus;
use satrs_minisim::{
SerializableSimMsgPayload, SimComponent, SimMessageProvider, SimReply, SimRequest,
udp::SIM_CTRL_PORT,
+1 -1
View File
@@ -4,8 +4,8 @@ use std::net::{SocketAddr, UdpSocket};
use std::sync::{Arc, Mutex, mpsc};
use log::warn;
use satrs::HandlingStatus;
use satrs::hal::std::udp_server::{ReceiveResult, UdpTcServer};
use satrs::pus::HandlingStatus;
use satrs::queue::GenericSendError;
use types::ccsds::CcsdsTmPacketOwned;
+3 -3
View File
@@ -21,8 +21,8 @@ use interface::{
use log::info;
use logger::setup_logger;
use satrs::{
HandlingStatus,
hal::std::{tcp_server::ServerConfig, udp_server::UdpTcServer},
pus::HandlingStatus,
spacepackets::time::cds::CdsTime,
};
use satrs_example::{
@@ -38,7 +38,7 @@ use types::{ComponentId, DeviceMode};
use crate::{
acs::{ctrl, mgm, mgm_assembly, mgt, subsystem},
control::Controller,
controller::Controller,
eps::pcdu::SwitchSet,
event_manager::EventManager,
interface::udp::UdpTmHandlerWithChannel,
@@ -47,7 +47,7 @@ use crate::{
mod acs;
mod ccsds;
mod control;
mod controller;
mod eps;
mod event_manager;
mod interface;
+1 -1
View File
@@ -1,5 +1,5 @@
use satrs::{
pus::HandlingStatus,
HandlingStatus,
spacepackets::{CcsdsPacketReader, ChecksumType},
tmtc::PacketAsVec,
};
+4
View File
@@ -8,6 +8,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
# [unreleased]
- Added `hk` module helpers to track whether a single HK set needs regeneration:
`SingleSetHkHelperStd` (`std`), `SingleSetHkHelperEmbassy` (new `embassy-time` feature),
and `SingleSetHkHelperCountdown`, generic over the existing `Countdown` trait.
# [v0.3.0-alpha.3] 2025-11-06
- Bump `sat-rs` edition to 2024.
+2
View File
@@ -35,6 +35,7 @@ socket2 = { version = "0.6", features = ["all"], optional = true }
arbitrary-int = "2"
mio = { version = "1", features = ["os-poll", "net"], optional = true }
defmt = { version = "1", optional = true }
embassy-time = { version = "0.5", optional = true }
[dev-dependencies]
serde = "1"
@@ -72,6 +73,7 @@ alloc = [
serde = ["dep:serde", "spacepackets/serde", "satrs-shared/serde"]
crossbeam = ["crossbeam-channel"]
defmt = ["dep:defmt", "spacepackets/defmt"]
embassy-time = ["dep:embassy-time"]
test_util = []
[package.metadata.docs.rs]
+181
View File
@@ -0,0 +1,181 @@
//! # HK generation helpers
//!
//! Each helper contains the minimal state to support the periodic generation of housekeeping
//! packets. Call [SingleSetHkHelperStd::needs_generation](crate::hk::SingleSetHkHelperStd::needs_generation) periodically, for example once per task
//! cycle. When it returns `true`, generate the HK set and send it, the helper has already reset
//! its clock for the next period.
//!
//! Pick a helper based on what clock is available:
//!
//! - [SingleSetHkHelperStd](crate::hk::SingleSetHkHelperStd): `std::time::Instant`, behind the `std` feature.
//! - [SingleSetHkHelperEmbassy](crate::hk::SingleSetHkHelperEmbassy): `embassy_time::Instant`, behind the `embassy-time` feature.
//! - [SingleSetHkHelperCountdown](crate::hk::SingleSetHkHelperCountdown): any clock implementing [Countdown](crate::time::Countdown), for example a
//! `fugit`-based monotonic.
//!
//! If your software object has multiple HK sets, you can simply put the helpers inside a dynamic
//! list like [alloc::vec::Vec], [heapless::vec::Vec] or a hash map.
#![deny(missing_docs)]
use crate::time::Countdown;
/// Generic single-set HK helper for any clock, backed by a [Countdown] implementation.
///
/// Useful for clocks not covered by [SingleSetHkHelperStd] or [SingleSetHkHelperEmbassy], for
/// example a `fugit`-based monotonic. Users implement [Countdown] for their clock and hand it in.
pub struct SingleSetHkHelperCountdown<C: Countdown> {
countdown: C,
enabled: bool,
}
impl<C: Countdown> SingleSetHkHelperCountdown<C> {
/// Create a new, enabled helper wrapping the given countdown.
pub fn new(countdown: C) -> Self {
Self {
countdown,
enabled: true,
}
}
/// Reference to the wrapped countdown.
pub fn countdown(&self) -> &C {
&self.countdown
}
/// Mutable reference to the wrapped countdown.
pub fn countdown_mut(&mut self) -> &mut C {
&mut self.countdown
}
/// Whether the helper is enabled.
pub fn enabled(&self) -> bool {
self.enabled
}
/// Enable or disable the helper.
pub fn set_enabled(&mut self, enabled: bool) {
self.enabled = enabled;
}
/// Returns true if the HK set needs regeneration, resetting the countdown.
///
/// Always returns false while disabled, leaving the countdown untouched.
pub fn needs_generation(&mut self) -> bool {
if !self.enabled {
return false;
}
if self.countdown.has_expired() {
self.countdown.reset();
return true;
}
false
}
}
/// Single-set HK helper backed by [std::time::Instant].
#[cfg(feature = "std")]
pub struct SingleSetHkHelperStd {
interval: core::time::Duration,
last_generated: std::time::Instant,
enabled: bool,
}
#[cfg(feature = "std")]
impl SingleSetHkHelperStd {
/// Create a new, enabled helper with the given interval, starting the clock now.
pub fn new(initial_interval: core::time::Duration) -> Self {
Self {
interval: initial_interval,
last_generated: std::time::Instant::now(),
enabled: true,
}
}
/// Update the generation interval.
pub fn update_interval(&mut self, interval: core::time::Duration) {
self.interval = interval;
}
/// Current generation interval.
pub fn interval(&self) -> core::time::Duration {
self.interval
}
/// Whether the helper is enabled.
pub fn enabled(&self) -> bool {
self.enabled
}
/// Enable or disable the helper.
pub fn set_enabled(&mut self, enabled: bool) {
self.enabled = enabled;
}
/// Returns true if the HK set needs regeneration.
///
/// Always returns false while disabled, leaving the clock untouched.
pub fn needs_generation(&mut self) -> bool {
if !self.enabled {
return false;
}
let now = std::time::Instant::now();
if now - self.last_generated > self.interval {
self.last_generated = now;
return true;
}
false
}
}
/// Single-set HK helper backed by [embassy_time::Instant].
#[cfg(feature = "embassy-time")]
pub struct SingleSetHkHelperEmbassy {
interval: embassy_time::Duration,
last_generated: embassy_time::Instant,
enabled: bool,
}
#[cfg(feature = "embassy-time")]
impl SingleSetHkHelperEmbassy {
/// Create a new, enabled helper with the given interval, starting the clock now.
pub fn new(initial_interval: embassy_time::Duration) -> Self {
Self {
interval: initial_interval,
last_generated: embassy_time::Instant::now(),
enabled: true,
}
}
/// Update the generation interval.
pub fn update_interval(&mut self, interval: embassy_time::Duration) {
self.interval = interval;
}
/// Current generation interval.
pub fn interval(&self) -> embassy_time::Duration {
self.interval
}
/// Whether the helper is enabled.
pub fn enabled(&self) -> bool {
self.enabled
}
/// Enable or disable the helper.
pub fn set_enabled(&mut self, enabled: bool) {
self.enabled = enabled;
}
/// Returns true if the HK set needs regeneration.
///
/// Always returns false while disabled, leaving the clock untouched.
pub fn needs_generation(&mut self) -> bool {
if !self.enabled {
return false;
}
let now = embassy_time::Instant::now();
if now - self.last_generated > self.interval {
self.last_generated = now;
return true;
}
false
}
}
+1 -1
View File
@@ -579,7 +579,7 @@ mod tests {
use super::*;
use crate::legacy::events::{EventErasedAlloc, Severity};
use crate::pus::test_util::{TEST_COMPONENT_ID_0, TEST_COMPONENT_ID_1};
use crate::legacy::pus::test_util::{TEST_COMPONENT_ID_0, TEST_COMPONENT_ID_1};
use std::sync::mpsc;
const TEST_GROUP_ID_0: u14 = u14::new(0);
+1 -1
View File
@@ -591,7 +591,7 @@ mod tests {
use crate::legacy::event_man_legacy::EventManager;
use crate::legacy::events_legacy::{EventU32, GenericEvent, Severity};
use crate::params::{ParamsHeapless, ParamsRaw};
use crate::pus::test_util::{TEST_COMPONENT_ID_0, TEST_COMPONENT_ID_1};
use crate::legacy::pus::test_util::{TEST_COMPONENT_ID_0, TEST_COMPONENT_ID_1};
use std::format;
use std::sync::mpsc::{self};
+2
View File
@@ -1,4 +1,6 @@
pub mod action;
pub mod event_man;
pub mod events;
pub mod res_code;
pub mod pus;
@@ -1,5 +1,5 @@
use crate::{
action::{ActionId, ActionRequest},
legacy::action::{ActionId, ActionRequest},
params::Params,
request::{GenericMessage, MessageMetadata, RequestId},
};
@@ -66,7 +66,7 @@ impl GenericActionReplyPus {
pub mod alloc_mod {
use crate::{
ComponentId,
action::ActionRequest,
legacy::action::ActionRequest,
queue::{GenericReceiveError, GenericSendError},
request::{
GenericMessage, MessageReceiverProvider, MessageSenderAndReceiver,
@@ -142,7 +142,7 @@ pub mod std_mod {
use crate::{
ComponentId,
pus::{
legacy::pus::{
ActivePusRequestStd, ActiveRequest, DefaultActiveRequestMap,
verification::{self, TcStateToken},
},
+2 -3
View File
@@ -1,4 +1,3 @@
use crate::pus::source_buffer_large_enough;
use arbitrary_int::u11;
use spacepackets::ByteConversionError;
use spacepackets::SpHeader;
@@ -110,7 +109,7 @@ impl EventReportCreator {
if let Some(aux_data) = params {
src_data_len += aux_data.len();
}
source_buffer_large_enough(src_data_buf.len(), src_data_len)?;
super::source_buffer_large_enough(src_data_buf.len(), src_data_len)?;
let sec_header = PusTmSecondaryHeader::new(
MessageTypeId::new(5, subservice.into()),
0,
@@ -137,7 +136,7 @@ impl EventReportCreator {
mod alloc_mod {
use super::*;
use crate::ComponentId;
use crate::pus::{EcssTmSender, EcssTmtcError};
use crate::legacy::pus::{EcssTmSender, EcssTmtcError};
use alloc::vec;
use alloc::vec::Vec;
use core::cell::RefCell;
File diff suppressed because it is too large Load Diff
@@ -1,12 +1,12 @@
use super::PusPacketHandlingError;
use super::scheduler::PusScheduler;
use super::verification::{VerificationReporter, VerificationReportingProvider};
use super::{
CacheAndReadRawEcssTc, DirectPusPacketHandlerResult, EcssTcInSharedPoolCacher, EcssTcReceiver,
EcssTcVecCacher, EcssTmSender, HandlingStatus, MpscTcReceiver, PartialPusHandlingError,
PusServiceHelper,
EcssTcVecCacher, EcssTmSender, MpscTcReceiver, PartialPusHandlingError, PusServiceHelper,
};
use crate::HandlingStatus;
use crate::pool::PoolProvider;
use crate::pus::PusPacketHandlingError;
use crate::tmtc::{PacketAsVec, PacketSenderWithSharedPool};
use alloc::string::ToString;
use spacepackets::ecss::{PusPacket, scheduling};
@@ -247,12 +247,14 @@ pub type PusService11SchedHandlerStaticWithBoundedMpsc<PusScheduler> = PusSchedS
#[cfg(test)]
mod tests {
use crate::legacy::pus::test_util::{PusTestHarness, TEST_APID};
use crate::legacy::pus::verification::{VerificationReporter, VerificationReportingProvider};
use crate::pool::{StaticMemoryPool, StaticPoolConfig};
use crate::pus::test_util::{PusTestHarness, TEST_APID};
use crate::pus::verification::{VerificationReporter, VerificationReportingProvider};
use crate::pus::{DirectPusPacketHandlerResult, MpscTcReceiver, PusPacketHandlingError};
use crate::pus::{
use crate::legacy::pus::{
DirectPusPacketHandlerResult, MpscTcReceiver, PusPacketHandlingError,
};
use crate::legacy::pus::{
EcssTcInSharedPoolCacher,
scheduler::{self, PusScheduler, TcInfo},
tests::PusServiceHandlerWithSharedStoreCommon,
@@ -377,8 +379,8 @@ mod tests {
fn insert_unwrapped_and_stored_tc(
&mut self,
_time_stamp: spacepackets::time::UnixTime,
info: crate::pus::scheduler::TcInfo,
) -> Result<(), crate::pus::scheduler::ScheduleError> {
info: crate::legacy::pus::scheduler::TcInfo,
) -> Result<(), crate::legacy::pus::scheduler::ScheduleError> {
self.inserted_tcs.push_back(info);
Ok(())
}
@@ -1,4 +1,4 @@
use crate::pus::{
use super::{
DirectPusPacketHandlerResult, PartialPusHandlingError, PusPacketHandlingError, PusTmVariant,
};
use crate::tmtc::{PacketAsVec, PacketSenderWithSharedPool};
@@ -12,8 +12,9 @@ use std::sync::mpsc;
use super::verification::{VerificationReporter, VerificationReportingProvider};
use super::{
CacheAndReadRawEcssTc, EcssTcInSharedPoolCacher, EcssTcReceiver, EcssTcVecCacher, EcssTmSender,
GenericConversionError, HandlingStatus, MpscTcReceiver, PusServiceHelper,
GenericConversionError, MpscTcReceiver, PusServiceHelper,
};
use crate::HandlingStatus;
/// This is a helper class for [std] environments to handle generic PUS 17 (test service) packets.
/// This handler only processes ping requests and generates a ping reply for them accordingly.
@@ -140,18 +141,19 @@ pub type PusService17TestHandlerStaticWithBoundedMpsc = PusService17TestHandler<
#[cfg(test)]
mod tests {
use crate::ComponentId;
use crate::pus::test_util::{PusTestHarness, SimplePusPacketHandler, TEST_APID};
use crate::pus::tests::{
use crate::HandlingStatus;
use crate::legacy::pus::test_util::{PusTestHarness, SimplePusPacketHandler, TEST_APID};
use crate::legacy::pus::tests::{
PusServiceHandlerWithSharedStoreCommon, PusServiceHandlerWithVecCommon,
};
use crate::pus::verification::{
use crate::legacy::pus::verification::{
RequestId, VerificationReporter, VerificationReportingProvider,
};
use crate::pus::verification::{TcStateAccepted, VerificationToken};
use crate::pus::{
use crate::legacy::pus::verification::{TcStateAccepted, VerificationToken};
use crate::legacy::pus::{
DirectPusPacketHandlerResult, EcssTcInSharedPoolCacher, EcssTcVecCacher,
GenericConversionError, HandlingStatus, MpscTcReceiver, MpscTmAsVecSender,
PartialPusHandlingError, PusPacketHandlingError,
GenericConversionError, MpscTcReceiver, MpscTmAsVecSender, PartialPusHandlingError,
PusPacketHandlingError,
};
use crate::tmtc::PacketSenderWithSharedPool;
use arbitrary_int::traits::Integer as _;
@@ -16,7 +16,7 @@
//! use std::sync::{Arc, mpsc, RwLock};
//! use std::time::Duration;
//! use satrs::pool::{PoolProviderWithGuards, StaticMemoryPool, StaticPoolConfig};
//! use satrs::pus::verification::{
//! use satrs::legacy::pus::verification::{
//! VerificationReportingProvider, VerificationReporterConfig, VerificationReporter
//! };
//! use satrs::tmtc::{SharedStaticMemoryPool, PacketSenderWithSharedPool};
@@ -80,8 +80,8 @@
//! The [integration test](https://egit.irs.uni-stuttgart.de/rust/fsrc-launchpad/src/branch/main/fsrc-core/tests/verification_test.rs)
//! for the verification module contains examples how this module could be used in a more complex
//! context involving multiple threads
use super::{EcssTmSender, EcssTmtcError, source_buffer_large_enough};
use crate::params::{Params, WritableToBeBytes};
use crate::pus::{EcssTmSender, EcssTmtcError, source_buffer_large_enough};
use arbitrary_int::{u3, u11, u14};
use core::fmt::{Debug, Display, Formatter};
use core::hash::{Hash, Hasher};
@@ -841,7 +841,7 @@ pub mod alloc_mod {
use spacepackets::ecss::PusError;
use super::*;
use crate::pus::PusTmVariant;
use crate::legacy::pus::PusTmVariant;
use core::cell::RefCell;
#[derive(Clone)]
@@ -1712,16 +1712,16 @@ pub mod test_util {
#[cfg(test)]
pub mod tests {
use crate::ComponentId;
use crate::params::Params;
use crate::pool::{SharedStaticMemoryPool, StaticMemoryPool, StaticPoolConfig};
use crate::pus::test_util::{TEST_APID, TEST_COMPONENT_ID_0};
use crate::pus::tests::CommonTmInfo;
use crate::pus::verification::{
use crate::legacy::pus::test_util::{TEST_APID, TEST_COMPONENT_ID_0};
use crate::legacy::pus::tests::CommonTmInfo;
use crate::legacy::pus::verification::{
EcssTmSender, EcssTmtcError, FailParams, FailParamsWithStep, RequestId, TcStateNone,
VerificationReporter, VerificationReporterConfig, VerificationToken,
handle_step_failure_with_generic_params,
};
use crate::pus::{ChannelWithId, PusTmVariant};
use crate::legacy::pus::{ChannelWithId, PusTmVariant};
use crate::params::Params;
use crate::pool::{SharedStaticMemoryPool, StaticMemoryPool, StaticPoolConfig};
use crate::request::MessageMetadata;
use crate::spacepackets::seq_count::{SequenceCounter, SequenceCounterCcsdsSimple};
use crate::tmtc::{PacketSenderWithSharedPool, SharedPacketPool};
+14 -15
View File
@@ -1,16 +1,7 @@
//! # sat-rs: A library to build on-board software for remote systems
//! # sat-rs: A helper library to build on-board software for remote systems
//!
//! You can find more information about the sat-rs framework on the
//! [homepage](https://absatsw.irs.uni-stuttgart.de/projects/sat-rs/).
//! The [satrs-book](https://absatsw.irs.uni-stuttgart.de/projects/sat-rs/book/) contains
//! high-level information about this framework.
//!
//! ## Overview
//!
//! The core modules of this crate include
//!
//! - The [pus] module which provides special support for projects using
//! the [ECSS PUS C standard](https://ecss.nl/standard/ecss-e-st-70-41c-space-engineering-telemetry-and-telecommand-packet-utilization-15-april-2016/).
//! The [satrs-book](https://robamu.github.io/sat-rs/book/) contains
//! high-level information about this library.
#![no_std]
#![cfg_attr(docsrs, feature(doc_cfg))]
#[cfg(any(feature = "alloc", test))]
@@ -20,23 +11,22 @@ extern crate downcast_rs;
#[cfg(any(feature = "std", test))]
extern crate std;
pub mod action;
pub mod ccsds;
pub mod encoding;
#[cfg(feature = "std")]
pub mod executable;
pub mod hal;
pub mod health;
/// Helpers to track when housekeeping sets need to be regenerated.
pub mod hk;
pub mod legacy;
pub mod mode;
#[cfg(feature = "std")]
pub mod mode_tree;
pub mod params;
pub mod pool;
pub mod pus;
pub mod queue;
pub mod request;
pub mod res_code;
#[cfg(feature = "alloc")]
pub mod scheduling;
#[cfg(feature = "alloc")]
@@ -48,6 +38,15 @@ pub use spacepackets;
use spacepackets::PacketId;
/// Generic handling status for an object which is able to continuosly handle a queue to handle
/// request or replies until the queue is empty.
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum HandlingStatus {
HandledOne,
Empty,
}
/// Generic component ID type.
pub type ComponentId = u32;
-1699
View File
File diff suppressed because it is too large Load Diff
+5 -5
View File
@@ -229,8 +229,8 @@ pub mod std_mod {
use spacepackets::ecss::WritablePusPacket;
use thiserror::Error;
use crate::legacy::pus::{EcssTmSender, EcssTmtcError, PacketSenderPusTc};
use crate::pool::PoolProvider;
use crate::pus::{EcssTmSender, EcssTmtcError, PacketSenderPusTc};
use super::*;
@@ -460,16 +460,16 @@ pub mod std_mod {
fn send_tm(
&self,
sender_id: crate::ComponentId,
tm: crate::pus::PusTmVariant,
) -> Result<(), crate::pus::EcssTmtcError> {
tm: crate::legacy::pus::PusTmVariant,
) -> Result<(), crate::legacy::pus::EcssTmtcError> {
let send_addr = |store_addr: PoolAddr| {
self.sender
.send_packet(sender_id, store_addr)
.map_err(EcssTmtcError::Send)
};
match tm {
crate::pus::PusTmVariant::InStore(store_addr) => send_addr(store_addr),
crate::pus::PusTmVariant::Direct(tm_creator) => {
crate::legacy::pus::PusTmVariant::InStore(store_addr) => send_addr(store_addr),
crate::legacy::pus::PusTmVariant::Direct(tm_creator) => {
let mut pool = self.shared_pool.borrow_mut();
let store_addr = pool.add_pus_tm_from_creator(&tm_creator)?;
send_addr(store_addr)
+3 -3
View File
@@ -3,12 +3,12 @@ pub mod crossbeam_test {
use arbitrary_int::traits::Integer as _;
use arbitrary_int::u14;
use hashbrown::HashMap;
use satrs::pool::{PoolProvider, PoolProviderWithGuards, StaticMemoryPool, StaticPoolConfig};
use satrs::pus::test_util::{TEST_APID, TEST_COMPONENT_ID_0};
use satrs::pus::verification::{
use satrs::legacy::pus::test_util::{TEST_APID, TEST_COMPONENT_ID_0};
use satrs::legacy::pus::verification::{
FailParams, RequestId, VerificationReporter, VerificationReporterConfig,
VerificationReportingProvider,
};
use satrs::pool::{PoolProvider, PoolProviderWithGuards, StaticMemoryPool, StaticPoolConfig};
use satrs::tmtc::{PacketSenderWithSharedPool, SharedStaticMemoryPool};
use spacepackets::SpHeader;
use spacepackets::ecss::tc::{PusTcCreator, PusTcReader, PusTcSecondaryHeader};