From c606fe7d0ce730f577427233ed9625abace0f348 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 15 Aug 2023 21:10:12 +0200 Subject: [PATCH 01/18] satrs-book init --- satrs-book/.gitignore | 1 + satrs-book/book.toml | 6 ++++++ satrs-book/src/SUMMARY.md | 3 +++ satrs-book/src/chapter_1.md | 1 + 4 files changed, 11 insertions(+) create mode 100644 satrs-book/.gitignore create mode 100644 satrs-book/book.toml create mode 100644 satrs-book/src/SUMMARY.md create mode 100644 satrs-book/src/chapter_1.md diff --git a/satrs-book/.gitignore b/satrs-book/.gitignore new file mode 100644 index 0000000..7585238 --- /dev/null +++ b/satrs-book/.gitignore @@ -0,0 +1 @@ +book diff --git a/satrs-book/book.toml b/satrs-book/book.toml new file mode 100644 index 0000000..95212c7 --- /dev/null +++ b/satrs-book/book.toml @@ -0,0 +1,6 @@ +[book] +authors = ["Robin Mueller"] +language = "en" +multilingual = false +src = "src" +title = "satrs-book" diff --git a/satrs-book/src/SUMMARY.md b/satrs-book/src/SUMMARY.md new file mode 100644 index 0000000..7390c82 --- /dev/null +++ b/satrs-book/src/SUMMARY.md @@ -0,0 +1,3 @@ +# Summary + +- [Chapter 1](./chapter_1.md) diff --git a/satrs-book/src/chapter_1.md b/satrs-book/src/chapter_1.md new file mode 100644 index 0000000..b743fda --- /dev/null +++ b/satrs-book/src/chapter_1.md @@ -0,0 +1 @@ +# Chapter 1 From bcf22f42d471993589600c4053261b1509134a5a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 30 Aug 2023 16:40:32 +0200 Subject: [PATCH 02/18] front page --- satrs-book/src/satrs-book.md | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 satrs-book/src/satrs-book.md diff --git a/satrs-book/src/satrs-book.md b/satrs-book/src/satrs-book.md new file mode 100644 index 0000000..571c1ea --- /dev/null +++ b/satrs-book/src/satrs-book.md @@ -0,0 +1,10 @@ +The sat-rs book +====== + +This book is the primary information resource for the [sat-rs framework](https://egit.irs.uni-stuttgart.de/rust/sat-rs) +in addition to the regular API documentation. It contains the following resources: + +1. Architecture informations and consideration which would exceeds the scope of the regular API. +2. A Getting-Started workshop where a small On-Board Software is built from scratch using + sat-rs components. + From f271ae5689715c13e934870a68bb8c01ee74dd38 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 30 Aug 2023 17:03:39 +0200 Subject: [PATCH 03/18] how does this work --- satrs-book/src/chapter_1.md | 1 - satrs-book/src/{satrs-book.md => title-page.md} | 0 2 files changed, 1 deletion(-) delete mode 100644 satrs-book/src/chapter_1.md rename satrs-book/src/{satrs-book.md => title-page.md} (100%) diff --git a/satrs-book/src/chapter_1.md b/satrs-book/src/chapter_1.md deleted file mode 100644 index b743fda..0000000 --- a/satrs-book/src/chapter_1.md +++ /dev/null @@ -1 +0,0 @@ -# Chapter 1 diff --git a/satrs-book/src/satrs-book.md b/satrs-book/src/title-page.md similarity index 100% rename from satrs-book/src/satrs-book.md rename to satrs-book/src/title-page.md From 37261e512c8e7e09be0fe2eb43df5248a0304e72 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 30 Aug 2023 17:12:45 +0200 Subject: [PATCH 04/18] book description --- satrs-book/book.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/satrs-book/book.toml b/satrs-book/book.toml index 95212c7..8d01bb6 100644 --- a/satrs-book/book.toml +++ b/satrs-book/book.toml @@ -3,4 +3,4 @@ authors = ["Robin Mueller"] language = "en" multilingual = false src = "src" -title = "satrs-book" +title = "The sat-rs book" From 73a4955fb38a74c8c1838d1796f01d386be53e3f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 30 Aug 2023 17:30:59 +0200 Subject: [PATCH 05/18] continue book --- satrs-book/src/SUMMARY.md | 4 +++- satrs-book/src/introduction.md | 11 +++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 satrs-book/src/introduction.md diff --git a/satrs-book/src/SUMMARY.md b/satrs-book/src/SUMMARY.md index 7390c82..b082e13 100644 --- a/satrs-book/src/SUMMARY.md +++ b/satrs-book/src/SUMMARY.md @@ -1,3 +1,5 @@ # Summary -- [Chapter 1](./chapter_1.md) +- [The sat-rs book](./title-page.md) +- [Introduction](./introduction.md) + diff --git a/satrs-book/src/introduction.md b/satrs-book/src/introduction.md new file mode 100644 index 0000000..0573ce2 --- /dev/null +++ b/satrs-book/src/introduction.md @@ -0,0 +1,11 @@ +# Introduction + +This is the repository of the sat-rs framework. Its primary goal is to provide re-usable components +to write on-board software for remote systems like rovers or satellites. It is specifically written +for the special requirements for these systems. + +A lot of the architecture and general design considerations are based on the +[FSFW](https://egit.irs.uni-stuttgart.de/fsfw/fsfw) C++ framework which has flight heritage +through the 2 missions [FLP](https://www.irs.uni-stuttgart.de/en/research/satellitetechnology-and-instruments/smallsatelliteprogram/flying-laptop/) +and [EIVE](https://www.irs.uni-stuttgart.de/en/research/satellitetechnology-and-instruments/smallsatelliteprogram/EIVE/). + From f8a92cef3d1209768b971f600d26748ee3ce2b7e Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 30 Aug 2023 18:20:27 +0200 Subject: [PATCH 06/18] this is a good start --- satrs-book/src/SUMMARY.md | 3 +- satrs-book/src/design.md | 57 ++++++++++++++++++++++++++++++++++ satrs-book/src/introduction.md | 12 ++++++- satrs-book/src/title-page.md | 10 ------ 4 files changed, 70 insertions(+), 12 deletions(-) create mode 100644 satrs-book/src/design.md delete mode 100644 satrs-book/src/title-page.md diff --git a/satrs-book/src/SUMMARY.md b/satrs-book/src/SUMMARY.md index b082e13..31c56f6 100644 --- a/satrs-book/src/SUMMARY.md +++ b/satrs-book/src/SUMMARY.md @@ -1,5 +1,6 @@ # Summary -- [The sat-rs book](./title-page.md) - [Introduction](./introduction.md) +- [Design](./design.md) + diff --git a/satrs-book/src/design.md b/satrs-book/src/design.md new file mode 100644 index 0000000..cd30845 --- /dev/null +++ b/satrs-book/src/design.md @@ -0,0 +1,57 @@ +# Framework Design + +Satellites and space systems in general are complex systems with a wide range of requirements for +both the hardware and the software. +Consequently, the general design of the framework is centered around many light-weight components +which try to impose as few restrictions as possible on how to solve certain problems. + +There are still a lot of common patterns and architectures across these systems where guidance +of how to solve a problem and a common structure would still be extremely useful to avoid pitfalls +which were already solved and to avoid boilerplate code. This framework tries to provide this +structure and guidance the following way: + +1. Providing this book which explains the architecture and design patterns in respect to common + issues and requirements of space systems. +2. Providing an example application. Space systems still commonly have large monolithic + primary On-Board Softwares, so the choice was made to provide one example software which + contains the various features provided by sat-rs. +3. Providing a good test suite. This includes both unittests and integration tests. The integration + tests can also serve as smaller usage examples than the large `satrs-example` application. + +This framework has special support for standards used in the space industry. This especially +includes standards provided by Consultative Committee for Space Data Systems (CCSDS) and European +Cooperation for Space Standardization (ECSS). It does not enforce using any of those standards, +but it is always recommended to use some sort of standard for interoperability. + +A lot of the modules and design considerations are based on the Flight Software Framework (FSFW). +The FSFW has its own [documentation](https://documentation.irs.uni-stuttgart.de/fsfw/), which +will be referred to when applicable. The FSFW was developed over a period of 10 years for the +Flying Laptop Project by the University of Stuttgart with Airbus Defence and Space GmbH. +It has flight heritage through the 2 mssions [FLP](https://www.irs.uni-stuttgart.de/en/research/satellitetechnology-and-instruments/smallsatelliteprogram/flying-laptop/) +and [EIVE](https://www.irs.uni-stuttgart.de/en/research/satellitetechnology-and-instruments/smallsatelliteprogram/EIVE/). +Therefore, a lot of the design concepts were ported more or less unchanged to the `sat-rs` +framework. +FLP is a medium-size small satellite with a higher budget and longer development time than EIVE, +which allowed to build a highly reliable system while EIVE is a smaller 6U+ cubesat which had a +shorter development cycle and was built using cheaper COTS components. This framework also tries +to accumulate the knowledge of developing the OBSW and operating the satellite for both these +different systems and provide a solution for a wider range of small satellite systems. + +`sat-rs` can be seen as a modern port of the FSFW which uses common principles of software +engineering to provide a reliable and robust basis for space On-Board Software. The choice +of using the Rust programming language was made for the following reasons: + +1. Rust has safety guarantees which are a perfect fit for space systems which generally have high + robustness and reliablity guarantees. +2. Rust is suitable for embedded systems. It can also be run on smaller embedded systems like the + STM32 which have also become common in the space sector. All space systems are embedded systems, + which makes using large languages like Python challenging even for OBCs with more performance. +3. Rust has support for linking C APIs through its excellent FFI support. This is especially + important because many vendor provided libaries are still C based. +4. Modern tooling like a package managers and various development helper, which can further reduce + development cycles for space systems. `cargo` provides tools like auto-formatters and linters + which can immediately ensure a high software quality throughout each development cycle. +5. A large ecosystem with excellent libraries which also leverages the excellent tooling provided + previously. Integrating these libraries is a lot easier compared to languages like C/C++ where + there is still no standardized way to use packages. + diff --git a/satrs-book/src/introduction.md b/satrs-book/src/introduction.md index 0573ce2..3cf731f 100644 --- a/satrs-book/src/introduction.md +++ b/satrs-book/src/introduction.md @@ -1,6 +1,16 @@ +The sat-rs book +====== + +This book is the primary information resource for the [sat-rs framework](https://egit.irs.uni-stuttgart.de/rust/sat-rs) +in addition to the regular API documentation. It contains the following resources: + +1. Architecture informations and consideration which would exceeds the scope of the regular API. +2. A Getting-Started workshop where a small On-Board Software is built from scratch using + sat-rs components. + # Introduction -This is the repository of the sat-rs framework. Its primary goal is to provide re-usable components +The primary goal of the sat-rs framework is to provide re-usable components to write on-board software for remote systems like rovers or satellites. It is specifically written for the special requirements for these systems. diff --git a/satrs-book/src/title-page.md b/satrs-book/src/title-page.md deleted file mode 100644 index 571c1ea..0000000 --- a/satrs-book/src/title-page.md +++ /dev/null @@ -1,10 +0,0 @@ -The sat-rs book -====== - -This book is the primary information resource for the [sat-rs framework](https://egit.irs.uni-stuttgart.de/rust/sat-rs) -in addition to the regular API documentation. It contains the following resources: - -1. Architecture informations and consideration which would exceeds the scope of the regular API. -2. A Getting-Started workshop where a small On-Board Software is built from scratch using - sat-rs components. - From dc6b7f64872e5208d97d61d494c73286e4a0dff3 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 30 Aug 2023 18:54:36 +0200 Subject: [PATCH 07/18] add more chapters --- satrs-book/src/SUMMARY.md | 3 +- satrs-book/src/communication.md | 46 +++++++++++++++++++++++++++ satrs-book/src/constrained-systems.md | 0 3 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 satrs-book/src/communication.md create mode 100644 satrs-book/src/constrained-systems.md diff --git a/satrs-book/src/SUMMARY.md b/satrs-book/src/SUMMARY.md index 31c56f6..2f40d33 100644 --- a/satrs-book/src/SUMMARY.md +++ b/satrs-book/src/SUMMARY.md @@ -2,5 +2,6 @@ - [Introduction](./introduction.md) - [Design](./design.md) - +- [Communication with Space Systems](./communication.md) +- [Working with Constrained Systems](./constrained-systems.md) diff --git a/satrs-book/src/communication.md b/satrs-book/src/communication.md new file mode 100644 index 0000000..e989130 --- /dev/null +++ b/satrs-book/src/communication.md @@ -0,0 +1,46 @@ +# Communication with sat-rs based software + +Communication is a huge topic for satellites. These systems are usually not (directly) connected +to the internet and only have 1-2 communication links during nominal operation. However, most +satellites have internet access during development cycle. There are various standards provided by +CCSDS and ECSS which can be useful to determine how to communicate with the satellite and the +primary On-Board Software. + +# Application layer + +Current communication with satellite systems is usually packet based. For example, the CCSDS space +packet standard only specifies a 6 byte header with at least 1 byte payload. The PUS packet +standard is a subset of the space packet standard which adds some fields and a 16 bit CRC, but +it is still centered around small packets. `sat-rs` provides support for these ECSS and CCSDS +standards to also attempts to fill the gap to the internet protocol by providing the following +components. + +1. UDP TMTC Server. UDP is already packet based which makes it an excellent fit for exchanging + space packets. +2. TCP TMTC Server. This is a stream based protocol, so the server uses the COBS framing protocol + to always deliver complete packets. + +# Working with telemetry and telecommands (TMTC) + +The commands sent to a space system are commonly called telecommands (TC) while the data received +from it are called telemetry (TM). Keeping in mind the previous section, the concept of a TC source +and a TM sink can be applied to most satellites. The TM sink is the one entity where all generated +telemetry arrives in real-time. The most important task of the TM sink usually is to send all +arriving telemetry to the ground segment of a satellite mission immediately. Another important +task might be to store all arriving telemetry persistently. This is especially important for +space systems which do not have permanent contact like low-earth-orbit (LEO) satellites. + +The most important task of a TC source is to deliver the telecommands to the correct recipients. +For modern component oriented software using message passing, this usually includes staged +demultiplexing components to determine where a command needs to be sent. + +# 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` +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 can mostly be done +by using the concept of TC sources and TM sinks mentioned previously. + diff --git a/satrs-book/src/constrained-systems.md b/satrs-book/src/constrained-systems.md new file mode 100644 index 0000000..e69de29 From 3bffa8ed83280bdc8db634a344631b31170b7f55 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 30 Aug 2023 19:15:38 +0200 Subject: [PATCH 08/18] added chapter for constrained systems --- satrs-book/src/constrained-systems.md | 43 +++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/satrs-book/src/constrained-systems.md b/satrs-book/src/constrained-systems.md index e69de29..ba18e29 100644 --- a/satrs-book/src/constrained-systems.md +++ b/satrs-book/src/constrained-systems.md @@ -0,0 +1,43 @@ +# Working with Constrained Systems + +Software for space systems oftentimes has different requirements than the software for host +systems or servers. Currently, most space systems are considered embedded systems. + +For these systems, the computation power and the available heap are the most important resources +which are constrained. This might make completeley heap based memory management schemes which +are oftentimes used on host and server based systems unfeasable. Still, completely forbidding +heap allocations might make software development unnecessarilly difficult, especially in a +time where the OBSW might be running on Linux based systems with 500 MB RAM. + +A useful pattern used commonly in space systems is to limit heap allocations to program +initialization time and avoid frequent run-time allocations. This prevents issues like +running out of memory (something event Rust can not protect from) or heap fragmentation. + +# Using pre-allocated pool structures + +A huge candidate for heap allocations is the TMTC and handling. TC, TMs and IPC data are all +candidates where the data size might vary greatly. The regular solution for host systems +might be to send around this data as a `Vec` until it is dropped. `sat-rs` provides +another solution to avoid run-time allocations by pre-allocated static pools. + +These pools are split into subpools where each subpool can have different page sizes. +For example, a very small TC pool might look like this: + +TODO: Add image + +A TC entry inside this pool has a store address which can then be sent around without having +to dynamically allocate memory. The same principle can also be applied to the TM and IPC data. + +# Using special crates to prevent smaller allocations + +Another common way to use the heap on host systems is using containers like `String` and `Vec` +to work with data where the size is not known beforehand. The most common solution for embedded +systems is to determine the maximum expected size and then use a pre-allocated `u8` buffer and a +size variable. Alternatively, you can use the following crates for more convenience or a smart +behaviour which at least reduced heap allocations: + +1. [`smallvec`](https://docs.rs/smallvec/latest/smallvec/). +2. [`arrayvec`](https://docs.rs/arrayvec/latest/arrayvec/index.html) which also contains an + [`ArrayString`](https://docs.rs/arrayvec/latest/arrayvec/struct.ArrayString.html) helper type. +3. [`tinyvec`](https://docs.rs/tinyvec/latest/tinyvec/). + From c153276454398fbe7c98ff56d1b0e28ba2d0b711 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 30 Aug 2023 19:23:48 +0200 Subject: [PATCH 09/18] add section for threads --- satrs-book/src/constrained-systems.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/satrs-book/src/constrained-systems.md b/satrs-book/src/constrained-systems.md index ba18e29..a10619d 100644 --- a/satrs-book/src/constrained-systems.md +++ b/satrs-book/src/constrained-systems.md @@ -41,3 +41,16 @@ behaviour which at least reduced heap allocations: [`ArrayString`](https://docs.rs/arrayvec/latest/arrayvec/struct.ArrayString.html) helper type. 3. [`tinyvec`](https://docs.rs/tinyvec/latest/tinyvec/). +# Using a fixed amount of threads + +On host systems, it is a common practice to dynamically spawn new threads to handle workloads. +On space systems this is generally considered an anti-pattern as this is considered undeterministic +and might lead to similar issues like when dynamically using the heap. For example, spawning a new +thread might use up the remaining heap of a system, leading to undeterministic errors. + +The most common way to avoid this is to simply spawn all required threads at program initialization +time. If a thread is done with its task, it can go back to sleeping regularly, only occasionally +checking for new jobs. If a system still needs to handle burst concurrent loads, another possible +way commonly used for host systems as well would be to use a threadpool, for example by using the +[`threadpool`](https://crates.io/crates/threadpool) crate. + From df90c22fef539c658ba2d6e114a08520434d9dd3 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 1 Sep 2023 19:09:49 +0200 Subject: [PATCH 10/18] smaller tweaks --- satrs-book/src/communication.md | 12 ++++++------ satrs-book/src/design.md | 6 +++--- satrs-book/src/introduction.md | 2 ++ 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/satrs-book/src/communication.md b/satrs-book/src/communication.md index e989130..bcda520 100644 --- a/satrs-book/src/communication.md +++ b/satrs-book/src/communication.md @@ -1,16 +1,16 @@ # Communication with sat-rs based software -Communication is a huge topic for satellites. These systems are usually not (directly) connected +Communication is a huge topic for space systems. They are usually not (directly) connected to the internet and only have 1-2 communication links during nominal operation. However, most -satellites have internet access during development cycle. There are various standards provided by -CCSDS and ECSS which can be useful to determine how to communicate with the satellite and the -primary On-Board Software. +of these systems have internet access during development cycle. There are various standards +provided by CCSDS and ECSS which can be useful to determine how to communicate with the satellite +and the primary On-Board Software. # Application layer -Current communication with satellite systems is usually packet based. For example, the CCSDS space +Most communication with space systems is usually packet based. For example, the CCSDS space packet standard only specifies a 6 byte header with at least 1 byte payload. The PUS packet -standard is a subset of the space packet standard which adds some fields and a 16 bit CRC, but +standard is a subset of the space packet standard, which adds some fields and a 16 bit CRC, but it is still centered around small packets. `sat-rs` provides support for these ECSS and CCSDS standards to also attempts to fill the gap to the internet protocol by providing the following components. diff --git a/satrs-book/src/design.md b/satrs-book/src/design.md index cd30845..9ec7317 100644 --- a/satrs-book/src/design.md +++ b/satrs-book/src/design.md @@ -1,9 +1,9 @@ # Framework Design Satellites and space systems in general are complex systems with a wide range of requirements for -both the hardware and the software. -Consequently, the general design of the framework is centered around many light-weight components -which try to impose as few restrictions as possible on how to solve certain problems. +both the hardware and the software. Consequently, the general design of the framework is centered +around many light-weight components which try to impose as few restrictions as possible on how to +solve certain problems. There are still a lot of common patterns and architectures across these systems where guidance of how to solve a problem and a common structure would still be extremely useful to avoid pitfalls diff --git a/satrs-book/src/introduction.md b/satrs-book/src/introduction.md index 3cf731f..31a0b0c 100644 --- a/satrs-book/src/introduction.md +++ b/satrs-book/src/introduction.md @@ -5,6 +5,8 @@ This book is the primary information resource for the [sat-rs framework](https:/ in addition to the regular API documentation. It contains the following resources: 1. Architecture informations and consideration which would exceeds the scope of the regular API. +2. General information on how to build On-Board Software and how `sat-rs` can help to fulfill + the unique requirements of writing software for remote systems. 2. A Getting-Started workshop where a small On-Board Software is built from scratch using sat-rs components. From 44905fb700302c3bdce107b9b49f5884030aca6f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 1 Sep 2023 19:15:32 +0200 Subject: [PATCH 11/18] add a lot of chapter stubs --- satrs-book/src/SUMMARY.md | 9 +++++++++ satrs-book/src/actions.md | 0 satrs-book/src/fdir.md | 0 satrs-book/src/ground.md | 0 satrs-book/src/modelling-space-systems.md | 0 satrs-book/src/modes-and-health.md | 0 satrs-book/src/power.md | 0 satrs-book/src/thermal.md | 0 8 files changed, 9 insertions(+) create mode 100644 satrs-book/src/actions.md create mode 100644 satrs-book/src/fdir.md create mode 100644 satrs-book/src/ground.md create mode 100644 satrs-book/src/modelling-space-systems.md create mode 100644 satrs-book/src/modes-and-health.md create mode 100644 satrs-book/src/power.md create mode 100644 satrs-book/src/thermal.md diff --git a/satrs-book/src/SUMMARY.md b/satrs-book/src/SUMMARY.md index 2f40d33..243449b 100644 --- a/satrs-book/src/SUMMARY.md +++ b/satrs-book/src/SUMMARY.md @@ -4,4 +4,13 @@ - [Design](./design.md) - [Communication with Space Systems](./communication.md) - [Working with Constrained Systems](./constrained-systems.md) +- [Actions](./actions.md) +- [Modes and Health](./modes-and-health.md) +- [Housekeeping Data](./housekeeping.md) +- [Events](./events.md) +- [Power Components](./power.md) +- [Thermal Components](./thermal.md) +- [FDIR](./fdir.md) +- [Modelling space systems](./modelling-space-systems.md) +- [Ground Systems](./ground.md) diff --git a/satrs-book/src/actions.md b/satrs-book/src/actions.md new file mode 100644 index 0000000..e69de29 diff --git a/satrs-book/src/fdir.md b/satrs-book/src/fdir.md new file mode 100644 index 0000000..e69de29 diff --git a/satrs-book/src/ground.md b/satrs-book/src/ground.md new file mode 100644 index 0000000..e69de29 diff --git a/satrs-book/src/modelling-space-systems.md b/satrs-book/src/modelling-space-systems.md new file mode 100644 index 0000000..e69de29 diff --git a/satrs-book/src/modes-and-health.md b/satrs-book/src/modes-and-health.md new file mode 100644 index 0000000..e69de29 diff --git a/satrs-book/src/power.md b/satrs-book/src/power.md new file mode 100644 index 0000000..e69de29 diff --git a/satrs-book/src/thermal.md b/satrs-book/src/thermal.md new file mode 100644 index 0000000..e69de29 From 4e186541ec64db31ecf64374875bcbff74532c31 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 1 Sep 2023 19:19:31 +0200 Subject: [PATCH 12/18] some more chapters --- satrs-book/src/SUMMARY.md | 3 +++ satrs-book/src/events.md | 1 + satrs-book/src/housekeeping.md | 1 + satrs-book/src/logging.md | 1 + satrs-book/src/persistent-tm-storage.md | 1 + satrs-book/src/serialization.md | 1 + 6 files changed, 8 insertions(+) create mode 100644 satrs-book/src/events.md create mode 100644 satrs-book/src/housekeeping.md create mode 100644 satrs-book/src/logging.md create mode 100644 satrs-book/src/persistent-tm-storage.md create mode 100644 satrs-book/src/serialization.md diff --git a/satrs-book/src/SUMMARY.md b/satrs-book/src/SUMMARY.md index 243449b..3fbc9f6 100644 --- a/satrs-book/src/SUMMARY.md +++ b/satrs-book/src/SUMMARY.md @@ -10,7 +10,10 @@ - [Events](./events.md) - [Power Components](./power.md) - [Thermal Components](./thermal.md) +- [Persistent TM storage](./persistent-tm-storage.md) - [FDIR](./fdir.md) +- [Serialization of Data](./serialization.md) +- [Logging](./logging.md) - [Modelling space systems](./modelling-space-systems.md) - [Ground Systems](./ground.md) diff --git a/satrs-book/src/events.md b/satrs-book/src/events.md new file mode 100644 index 0000000..1f187df --- /dev/null +++ b/satrs-book/src/events.md @@ -0,0 +1 @@ +# Events diff --git a/satrs-book/src/housekeeping.md b/satrs-book/src/housekeeping.md new file mode 100644 index 0000000..af23140 --- /dev/null +++ b/satrs-book/src/housekeeping.md @@ -0,0 +1 @@ +# Housekeeping Data diff --git a/satrs-book/src/logging.md b/satrs-book/src/logging.md new file mode 100644 index 0000000..b921bbe --- /dev/null +++ b/satrs-book/src/logging.md @@ -0,0 +1 @@ +# Logging diff --git a/satrs-book/src/persistent-tm-storage.md b/satrs-book/src/persistent-tm-storage.md new file mode 100644 index 0000000..08b20d9 --- /dev/null +++ b/satrs-book/src/persistent-tm-storage.md @@ -0,0 +1 @@ +# Persistent TM storage diff --git a/satrs-book/src/serialization.md b/satrs-book/src/serialization.md new file mode 100644 index 0000000..0dfc62d --- /dev/null +++ b/satrs-book/src/serialization.md @@ -0,0 +1 @@ +# Serialization From 696d9fe48dce727ed2a239feb8816bd64937b462 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 1 Sep 2023 19:37:23 +0200 Subject: [PATCH 13/18] added actions chapter --- satrs-book/src/actions.md | 42 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/satrs-book/src/actions.md b/satrs-book/src/actions.md index e69de29..1f3c921 100644 --- a/satrs-book/src/actions.md +++ b/satrs-book/src/actions.md @@ -0,0 +1,42 @@ +# Working with Actions + +Space systems generally need to be commanded regularly. This can include commands periodically +required to ensure a health system, or commands to reach the mission goals. + +These commands can be modelled using the concept of Actions. the ECSS PUS standard also provides +the PUS service 8 for actions, but provides few concrete subservices and specification on how +action commanding could look like. + +`sat-rs` proposes two recommended ways to perform action commanding: + +1. Target ID and Action ID based. The target ID is a 32-bit unsigned ID for an OBSW object entity + which can also accept Actions. The action ID is a 32-bit unsigned ID for each action that a + target is able to perform. +2. Target ID and Action String based. The target ID is the same as in the first proposal, but + the unique action is identified by a string. + +The framework provides an `ActionRequest` abstraction to model both of these cases. + +## Commanding with ECSS PUS 8 + +`sat-rs` provides a generic ECSS PUS 8 action command handler. This handler can convert PUS 8 +telecommands which use the commanding scheme 1 explained above to an `ActionRequest` which is +then forwarded to the target specified by the Target ID. + +There are 3 requirements for the PUS 8 telecommand: + +1. The subservice 128 must be used +2. Bytes 0 to 4 of application data must contain the target ID in `u32` big endian format. +3. Bytes 4 to 8 of application data must contain the action ID in `u32` big endian format. +4. The rest of the application data are assumed to be command specific additional parameters. They + will be added to an IPC store, the the corresponding store address will be sent as part of the + `ActionRequest`. + +## Sending back telemetry + +There are some cases where the regular verification provided by PUS in response to PUS action +commands is not sufficient and some additional telemetry needs to be sent to ground. In that +case, it is recommended to chose some custom subservice for action TM data and then send the +telemetry using the same scheme as shown above, where the first 8 bytes of the application +data is reserved for the target ID and action ID. + From 2322d3a9b347bcfe1255ddc5993e830deeb2bc43 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 1 Sep 2023 20:18:26 +0200 Subject: [PATCH 14/18] added a basic modes and health chapter --- satrs-book/src/actions.md | 2 +- satrs-book/src/modes-and-health.md | 102 +++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+), 1 deletion(-) diff --git a/satrs-book/src/actions.md b/satrs-book/src/actions.md index 1f3c921..6ad9c39 100644 --- a/satrs-book/src/actions.md +++ b/satrs-book/src/actions.md @@ -29,7 +29,7 @@ There are 3 requirements for the PUS 8 telecommand: 2. Bytes 0 to 4 of application data must contain the target ID in `u32` big endian format. 3. Bytes 4 to 8 of application data must contain the action ID in `u32` big endian format. 4. The rest of the application data are assumed to be command specific additional parameters. They - will be added to an IPC store, the the corresponding store address will be sent as part of the + will be added to an IPC store and the corresponding store address will be sent as part of the `ActionRequest`. ## Sending back telemetry diff --git a/satrs-book/src/modes-and-health.md b/satrs-book/src/modes-and-health.md index e69de29..4cb6878 100644 --- a/satrs-book/src/modes-and-health.md +++ b/satrs-book/src/modes-and-health.md @@ -0,0 +1,102 @@ +# Modes + +Modes are an extremely useful concept for complex system in general. They also allow simplified +system reasoning for both system operators and OBSW developers. They model the behaviour of a +component and also provide observability of a system. A few examples of how to model +different components of a space system with modes will be given. + +## Modelling a pyhsical devices with modes + +The following simple mode scheme with the following three mode + +- `OFF` +- `ON` +- `NORMAL` + +can be applied to a large number of simpler devices of a remote system, for example sensors. + +1. `OFF` means that a device is physically switched off, and the corresponding software component +does not poll the device regularly. +2. `ON` means that a device is pyhsically switched on, but the device is not polled perically. +3. `NORMAL` means that a device is powered on and polled periodically. + +If a devices is `OFF`, the device handler will deny commands which include physical communication +with the connected devices. In `NORMAL` mode, it will autonomously perform periodic polling +of a connected physical device in addition to handling remote commands by the operator. +Using these three basic modes, there are two important transitions which need to be taken care of +for the majority of devices: + +1. `OFF` to `ON` or `NORMAL`: The device first needs to be powered on. After that, the + device initial startup configuration must be performed. +2. `NORMAL` or `ON` to `OFF`: Any important shutdown configuration or handling must be performed + before powering off the device. + +## Modelling a controller with modes + +Controller components are not modelling physical devices, but a mode scheme is still the best +way to model most of these components. + +For example, a hypothetical attitude controller might have the following modes: + +- `SAFE` +- `TARGET IDLE` +- `TARGET POINTING GROUND` +- `TARGET POINTING NADIR` + +We can also introduce the concept of submodes: The `SAFE` mode can for example have a +`DEFAULT` submode and a `DETUMBLE` submode. + +## Achieving system observability with modes + +If a system component has a mode in some shape or form, this mode should be observable. This means +that the operator can also retrieve the mode for a particular component. This is especially +important if these components can change their mode autonomously. + +If a component is able to change its mode autonomously, this is also something which is relevant +information for the operator or for other software components. This means that a component +should also be able to announce its mode. + +This concept becomes especially important when applying the mode concept on the whole +system level. This will also be explained in detail in a dedicated chapter, but the basic idea +is to model the whole system as a tree where each node has a mode. A new capability is added now: +A component can announce its mode recursively. This means that the component will announce its +own mode first before announcing the mode of all its children. Using a scheme like this, the mode +of the whole system can be retrieved using only one command. The same concept can also be used +for commanding the whole system, which will be explained in more detail in the dedicated systems +modelling chapter. + +In summary, a component which has modes has to expose the following 4 capabilities: + +1. Set a mode +2. Read the mode +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. +Oftentimes, the health is tied to the mode of a system component in some shape or form, and +determines whether a system component is usable. Health is also an extremely useful concept +to simplify the Fault Detection, Isolation and Recovery (FDIR) concept of a system. + +The following health states are based on the ones used inside the FSFW and are enough to model most +use-cases: + +- `HEALTHY` +- `FAULTY` +- `NEEDS RECOVERY` +- `EXTERNAL CONTROL` + +1. `HEALTHY` means that a component is working nominally, and can perform its task without any issues. +2. `FAULTY` means that a component does not work properly. This might also impact other system +components, so the passivation and isolation of that component is desirable for FDIR purposes. +3. `NEEDS RECOVERY` is used to attempt a recovery of a component. For example, a simple sensor +could be power-cycled if there were multiple communication issues in the last time. +4. `EXTERNAL CONTROL` is used to isolate an individual component from the rest of the system. For + 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. + + From 83c5784b9d88c5de89590359cf8c528292515211 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 13 Sep 2023 15:11:44 +0200 Subject: [PATCH 15/18] improve the book, add first pictures --- satrs-book/src/SUMMARY.md | 2 +- satrs-book/src/actions.md | 2 +- satrs-book/src/communication.md | 12 +- satrs-book/src/constrained-systems.md | 11 +- satrs-book/src/events.md | 15 ++ satrs-book/src/fdir.md | 1 + satrs-book/src/ground-segments.md | 1 + satrs-book/src/ground.md | 0 satrs-book/src/housekeeping.md | 23 ++ satrs-book/src/images/event_man_arch.graphml | 259 +++++++++++++++++++ satrs-book/src/images/event_man_arch.png | Bin 0 -> 71832 bytes satrs-book/src/modelling-space-systems.md | 1 + satrs-book/src/persistent-tm-storage.md | 2 +- satrs-book/src/power.md | 1 + satrs-book/src/thermal.md | 1 + 15 files changed, 317 insertions(+), 14 deletions(-) create mode 100644 satrs-book/src/ground-segments.md delete mode 100644 satrs-book/src/ground.md create mode 100644 satrs-book/src/images/event_man_arch.graphml create mode 100644 satrs-book/src/images/event_man_arch.png diff --git a/satrs-book/src/SUMMARY.md b/satrs-book/src/SUMMARY.md index 3fbc9f6..995e8a9 100644 --- a/satrs-book/src/SUMMARY.md +++ b/satrs-book/src/SUMMARY.md @@ -15,5 +15,5 @@ - [Serialization of Data](./serialization.md) - [Logging](./logging.md) - [Modelling space systems](./modelling-space-systems.md) -- [Ground Systems](./ground.md) +- [Ground Segments](./ground-segments.md) diff --git a/satrs-book/src/actions.md b/satrs-book/src/actions.md index 6ad9c39..0e092d9 100644 --- a/satrs-book/src/actions.md +++ b/satrs-book/src/actions.md @@ -1,7 +1,7 @@ # Working with Actions Space systems generally need to be commanded regularly. This can include commands periodically -required to ensure a health system, or commands to reach the mission goals. +required to ensure a healthy system, or commands to reach the mission goals. These commands can be modelled using the concept of Actions. the ECSS PUS standard also provides the PUS service 8 for actions, but provides few concrete subservices and specification on how diff --git a/satrs-book/src/communication.md b/satrs-book/src/communication.md index bcda520..1bb66a5 100644 --- a/satrs-book/src/communication.md +++ b/satrs-book/src/communication.md @@ -1,8 +1,8 @@ # Communication with sat-rs based software -Communication is a huge topic for space systems. They are usually not (directly) connected -to the internet and only have 1-2 communication links during nominal operation. However, most -of these systems have internet access during development cycle. There are various standards +Communication is a huge topic for space systems. Remote systems are usually not (directly) +connected to the internet and only have 1-2 communication links during nominal operation. However, +most of these systems have internet access during development cycle. There are various standards provided by CCSDS and ECSS which can be useful to determine how to communicate with the satellite and the primary On-Board Software. @@ -12,7 +12,7 @@ Most communication with space systems is usually packet based. For example, the packet standard only specifies a 6 byte header with at least 1 byte payload. The PUS packet standard is a subset of the space packet standard, which adds some fields and a 16 bit CRC, but it is still centered around small packets. `sat-rs` provides support for these ECSS and CCSDS -standards to also attempts to fill the gap to the internet protocol by providing the following +standards and also attempts to fill the gap to the internet protocol by providing the following components. 1. UDP TMTC Server. UDP is already packet based which makes it an excellent fit for exchanging @@ -41,6 +41,6 @@ layer covered by the PUS standard or the CCSDS space packets standard. This ofte 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 can mostly be done -by using the concept of TC sources and TM sinks mentioned previously. +software and hardware. Still, connecting this custom software and hardware to `sat-rs` can mostly +be done by using the concept of TC sources and TM sinks mentioned previously. diff --git a/satrs-book/src/constrained-systems.md b/satrs-book/src/constrained-systems.md index a10619d..4dbdb7a 100644 --- a/satrs-book/src/constrained-systems.md +++ b/satrs-book/src/constrained-systems.md @@ -7,18 +7,19 @@ For these systems, the computation power and the available heap are the most imp which are constrained. This might make completeley heap based memory management schemes which are oftentimes used on host and server based systems unfeasable. Still, completely forbidding heap allocations might make software development unnecessarilly difficult, especially in a -time where the OBSW might be running on Linux based systems with 500 MB RAM. +time where the OBSW might be running on Linux based systems with hundreds of MBs of RAM. A useful pattern used commonly in space systems is to limit heap allocations to program initialization time and avoid frequent run-time allocations. This prevents issues like -running out of memory (something event Rust can not protect from) or heap fragmentation. +running out of memory (something even Rust can not protect from) or heap fragmentation. # Using pre-allocated pool structures A huge candidate for heap allocations is the TMTC and handling. TC, TMs and IPC data are all candidates where the data size might vary greatly. The regular solution for host systems might be to send around this data as a `Vec` until it is dropped. `sat-rs` provides -another solution to avoid run-time allocations by pre-allocated static pools. +another solution to avoid run-time allocations by offering and recommendng pre-allocated static +pools. These pools are split into subpools where each subpool can have different page sizes. For example, a very small TC pool might look like this: @@ -34,7 +35,7 @@ Another common way to use the heap on host systems is using containers like `Str to work with data where the size is not known beforehand. The most common solution for embedded systems is to determine the maximum expected size and then use a pre-allocated `u8` buffer and a size variable. Alternatively, you can use the following crates for more convenience or a smart -behaviour which at least reduced heap allocations: +behaviour which at the very least reduce heap allocations: 1. [`smallvec`](https://docs.rs/smallvec/latest/smallvec/). 2. [`arrayvec`](https://docs.rs/arrayvec/latest/arrayvec/index.html) which also contains an @@ -50,7 +51,7 @@ thread might use up the remaining heap of a system, leading to undeterministic e The most common way to avoid this is to simply spawn all required threads at program initialization time. If a thread is done with its task, it can go back to sleeping regularly, only occasionally -checking for new jobs. If a system still needs to handle burst concurrent loads, another possible +checking for new jobs. If a system still needs to handle bursty concurrent loads, another possible way commonly used for host systems as well would be to use a threadpool, for example by using the [`threadpool`](https://crates.io/crates/threadpool) crate. diff --git a/satrs-book/src/events.md b/satrs-book/src/events.md index 1f187df..083e76a 100644 --- a/satrs-book/src/events.md +++ b/satrs-book/src/events.md @@ -1 +1,16 @@ # Events + +Events can be an extremely important mechanism used for remote systems to monitor unexpected +or expected anomalies and events occuring on these systems. They are oftentimes tied to +Fault Detection, Isolation and Recovery (FDIR) operations, which need to happen autonomously. + +Events can also be used as a convenient Inter-Process Communication (IPC) mechansism, which is +also observable for the Ground segment. 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 really need 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/event_man_arch.png) diff --git a/satrs-book/src/fdir.md b/satrs-book/src/fdir.md index e69de29..074b2ad 100644 --- a/satrs-book/src/fdir.md +++ b/satrs-book/src/fdir.md @@ -0,0 +1 @@ +# Fault Detecion, Isolation And Recovery (FDIR) diff --git a/satrs-book/src/ground-segments.md b/satrs-book/src/ground-segments.md new file mode 100644 index 0000000..58672b2 --- /dev/null +++ b/satrs-book/src/ground-segments.md @@ -0,0 +1 @@ +# Ground Segments diff --git a/satrs-book/src/ground.md b/satrs-book/src/ground.md deleted file mode 100644 index e69de29..0000000 diff --git a/satrs-book/src/housekeeping.md b/satrs-book/src/housekeeping.md index af23140..5a7d73b 100644 --- a/satrs-book/src/housekeeping.md +++ b/satrs-book/src/housekeeping.md @@ -1 +1,24 @@ # Housekeeping Data + +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 +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. + +First, we are going to list some assumption and requirements about Housekeeping (HK) data: + +1. HK data is generated periodically by various system components throughout the + systems. +2. An autonomous and periodic sampling of that HK data to be stored and sent to Ground is generally + required. A minimum interface consists of requesting a one-shot sample of HK, enabling and + disabling the periodic autonomous generation of samples and modifying the collection interval + of the periodic autonomous generation. +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. + +TODO: Write down `sat-rs` recommendations how to expose and work with HK data. diff --git a/satrs-book/src/images/event_man_arch.graphml b/satrs-book/src/images/event_man_arch.graphml new file mode 100644 index 0000000..1336793 --- /dev/null +++ b/satrs-book/src/images/event_man_arch.graphml @@ -0,0 +1,259 @@ + + + + + + + + + + + + + + + + + + + + + + + Example Event Flow + + + + + + + + + + + Event Manager + + + + + + + + + + + Event +Creator 0 + + + + + + + + + + + Event +Creator 2 + + + + + + + + + + + Event +Creator 1 + + + + + + + + + + + Event +Creator 3 + + + + + + + + + + + PUS Service 5 +Event Reporting + + + + + + + + + + + + PUS Service 19 +Event Action + + + + + + + + + + + Telemetry +Sink + + + + + + + + + + + Subscriptions + +1. Event Creator 0 subscribes + for event 0 +2. Event Creator 1 subscribes + for event group 2 +3. PUS Service 5 handler + subscribes for all events +4. PUS Service 19 handler + subscribes for all events + + + + + + + + + + + event 1 +(group 1) + + + + + + + + + + + + + event 0 +(group 0) + + + + + + + + + + + event 2 +(group 3) + + + + + + + + + + + + + event 3 (group 2) +event 4 (group 2) + + + + + + + + + + + <<all events>> + + + + + + + + + + + <<all events>> + + + + + + + + + + + + + event 1 +event 2 + + + + + + + + + + + group 2 + + + + + + + + + + + enabled Events +as PUS 5 TM + + + + + + + + + diff --git a/satrs-book/src/images/event_man_arch.png b/satrs-book/src/images/event_man_arch.png new file mode 100644 index 0000000000000000000000000000000000000000..61c8d7255dfe663247b6d21db6f368570fd5105c GIT binary patch literal 71832 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

57b?fjoQm3O83H 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 Y_NLHOi$+i4r^p Date: Wed, 13 Sep 2023 15:18:50 +0200 Subject: [PATCH 16/18] add first links to doc --- satrs-book/src/communication.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/satrs-book/src/communication.md b/satrs-book/src/communication.md index 1bb66a5..447ebfd 100644 --- a/satrs-book/src/communication.md +++ b/satrs-book/src/communication.md @@ -15,8 +15,8 @@ it is still centered around small packets. `sat-rs` provides support for these E standards and also attempts to fill the gap to the internet protocol by providing the following components. -1. UDP TMTC Server. UDP is already packet based which makes it an excellent fit for exchanging - space packets. +1. [UDP TMTC Server](https://docs.rs/satrs-core/0.1.0-alpha.0/satrs_core/hal/host/udp_server/index.html#). + UDP is already packet based which makes it an excellent fit for exchanging space packets. 2. TCP TMTC Server. This is a stream based protocol, so the server uses the COBS framing protocol to always deliver complete packets. From e2bbcedf3e394175a5aa24f2af07f3413ce0a954 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 13 Sep 2023 15:21:28 +0200 Subject: [PATCH 17/18] link corrections --- satrs-core/src/hal/host/udp_server.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/satrs-core/src/hal/host/udp_server.rs b/satrs-core/src/hal/host/udp_server.rs index de5a3f0..b91a239 100644 --- a/satrs-core/src/hal/host/udp_server.rs +++ b/satrs-core/src/hal/host/udp_server.rs @@ -51,9 +51,9 @@ use std::vec::Vec; /// .expect("Error sending PUS TC via UDP"); /// ``` /// -/// The [fsrc-example crate](https://egit.irs.uni-stuttgart.de/rust/fsrc-launchpad/src/branch/main/fsrc-example) +/// The [satrs-example crate](https://egit.irs.uni-stuttgart.de/rust/fsrc-launchpad/src/branch/main/-example) /// server code also includes -/// [example code](https://egit.irs.uni-stuttgart.de/rust/fsrc-launchpad/src/branch/main/fsrc-example/src/bin/obsw/tmtc.rs) +/// [example code](https://egit.irs.uni-stuttgart.de/rust/sat-rs/src/branch/main/satrs-example/src/tmtc.rs#L67) /// on how to use this TC server. It uses the server to receive PUS telecommands on a specific port /// and then forwards them to a generic CCSDS packet receiver. pub struct UdpTcServer { From 1bb4238e9fa8d393ca2643436b2fcaad2586adac Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 13 Sep 2023 15:26:20 +0200 Subject: [PATCH 18/18] README update --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 548c038..585d3a9 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ This project currently contains following crates: on a host computer or on any system with a standard runtime like a Raspberry Pi. * [`satrs-mib`](https://egit.irs.uni-stuttgart.de/rust/satrs-launchpad/src/branch/main/satrs-mib): Components to build a mission information base from the on-board software directly. -* [`satrs-example-stm32f3-disco`](https://egit.irs.uni-stuttgart.de/rust/satrs-example-stm32f3-disco): +* [`satrs-example-stm32f3-disco`](https://egit.irs.uni-stuttgart.de/rust/sat-rs/src/branch/main/satrs-example-stm32f3-disco): Example of a simple example on-board software using sat-rs components on a bare-metal system with constrained resources.