As an Arduino project grows, the complexity of the software can become overwealming. CiC provides an architecture for building complex projects with reusable components.
Complex projects also demand features for observability. The memory contrained environment for Arduinos, for example on the common UNO board, mean off-the-shelf solutions may not fit.
CiC is built in C and is designed around an event bus to enable loosly coupled components.
Typically the core system loop is handled in the standard Arduino loop()
function. Events are generated by responding to real-world activity
(including a radio) and routed through the event bus to listening components.
Primarily the author. It's experimental and certainly not flight worthy. Consider this more of an educational project.
evt
event is the event subsystem.com
communications interfaces with a hardware interface and decodes multiple types of messages for consumption by other components.to
telemetry provides an interface for recording parameters and their values, packaging up a packet to send to mission control.ci
command ingestion processes commands and maps them to mission specific functions.tmr
timer provides for triggering events on a timed scheduletbl
table provides persistent storage of runtime adjustable configuration variables.
Simple tests are available using the provided Makefile
$ make test
These run under gcc and are helpful for local development.
Inspiration for this project came from looking at two competing NASA projects:
Both are used in real world space missions.
cFS is the older more mature system. It's written in C and is architected around an event bus.
fPrime is a newer system famously used on Ingenuity. It's written in C++ and is architected around "ports" and configurable build system to connect components together.
- Loose coupling by using the event bus is good, but don't go overboard. It's not worth adding unnecessary indirection.
- Make it observable.
- Prefer consistent memory usage. (pre-allocation is good)
- Avoid globals within components. Rely on the Mission to define them.
- A TBL component would be helpful for storing stateful data that preserves reboots. For example, error flags shouldn't be reset.
- Tools for tracking memory consumption during a live mission.