Skip to content

Repository files navigation

EmbeddedPUS

Minimal ECSS Packet Utilisation Standard (PUS) implementation in C, designed for small-scale academic space missions.

Zero dynamic allocation, no global state, C99 with C++-compatible headers — and 100% line & branch test coverage.

Standards Compliance

  • ECSS-E-ST-70-41C: Packet Utilisation Standard (PUS)

Features

Implemented Services

ServiceNameSubtypes
ST[01]Request VerificationAcceptance, Start, Completion (success & failure), Routing failure; Progress reports must be emitted manually by the handler
ST[03]HousekeepingTM[3,25] HK report, TM[3,26] diagnostic report
ST[05]Event ReportingInfo, Low/Medium/High severity
ST[17]TestTC[17,1] are-you-alive, TC[17,3] on-board connection test
ST[20]Parameter ManagementTC[20,1] request report, TC[20,3] set values, TM[20,2] value report

Design Principles

  • Transport-agnostic — a pure PUS layer operating on the secondary header and application data; wrap its packets in a CCSDS Space Packet primary header or carry them in CCSDS SDLP TC/TM transfer frames
  • No heap — all memory is caller-supplied or statically declared
  • No global state — everything lives in a pus_context_t you own
  • Composable — each service has its own context struct; mix and match what you need
  • Portable C — no platform-specific dependencies
  • C99, C++-friendly — compiles as C99; every public header is wrapped in extern "C" for direct use from C++

Project Structure

EmbeddedPUS/
├── include/ # Public API headers
├── src/ # Library source + internal headers
├── example/
│ └── obc_example.c # Minimum OBC usage example
├── tests/ # Unit tests (single file per module) + minimal framework
├── tools/
│ └── coverage_html.sh # Coverage report generator
├── docs/ # ECSS-E-ST-70-41C reference (PDF)
├── Makefile
├── LICENSE
└── README.md

Building

make # build and run tests
make example # build and run the OBC example
make clean # remove build artifacts

Testing & Coverage

make compiles and runs the full unit-test suite under a strict warning set (-Wall -Wextra -Wpedantic -Wconversion and more). Coverage is maintained at 100% of lines and branches; regenerate the report with gcovr:

sudo apt install gcovr
make coverage-html
# Prints a console summary and writes an HTML report to build/coverage/index.html

Quick Start

#include"pus.h"#include"pus_service_17.h"#include"pus_service_3.h"#include"pus_service_5.h"/* 1. Allocate contexts statically */staticpus_context_tg_pus;
staticpus_service_3_ctx_tg_s3;
/* 2. TM sink — called for every outgoing packet */staticpus_status_tuart_send(void*ud, constuint8_t*data, uint16_tlen)
{
(void)ud;
/* write data[0..len] to your UART / radio */returnPUS_STATUS_OK;
}
/* 3. HK provider — fill the housekeeping buffer on demand */staticpus_status_thk_provider(uint16_tsid, uint8_t*buf,
uint16_tcap, uint16_t*out_len, void*ud)
{
(void)sid; (void)cap; (void)ud;
buf[0] =read_temperature();
*out_len=1u;
returnPUS_STATUS_OK;
}
voidapp_init(void)
{
/* 4. Initialise */pus_config_tcfg= {0};
cfg.default_source_id=0x0001;
cfg.tm_sink=uart_send;
pus_init_with_config(&g_pus, &cfg);
/* 5. Register service handlers */pus_service_17_register_handlers(&g_pus); /* auto-respond to ping */pus_service_3_init(&g_s3);
pus_service_3_register_hk(&g_s3, 0x0001, hk_provider, NULL);
}
voidapp_on_tc_received(constuint8_t*raw, uint16_tlen)
{
/* 6. Decode, route, verify — all in one call */pus_tc_process(&g_pus, raw, len);
}
voidapp_periodic(void)
{
/* 7. Emit periodic housekeeping */pus_service_3_emit_hk(&g_pus, &g_s3, 0x0001u);
/* 8. Emit an event */pus_service_5_emit(&g_pus, PUS_5_1_EVENT_INFO, 0x0101u, NULL, 0u);
}

See example/obc_example.c for a more complete scenario covering all five services.

Memory

  • Code size: ~7.8 kB .text for all services (x86-64 -O2, unstripped; varies by target and flags)
  • Per-context RAM: sizeof(pus_context_t) — handler table + counters
  • No heap: zero dynamic allocation; all buffers are caller-supplied

Limitations

  • Single-threaded: pus_context_t is not thread-safe; protect with a mutex if used from multiple tasks
  • Fixed-capacity tables: handler slots and service contexts are bounded by PUS_MAX_TC_HANDLERS, PUS_SERVICE_3_MAX_STRUCTURES, PUS_SERVICE_20_MAX_PARAMS (all overridable at compile time via -D)

References

  • ECSS-E-ST-70-41C — Telemetry and Telecommand Packet Utilization, European Cooperation for Space Standardization (local copy)

License

Licensed under the Apache License 2.0. See LICENSE.

About

Minimal ECSS Packet Utilisation Standard (PUS) protocol implementation in C for small-scale space missions.

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages