Skip to content

Latest commit

 

History

History
148 lines (113 loc) · 5.59 KB

File metadata and controls

148 lines (113 loc) · 5.59 KB

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

Service Name Subtypes
ST[01] Request Verification Acceptance, Start, Completion (success & failure), Routing failure; Progress reports must be emitted manually by the handler
ST[03] Housekeeping TM[3,25] HK report, TM[3,26] diagnostic report
ST[05] Event Reporting Info, Low/Medium/High severity
ST[17] Test TC[17,1] are-you-alive, TC[17,3] on-board connection test
ST[20] Parameter Management TC[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 */
static pus_context_t       g_pus;
static pus_service_3_ctx_t g_s3;

/* 2. TM sink — called for every outgoing packet */
static pus_status_t uart_send(void *ud, const uint8_t *data, uint16_t len)
{
    (void)ud;
    /* write data[0..len] to your UART / radio */
    return PUS_STATUS_OK;
}

/* 3. HK provider — fill the housekeeping buffer on demand */
static pus_status_t hk_provider(uint16_t sid, uint8_t *buf,
                                  uint16_t cap, uint16_t *out_len, void *ud)
{
    (void)sid; (void)cap; (void)ud;
    buf[0] = read_temperature();
    *out_len = 1u;
    return PUS_STATUS_OK;
}

void app_init(void)
{
    /* 4. Initialise */
    pus_config_t cfg = {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);
}

void app_on_tc_received(const uint8_t *raw, uint16_t len)
{
    /* 6. Decode, route, verify — all in one call */
    pus_tc_process(&g_pus, raw, len);
}

void app_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.