Synapse cFS SDK
Synapse is a small interface definition language and code generator for NASA cFS-friendly data types. A .syn file can describe plain ABI-compatible structs, cFS Software Bus commands and telemetry packets, and cFS Table Services payloads; the synapse CLI turns those definitions into C headers or Rust #[repr(C)] bindings.
Quick Start
Install synapse with the path that best fits your environment.
For C developers and CI jobs without Rust installed, download a prebuilt binary from GitHub Releases:
|
For Rust users, install the cfs-synapse package from crates.io. The installed executable is still named synapse:
Generate C and Rust bindings from a .syn file:
The output file is named after the input file. For example, the commands above write generated/geometry_msgs.h and generated/geometry_msgs.rs.
Install
Prebuilt Binaries
Tagged releases attach archives for common platforms:
synapse-linux-x86_64.tar.gzsynapse-macos-x86_64.tar.gzsynapse-windows-x86_64.zip
Download the archive for your platform from the latest GitHub Release, extract it, and place the synapse executable somewhere on your PATH.
Cargo
The crates.io package is named cfs-synapse; the installed command is synapse.
From Source
Use the source workflow when contributing to Synapse itself:
If you have just installed, the common contributor workflow is:
The default test workflow skips the cfs-sys crate because it needs a local cFS tree and generated cFS build headers. To include it, bootstrap cFS first:
By default cFS is expected at /tmp/cFS. Override it with:
CFS_ROOT=/path/to/cFS
CLI
|
--lang cgenerates a cFS C header (.h) that includescfe.h.--lang rustgenerates Rust#[repr(C)]bindings (.rs) that referencecfs_sysheader types by default.- Without
-o, generated code is written to stdout.
Build Scripts
Rust projects can use Synapse from build.rs without requiring the synapse executable to be installed on PATH.
[]
= "0.1"
The library facade also exposes generate_rust_file, generate_file, and generate_str for custom build flows.
Mental Model
Use struct for plain data layout:
struct Point {
x: f64
y: f64
}
Plain structs do not include a cFS message header. They are useful as nested payload types and other reusable C-compatible data.
Use command for Software Bus packets sent to an app:
@mid(0x1880)
command SetMode {
mode: u8
}
Generated commands place CFE_MSG_CommandHeader_t first.
Use telemetry for Software Bus packets published by an app:
@mid(0x0801)
telemetry NavState {
position: geometry_msgs::Point
}
Generated telemetry packets place CFE_MSG_TelemetryHeader_t first.
Use table for cFS Table Services payload data:
table NavConfig {
max_speed: f64
enabled: bool
frame_id: string[<=32]
}
Generated tables do not include a Software Bus header. They are plain table data. The legacy message keyword still works for generic Software Bus packets, but new files should prefer command or telemetry.
Language Surface
The cFS generator currently emits:
namespaceprefixes for generated C type names, such asgeometry_msgs_Point_t.importdeclarations as C#includelines or Rustuse crate::...lines.constdeclarations as C#defines or Rustpub consts.structandtabledefinitions as plain data structs.command,telemetry, and legacymessagedefinitions as Software Bus packet structs with cFS headers.@mid(...)attributes as message ID constants.- Fixed arrays, bounded strings, dynamic arrays, and namespaced type references.
Enums, field defaults, and optional field markers are parsed into the AST, but cFS code generation for those pieces is still early. Prefer plain integer fields for generated packet payloads until enum emission and optional/default handling are completed.
See docs/language.md for the current language status and 0.1.x review checklist.
See docs/types.md for the supported type forms and generated C/Rust mappings.
Documentation Comments
Use ## for comments that should attach to the next declaration or field and eventually feed generated documentation:
## Stable identifier for one physical or logical camera.
struct CameraId {
## Mission-defined camera name.
name: string[<=32]
}
Use single # comments for ordinary notes that should not become API documentation.
UDP and Tables
When communicating with cFS through UDP apps such as CI_LAB or TO_LAB, UDP is only the transport. The bytes entering or leaving the Software Bus are still cFS packets, so generated command and telemetry types need the cFS header.
Table Services are different: the table data itself is normally a plain struct without a Software Bus header. Commands that load, validate, or activate tables are Software Bus command messages, but the table buffer/file is just table data.
Examples
Sample .syn files live in synapse-integration-tests/syn.
geometry_msgs.syn: ROS-like geometry telemetry packets.cfs_patterns.syn: minimal command, telemetry, and table examples.camera_msgs.syn: camera control syntax coverage, including commands to set mode/exposure, a command to send updated intrinsics, telemetry for camera status, and aCameraCalibrationtable containing persistent calibration data. It also exercises parsed enum and doc-comment support.
See docs/examples.md for links to all sample .syn files and checked-in generated output.
Workspace
cfs-synapse-parser: Pest grammar and AST builder for.syncfs-synapse-codegen-cfs: C and Rust cFS code generationcfs-synapse: public library facade andsynapseCLI binarycfs-sys: bindgen wrapper for selected cFS typessynapse-integration-tests: sample.synfiles and generated-code checksgenerated: checked-in generated geometry examples
Release Model
CI runs the core test suite on pull requests and pushes to main. Pushing a tag like v0.1.0 runs the release workflow, builds release binaries, and attaches platform archives to the GitHub Release.
Crates.io publishing is gated behind the repository variable PUBLISH_CRATE=true and the CARGO_REGISTRY_TOKEN secret. When enabled, the release workflow publishes cfs-synapse-parser, cfs-synapse-codegen-cfs, and then cfs-synapse.
See docs/publishing.md for the full release checklist and first-publish notes.
Editor Support
A local VS Code syntax-highlighting extension lives in vscode-synapse.
This launches VS Code with the extension development path pointed at the local Synapse grammar.