Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,17 @@ CFLAGS ?= -O2 -std=c11 \
-Wcast-align -Wcast-qual -Wpointer-arith -Wformat=2 \
-Wmissing-prototypes -Wstrict-prototypes -Wredundant-decls -Wundef

BUILD_DIR = build
CTEST_PATH = $(BUILD_DIR)/tests/ctest
BUILD_DIR = build
CTEST_PATH = $(BUILD_DIR)/tests/ctest
EXAMPLE_PATH = $(BUILD_DIR)/example/obc_example

SRC_FILES = $(wildcard src/*.c)
TEST_FILES = $(wildcard tests/*.c)

SRC_OBJS = $(patsubst src/%.c, $(BUILD_DIR)/src/%.o, $(SRC_FILES))
TEST_OBJS = $(patsubst tests/%.c, $(BUILD_DIR)/tests/%.o, $(TEST_FILES))

.PHONY: all ctest clean
.PHONY: all ctest example clean

all: ctest

Expand All @@ -33,6 +34,17 @@ $(BUILD_DIR)/tests/%.o: tests/%.c
mkdir -p $(dir $@)
$(CC) $(CFLAGS) -c -o $@ $<

example: $(EXAMPLE_PATH)
$(EXAMPLE_PATH)

$(EXAMPLE_PATH): $(SRC_OBJS) $(BUILD_DIR)/example/obc_example.o
mkdir -p $(dir $@)
$(CC) $(CFLAGS) -o $@ $^

$(BUILD_DIR)/example/%.o: example/%.c
mkdir -p $(dir $@)
$(CC) $(CFLAGS) -c -o $@ $<

clean:
rm -rf $(BUILD_DIR)

Expand Down
204 changes: 117 additions & 87 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,150 +1,180 @@
# EmbeddedPUS
Minimal ECSS Packet Utilisation Standard (PUS) protocol implementation in C for small-scale space missions.

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

## Standards Compliance

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

## Features

### Core Protocol Implementation
### Implemented Services

| Service | Name | Subtypes |
|---------|------|----------|
| ST[01] | Request Verification | Acceptance, Start, Progress, Completion (success & failure), Routing failure |
| 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

- **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

## Project Structure

```
EmbeddedSpacePacket/
├── include/
│ └──
├── src/
│ └──
├── examples/
│ └──
EmbeddedPUS/
├── include/ # Public API headers
├── src/ # Library source files
├── example/
│ └── obc_example.c # CubeSat OBC usage example
├── tests/
│ ├── cunit.h # Minimal test framework
│ └── unit_tests.c # Unit tests
│ ├── cunit.h # Minimal test framework
│ └── unit_tests.c # Test entry point
├── tools/
│ └── coverage_html.sh # Coverage report
├── build/ # Build artifacts
│ └── coverage_html.sh # Coverage report generator
├── build/ # Build artifacts (generated)
├── Makefile
└── README.md
```

## Building

### Build Everything

```bash
make
```

Builds the static library, the example binary and the test binary in `build/`.

### Build Library Only

```bash
make lib
# Produces: build/
make # build and run tests
make example # build and run the OBC example
make clean # remove build artifacts
```

### Build Example

```bash
make example
./build/examples/example
```
### Coverage Report

### Run Tests

```bash
make ctest
```

### Coverage (HTML)

Requires `gcovr` installed in your system:
Requires `gcovr`:

```bash
sudo apt install gcovr
```

Generate coverage report:

```bash
make coverage-html
```

Output report:

```bash
build/coverage/index.html
```

### Clean

```bash
make clean
# Output: build/coverage/index.html
```

## Quick Start

### Step 1

```c

```

### Step 2

```c

```

### Step X

#include "pus.h"
#include "pus_service_17.h"
#include "pus_service_3.h"
#include "pus_service_5.h"
#include "pus_service_20.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, 0x0001);

/* 8. Emit an event */
pus_service_5_emit(&g_pus, PUS_SUBTYPE_EVENT_INFO, 0x0101, NULL, 0);
}
```

See [example/obc_example.c](example/obc_example.c) for a more complete scenario covering all five services.

## API Reference

### Lifecycle

```c

pus_status_t pus_init(pus_context_t *ctx);
pus_status_t pus_init_with_config(pus_context_t *ctx, const pus_config_t *config);
pus_status_t pus_set_tm_sink(pus_context_t *ctx, pus_tm_sink_t sink, void *user_data);
```

### Building a Packet
### TC / TM

```c
/* Decode a raw TC buffer into a packet view (zero-copy) */
pus_status_t pus_tc_decode(const uint8_t *data, uint16_t len, pus_tc_packet_t *tc);

```

### Utilities

```c
/* Decode, route, and process a TC; emits ST[01] verification automatically */
pus_status_t pus_tc_process(pus_context_t *ctx, const uint8_t *data, uint16_t len);

/* Build and emit a TM packet; calls the configured TM sink */
pus_status_t pus_tm_build(pus_context_t *ctx, pus_service_t service,
pus_subtype_t subtype, uint16_t destination_id,
const uint8_t *payload, uint16_t payload_len,
uint8_t *out, uint16_t out_capacity, uint16_t *out_len);
```

### Types
### Handler Registration

```c

/* Register a TC handler callback for (service, subtype) */
pus_status_t pus_handler_register(pus_context_t *ctx,
pus_service_t service, pus_subtype_t subtype,
pus_tc_handler_t handler, void *user_data);
```

## Memory Usage (Estimated)

- **Library (stripped)**:
- **Serialization buffer**:
- **No heap usage**: all allocations are caller-supplied
## Memory

## CCSDS XXX — Notes
- **Code size**: ~7.7 kB (text segment, all services, unstripped)
- **Per-context RAM**: `sizeof(pus_context_t)` — handler table + counters
- **No heap**: zero dynamic allocation; all buffers are caller-supplied

## Limitations

- No CCSDS Space Packet primary header (library operates on the PUS secondary header and payload layer only)
- 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

## License

See LICENSE file.
See [LICENSE](LICENSE).
Loading