Skip to content

Commit 939fa75

Browse files
update README + example
docs: Restructure README to match EmbeddedSpaceWire conventions
2 parents 1e4f517 + 3dcfc90 commit 939fa75

2 files changed

Lines changed: 173 additions & 62 deletions

File tree

README.md

Lines changed: 166 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,120 +1,230 @@
1-
# Embedded-SDLP
1+
# EmbeddedSDLP
22

3-
A minimal Space Data Link Protocol (SDLP) implementation in C designed for embedded and resource-constrained space applications.
3+
Minimal, embedded-optimized implementation of **CCSDS Space Data Link Protocol (SDLP)** for TM (Telemetry) and TC (Telecommand) frame handling, following international standards.
44

5-
## Overview
5+
## Standards Compliance
66

7-
EmbeddedSDLP provides a lightweight implementation of TM (Telemetry) and TC (Telecommand) frame handling based on CCSDS standards. It's designed for use in spacecraft, CubeSats, and other space systems where code size and reliability are critical.
7+
- **CCSDS 132.0-B-3**: TM Space Data Link Protocol
8+
- **CCSDS 232.0-B-4**: TC Space Data Link Protocol
89

910
## Features
1011

12+
### Core Protocol Implementation
13+
1114
- **Telemetry (TM) Frame Handling**: Create, encode, and decode TM frames with CRC validation
1215
- **Telecommand (TC) Frame Handling**: Create, encode, and decode TC frames with CRC validation
13-
- **Minimal Dependencies**: Pure C99 with no external dependencies
14-
- **Embedded-Friendly**: Small memory footprint and predictable behavior
1516
- **CRC16 Error Detection**: Built-in frame error control field (FECF) for data integrity
1617
- **Configurable**: Support for virtual channels, spacecraft IDs, and frame sequence numbers
18+
- **TC Segment Header**: Optional MAP-based segmentation support (enabled with `TC_SEGMENT_HEADER_ENABLED`)
19+
20+
### Design Principles
21+
22+
- **Minimal footprint**: Small library size (stripped)
23+
- **Zero allocation**: Stack-based, no dynamic memory
24+
- **Embedded-optimized**: Pure C99, no external dependencies
25+
- **Portable**: Standard C99, big-endian network byte order
26+
- **Reliable**: CRC-16-CCITT frame error control
27+
28+
## Project Structure
29+
30+
```
31+
EmbeddedSDLP/
32+
├── include/
33+
│ ├── sdlp_common.h # Common definitions and CRC
34+
│ ├── sdlp_tm.h # TM frame definitions
35+
│ └── sdlp_tc.h # TC frame definitions
36+
├── src/
37+
│ ├── sdlp_common.c # CRC16 implementation
38+
│ ├── sdlp_tm.c # TM frame implementation
39+
│ └── sdlp_tc.c # TC frame implementation
40+
├── examples/
41+
│ ├── tm_example.c # TM frame example
42+
│ └── tc_example.c # TC frame example
43+
├── docs/
44+
│ ├── 132x0b3_TM_SDLP.pdf # CCSDS 132.0-B-3 standard
45+
│ └── 232x0b4e1c1_TC_SDLP.pdf # CCSDS 232.0-B-4 standard
46+
├── Makefile
47+
└── README.md
48+
```
1749

1850
## Building
1951

20-
Build the library and examples using Make:
52+
### Build Everything
2153

2254
```bash
23-
make all # Build library and examples
24-
make lib # Build library only
25-
make examples # Build examples only
26-
make test # Run example programs
27-
make clean # Clean build artifacts
55+
make all
2856
```
2957

3058
This will create:
3159
- `libsdlp.a` - Static library
3260
- `bin/tm_example` - TM frame example
3361
- `bin/tc_example` - TC frame example
3462

35-
## Usage
63+
### Build Library Only
64+
65+
```bash
66+
make lib
67+
# Produces: libsdlp.a (static)
68+
```
69+
70+
### Build Examples
71+
72+
```bash
73+
make examples
74+
```
3675

37-
### Telemetry (TM) Example
76+
### Run Tests
77+
78+
```bash
79+
make test
80+
```
81+
82+
### Clean
83+
84+
```bash
85+
make clean # Remove build artifacts
86+
```
87+
88+
## Quick Start
89+
90+
### Create and Send a TM Frame
3891

3992
```c
4093
#include "sdlp_tm.h"
4194

42-
sdlp_tm_frame_t frame;
4395
uint8_t buffer[1500];
4496
size_t encoded_size;
4597

4698
// Create a TM frame
47-
const char *data = "Temperature: 25C";
99+
const char *data = "Temperature: 25C, Voltage: 3.3V";
100+
sdlp_tm_frame_t frame;
48101
sdlp_tm_create_frame(&frame, 0x123, 2, (uint8_t *)data, strlen(data));
49102

50103
// Encode frame to buffer
51-
sdlp_tm_encode_frame(&frame, buffer, sizeof(buffer), &encoded_size);
104+
if (sdlp_tm_encode_frame(&frame, buffer, sizeof(buffer), &encoded_size) == SDLP_SUCCESS) {
105+
printf("TM frame encoded: %zu bytes\n", encoded_size);
106+
}
107+
```
108+
109+
### Parse an Incoming TM Frame
52110
53-
// Decode frame from buffer
111+
```c
54112
sdlp_tm_frame_t decoded;
55-
sdlp_tm_decode_frame(buffer, encoded_size, &decoded);
113+
if (sdlp_tm_decode_frame(buffer, encoded_size, &decoded) == SDLP_SUCCESS) {
114+
printf("Spacecraft ID: 0x%03X, Data: %.*s\n",
115+
decoded.header.spacecraft_id,
116+
(int)decoded.data_length, decoded.data);
117+
}
56118
```
57119

58-
### Telecommand (TC) Example
120+
### Create and Send a TC Frame
59121

60122
```c
61123
#include "sdlp_tc.h"
62124

63-
sdlp_tc_frame_t frame;
125+
/* Telecommand identifiers */
126+
#define TC_CMD_SET_MODE_SAFE 0x01U
127+
64128
uint8_t buffer[1500];
65129
size_t encoded_size;
66130

67-
// Create a TC frame
68-
const char *cmd = "ENABLE_SENSOR";
69-
sdlp_tc_create_frame(&frame, 0x456, 1, 0, (uint8_t *)cmd, strlen(cmd));
131+
// Create a TC frame with a numeric command ID
132+
uint8_t cmd_id = TC_CMD_SET_MODE_SAFE;
133+
sdlp_tc_frame_t frame;
134+
sdlp_tc_create_frame(&frame, 0x123, 1, 42, &cmd_id, sizeof(cmd_id));
70135

71136
// Encode frame to buffer
72-
sdlp_tc_encode_frame(&frame, buffer, sizeof(buffer), &encoded_size);
137+
if (sdlp_tc_encode_frame(&frame, buffer, sizeof(buffer), &encoded_size) == SDLP_SUCCESS) {
138+
printf("TC frame encoded: %zu bytes\n", encoded_size);
139+
}
140+
```
73141
74-
// Decode frame from buffer
142+
### Parse an Incoming TC Frame
143+
144+
```c
75145
sdlp_tc_frame_t decoded;
76-
sdlp_tc_decode_frame(buffer, encoded_size, &decoded);
146+
if (sdlp_tc_decode_frame(buffer, encoded_size, &decoded) == SDLP_SUCCESS) {
147+
printf("Spacecraft ID: 0x%03X, Command ID: 0x%02X\n",
148+
decoded.header.spacecraft_id,
149+
decoded.data[0]);
150+
}
77151
```
78152

79-
## API Overview
153+
## API Reference
154+
155+
### Common
80156

81-
### Common Functions
82-
- `sdlp_crc16()` - Calculate CRC16 checksum
157+
```c
158+
// Calculate CRC-16-CCITT checksum
159+
uint16_t sdlp_crc16(const uint8_t *data, size_t length);
160+
```
83161
84162
### TM Functions
85-
- `sdlp_tm_create_frame()` - Create a TM frame with data
86-
- `sdlp_tm_encode_frame()` - Encode frame to byte buffer
87-
- `sdlp_tm_decode_frame()` - Decode frame from byte buffer
163+
164+
```c
165+
// Create a TM frame with payload data
166+
int sdlp_tm_create_frame(sdlp_tm_frame_t *frame, uint16_t spacecraft_id,
167+
uint8_t virtual_channel_id, const uint8_t *data,
168+
uint16_t data_length);
169+
170+
// Encode a TM frame into a byte buffer
171+
int sdlp_tm_encode_frame(const sdlp_tm_frame_t *frame, uint8_t *buffer,
172+
size_t buffer_size, size_t *encoded_size);
173+
174+
// Decode a TM frame from a byte buffer (validates CRC)
175+
int sdlp_tm_decode_frame(const uint8_t *buffer, size_t buffer_size,
176+
sdlp_tm_frame_t *frame);
177+
```
88178

89179
### TC Functions
90-
- `sdlp_tc_create_frame()` - Create a TC frame with data
91-
- `sdlp_tc_encode_frame()` - Encode frame to byte buffer
92-
- `sdlp_tc_decode_frame()` - Decode frame from byte buffer
93180

94-
All functions return `SDLP_SUCCESS` (0) on success or a negative error code on failure.
181+
```c
182+
// Create a TC frame with command data
183+
int sdlp_tc_create_frame(sdlp_tc_frame_t *frame, uint16_t spacecraft_id,
184+
uint8_t virtual_channel_id, uint8_t frame_seq_num,
185+
const uint8_t *data, uint16_t data_length);
186+
187+
// Encode a TC frame into a byte buffer
188+
int sdlp_tc_encode_frame(const sdlp_tc_frame_t *frame, uint8_t *buffer,
189+
size_t buffer_size, size_t *encoded_size);
190+
191+
// Decode a TC frame from a byte buffer (validates CRC)
192+
int sdlp_tc_decode_frame(const uint8_t *buffer, size_t buffer_size,
193+
sdlp_tc_frame_t *frame);
194+
195+
// Set TC segment header fields (requires TC_SEGMENT_HEADER_ENABLED)
196+
int sdlp_tc_set_segment_header(sdlp_tc_frame_t *frame,
197+
sdlp_tc_seq_flag_t sequence_flags, uint8_t map_id);
198+
```
95199
96-
## Project Structure
200+
All functions return `SDLP_SUCCESS` (0) on success or a negative error code on failure:
201+
- `SDLP_ERROR_INVALID_PARAM` (-1): NULL pointer or invalid parameter
202+
- `SDLP_ERROR_BUFFER_TOO_SMALL` (-2): Output buffer too small
203+
- `SDLP_ERROR_INVALID_FRAME` (-3): Frame structure invalid
204+
- `SDLP_ERROR_CRC_MISMATCH` (-4): CRC validation failed
97205
98-
```
99-
.
100-
├── include/ # Header files
101-
│ ├── sdlp_common.h # Common definitions and CRC
102-
│ ├── sdlp_tm.h # TM frame definitions
103-
│ └── sdlp_tc.h # TC frame definitions
104-
├── src/ # Implementation files
105-
│ ├── sdlp_common.c
106-
│ ├── sdlp_tm.c
107-
│ └── sdlp_tc.c
108-
├── examples/ # Example programs
109-
│ ├── tm_example.c
110-
│ └── tc_example.c
111-
└── Makefile # Build configuration
112-
```
206+
## Memory Usage (Estimated)
207+
208+
- **Library (stripped)**: < 5 KB
209+
- **Per TM frame buffer**: `TM_PRIMARY_HEADER_SIZE` (6) + data + 2 bytes FECF
210+
- **Per TC frame buffer**: `TC_PRIMARY_HEADER_SIZE` (5) + data + 2 bytes FECF
211+
- **Maximum data per frame**: 1024 bytes (`TM_MAX_DATA_SIZE` / `TC_MAX_DATA_SIZE`)
212+
213+
## Limitations and Extensions
214+
215+
Current implementation focuses on core protocol features:
216+
217+
- No automatic retransmission handling
218+
- No flow control or bandwidth management
219+
- No segmentation beyond optional TC segment header
220+
- Single static frame counter (not thread-safe)
221+
222+
These can be extended as needed for specific mission requirements.
113223
114-
## Requirements
224+
## References
115225
116-
- C compiler with C99 support (gcc, clang, etc.)
117-
- Make
226+
- CCSDS 132.0-B-3: TM Space Data Link Protocol ([docs/132x0b3_TM_SDLP.pdf](docs/132x0b3_TM_SDLP.pdf))
227+
- CCSDS 232.0-B-4: TC Space Data Link Protocol ([docs/232x0b4e1c1_TC_SDLP.pdf](docs/232x0b4e1c1_TC_SDLP.pdf))
118228
119229
## License
120230

examples/tc_example.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
#include <stdio.h>
2-
#include <string.h>
32
#include "sdlp_tc.h"
43

4+
/* Example telecommand identifiers */
5+
#define TC_CMD_SET_MODE_SAFE 0x01U
6+
57
int main(void) {
68
sdlp_tc_frame_t frame;
79
uint8_t buffer[1500];
@@ -10,7 +12,7 @@ int main(void) {
1012

1113
printf("=== TC Frame Example ===\n\n");
1214

13-
const char *command_data = "SET_MODE SAFE";
15+
uint8_t cmd_id = TC_CMD_SET_MODE_SAFE;
1416
uint16_t spacecraft_id = 0x123;
1517
uint8_t virtual_channel = 1;
1618
uint8_t sequence_number = 42;
@@ -19,11 +21,10 @@ int main(void) {
1921
printf("Spacecraft ID: 0x%03X\n", spacecraft_id);
2022
printf("Virtual Channel: %d\n", virtual_channel);
2123
printf("Sequence Number: %d\n", sequence_number);
22-
printf("Command: %s\n", command_data);
24+
printf("Command ID: 0x%02X\n", cmd_id);
2325

2426
result = sdlp_tc_create_frame(&frame, spacecraft_id, virtual_channel,
25-
sequence_number, (const uint8_t *)command_data,
26-
strlen(command_data));
27+
sequence_number, &cmd_id, sizeof(cmd_id));
2728

2829
if (result != SDLP_SUCCESS) {
2930
printf("Error creating frame: %d\n", result);
@@ -73,7 +74,7 @@ int main(void) {
7374
printf("Segment Header: sequence_flags=0x%X map_id=%d\n",
7475
decoded_frame.segment_header.sequence_flags, decoded_frame.segment_header.map_id);
7576
#endif
76-
printf("Command: %.*s\n", (int)decoded_frame.data_length, decoded_frame.data);
77+
printf("Command ID: 0x%02X\n", decoded_frame.data[0]);
7778
printf("CRC: 0x%04X\n", decoded_frame.fecf);
7879

7980
printf("\n=== TC Frame Example Complete ===\n");

0 commit comments

Comments
 (0)