| Name | Modified | Size | Downloads / Week |
|---|---|---|---|
| Parent folder | |||
| README.md | 2026-09-30 | 21.8 kB | |
| v4.4.0 source code.tar.gz | 2026-09-30 | 21.6 MB | |
| v4.4.0 source code.zip | 2026-09-30 | 23.3 MB | |
| Totals: 3 Items | 45.0 MB | 0 | |
Highlights
Major Features
- WebAssembly Sequencer: new
Svc::WasmSequencerruns sequences compiled to WebAssembly (via the spacewasm interpreter, built as an external Rust/C library). Supports load/run/pause/resume/cancel, timeouts, commands with response tracking, telemetry and parameter reads, time, events, sleeps, and serial I/O. Driven by two FPP state machines and configured with a project-suppliedFw::MemAllocator. A Rust toolchain is required only when the component is built. - CCSDS TM packet spanning:
Svc::ComAggregatorcan now split Space Packets across TM transfer frames (First Header Pointer reported throughComCfg::FrameContext.firstHeaderPointer). Opt-in viaComCcsdsConfig.Aggregator.enablePacketSpanning; requiresSvc.Ccsds.TmFramerand a ground deframer that reassembles spanned packets. - AES-256-GCM for CCSDS SDLS: new
Svc::Ccsds::AesGcmEncryptor/AesGcmDecryptorimplement the SDLS encryptor/decryptor interfaces on top of OpenSSL, replacing the clear-text null ciphers for deployments that need confidentiality and authentication. TheClearText*components now emit a throttledNullCipherInUseWARNING_HI event so an unauthenticated link is never silent. - Data products: new
Svc::ComLoggerDprecordsFw::ComBuffers into data-product containers (an alternative to file-basedSvc::ComLogger);Svc::DpWritergains matched[DpWriterNumPorts]port arrays so one instance can serve multiple fused data-product paths;Svc::DpCatalogskips products already markedTRANSMITTEDin its state file. - Time: new passive
Svc::TimeConverterconvertsFw::Timevalues between time bases using runtime-supplied offsets (commands, ports, fixed-capacity offset table).Os::Posix::RawTimenow honoursOs::RawTimeSource(REALTIME,MONOTONIC, andBOOTTIMEon Linux); intervals between different clock sources returnINVALID_PARAMSinstead of a meaningless difference. - Command dispatch:
Svc::CmdDispatcherreportsCLEAREDto callers whose tracking entries are cleared, and can optionally dispatch commands when its sequence tracker is full (cmdDisp.configure(true), reported asDISPATCHED_UNTRACKED). Its dropped-command counter is now safe under concurrent overflow. - OSAL:
Os::Mutex/Os::ConditionVariablejoinOs::RawTimeas configurable aliases (default: link-timeOs::Delegate*), allowing platform-specific implementations to be selected at compile time and devirtualized; all three selections now live in a singleconfig/OsSelection.hpp. NewOs::Posix::TASK_PRIORITY_NON_REALTIMEselectsSCHED_OTHERfor tasks that must not run under real-time scheduling. - Drivers:
Drv::LinuxUartDriverbecomesDrv::PosixUartDriver(available on all POSIX platforms). TCP sends to a disconnected peer no longer raiseSIGPIPE, and send timeouts returnSOCK_INTERRUPTED_TRY_AGAINfor retry. - File security: fail-closed path sandboxing extended to
Svc::FileManager(newconfigure(sandboxDir)),Svc::FileDownlink, and the whole ofSvc::PrmDb;Os::SandboxedFilerejects every open until configured. See Breaking Changes for the default subtopology behaviour.
Security Fixes
This release continues the hardening effort begun in v4.3.0 — upgrading is recommended:
- Fail-closed sandboxing of every path-bearing command in
Svc::FileManager(PathOutsideSandboxevent +VALIDATION_ERROR), ofFileDownlinkreads, and of allPrmDbfile access;Os::SandboxedFileis fail-closed until configured. - Overflow-safe bounds checks in
Fw::LinearBufferBaseserialization andSvc::BufferManagerallocation sizing;Os::Generic::PriorityQueuereturnsSIZE_MISMATCHwithout consuming an undersized message. - Asserts on externally-reachable inputs replaced with events/errors: overlong CRC hash-file names (
Utils::CRCChecker,Svc::FileWorker), stalefileDonecallbacks inSvc::DpCatalog,PRM_LOAD_FILEwith an empty file name,FLUSH_QUEUE/SET_QUEUE_PRIORITYindex validation inSvc::ComQueue,FpySequencerdeserialize failures,WasmSequencerhost-call failures. Svc::FileWorkerandSvc::BufferLoggertruncate existing files on non-append writes (no stale trailing bytes).SIGPIPE-safe TCP sends inDrv::IpSocket(MSG_NOSIGNAL/SO_NOSIGPIPE).- Clear-text SDLS ciphers announce themselves with
NullCipherInUse; documentation now instructs replacing, not augmenting, the null ciphers.
Breaking Changes
Configuration Changes
ComCfg.AggregationSize removed; aggregator size moves to ComCcsdsConfig.Aggregator
Svc::ComAggregator now owns idle filling and sizes its buffer from an allocator. The ComCfg.AggregationSize dictionary constant is gone; the ComCcsds subtopology configures the aggregator from new constants. Projects overriding ComCfg.fpp must delete the constant, and projects overriding ComCcsdsConfig.fpp must add the Aggregator module.
Migration details
:::diff # ComCfg.fpp - @ Size of the aggregation buffer - dictionary constant AggregationSize = Svc.Ccsds.TmDataFieldSize - ... :::diff # ComCcsdsConfig.fpp module ComCcsdsConfig { + module Aggregator { + @ Size in bytes of every aggregate emitted by the aggregator (must equal Svc.Ccsds.TmDataFieldSize + @ unless a layer between the aggregator and the framer adds bytes, e.g. SDLS) + constant aggregationSize = Svc.Ccsds.TmDataFieldSize + @ Span packets across TM transfer frames (requires Svc.Ccsds.TmFramer and a spanning-aware ground deframer) + constant enablePacketSpanning = false + } Projects using `ComCcsdsSdls` must reserve the SA index (and any per-frame encryptor overhead) so that the encrypted data field is exactly frame-sized: :::fpp constant aggregationSize = Svc.Ccsds.TmDataFieldSize - Svc.Ccsds.SdlsSaIndexSize Every emitted aggregate is now exactly `aggregationSize` bytes and idle-filled — including in the frame-less Space Packet variant of the subtopology, where each flush costs a full aggregate. `Svc.Ccsds.TmFramer` no longer inserts idle packets and asserts if it receives anything other than an exactly-sized data field.New fields in ComCfg::FrameContext
FrameContext gained the Space Packet type bit and the TM First Header Pointer. Projects overriding ComCfg.fpp must add the enum, the fields, and their defaults.
Migration details
:::diff + @ Packet type in the Space Packet Primary Header + enum SppPacketType : U8 { + SPP_TELEMETRY = 0 @< Telemetry / data packet (downlink) + SPP_COMMAND = 1 @< Telecommand packet (uplink) + } default SPP_TELEMETRY + struct FrameContext { comQueueIndex: FwIndexType apid: Apid + pktType: SppPacketType @< 1 bit packet type in space packet primary header hasSecHdr: bool ... saIndex: U16 + firstHeaderPointer: U16 @< TM First Header Pointer, set by ComAggregator, consumed by TmFramer } default { comQueueIndex = 0 apid = Apid.FW_PACKET_UNKNOWN + pktType = SppPacketType.SPP_TELEMETRY ... + firstHeaderPointer = 0 } `Svc.Ccsds.SpacePacketFramer` now sets the primary-header packet-type bit from `pktType` (previously always 0).Default FwSizeStoreType is now FwSizeType
The serialized width of string lengths and buffer sizes changes from U16 to the width of FwSizeType (U64 on 64-bit platforms by default).
Migration details
:::diff # FpConfig.fpp -dictionary type FwSizeStoreType = U16 +dictionary type FwSizeStoreType = FwSizeType > [!WARNING] > This change is a **required** change to ensure that assumptions the framework makes on sizes hold correctly. Using any other configuration is at a project's own risk. This changes the on-wire and on-disk format of anything carrying a string or size-prefixed buffer (command arguments, events, telemetry, parameter database, data products, sequence files).File sandboxes are configured by the subtopologies (default: unrestricted)
Svc::FileUplink, Svc::FileDownlink, Svc::FileManager, and Svc::PrmDb are fail-closed until configured. The FileHandling subtopology now configures all four from a new constant (default "/", i.e. the historical unrestricted behaviour) and also calls prmDb.configure(FileHandlingConfig::Paths::prmDbFile) for you.
Migration details
:::fpp # FileHandlingConfig.fpp module Paths { constant prmDbFile = "PrmDb.dat" # Parameter database storage file constant sandboxDir = "/" # "/" = unrestricted } Deployments that previously called `FileHandling::prmDb.configure(...)` / `FileHandling::fileUplink.configure(...)` from `configureTopology()` may remove those calls (the `prmDb.configure` call is now redundant). To actually confine file access, override `sandboxDir` or re-configure after the autocoded `configComponents` phase: :::diff void configureTopology() { - FileHandling::fileUplink.configure("/tmp/uplink/"); - FileHandling::prmDb.configure("PrmDb.dat"); + // Restrict file access to the working directory (where PrmDb.dat lives) + FileHandling::fileUplink.configure("."); + FileHandling::fileDownlink.configure("."); + FileHandling::fileManager.configure("."); + FileHandling::prmDb.configureSandbox("."); } Deployments instantiating these components outside the subtopology **must** call `configure()` / `configureSandbox()` or every file operation will fail with `OUTSIDE_SANDBOX`. `FileHandlingConfig` is no longer an `INTERFACE` config module (it now generates C++ constants).Svc::ComAggregator must be configured with an allocator
ComAggregator::configure() now takes the aggregation size, spanning flag, allocation ID, and a Fw::MemAllocator, and cleanup() must be called at teardown; the ComCcsds subtopology does this for you, deployments wiring the aggregator directly must add the calls.
Migration details
:::diff - aggregator.configure(false); + aggregator.configure(ComCcsdsConfig::Aggregator::aggregationSize, + ComCcsdsConfig::Aggregator::enablePacketSpanning, + allocationId, memAllocator); + ... + aggregator.cleanup(); // in tearDownComponents The `ComCcsds` subtopology does this itself and requires the deployment to provide `ComCcsds::Allocation::memAllocator` (as in v4.3.0).OSAL implementation selection consolidated into config/OsSelection.hpp
Os::Mutex and Os::ConditionVariable are now configurable aliases like Os::RawTime, and the per-service selection headers are collapsed into one: default/config/OsDelegateRawTime.hpp is removed (along with the interim OsDelegateMutex.hpp) and replaced by default/config/OsSelection.hpp. Projects that override OsDelegateRawTime.hpp for compile-time RawTime selection must rename their override to OsSelection.hpp and, because the override replaces the whole default, define every alias and OS_*_HEADER macro — not just the service being changed.
Migration details
:::diff -// my-project/config/OsDelegateRawTime.hpp -#ifndef CONFIG_OS_DELEGATERAWTIME_HPP -#define CONFIG_OS_DELEGATERAWTIME_HPP +// my-project/config/OsSelection.hpp +#ifndef CONFIG_OSSELECTION_HPP +#define CONFIG_OSSELECTION_HPP namespace Va416x0Os { class TimerRawTime; } namespace Os { using RawTime = Va416x0Os::TimerRawTime; +class DelegateMutex; +class DelegateConditionVariable; +using Mutex = DelegateMutex; +using ConditionVariable = DelegateConditionVariable; } #define OS_RAW_TIME_HEADER "Va416x0/Os/TimerRawTime/TimerRawTime.hpp" +#define OS_MUTEX_HEADER <os delegatemutex.hpp> +#define OS_CONDITION_VARIABLE_HEADER <os delegateconditionvariable.hpp> -#endif // CONFIG_OS_DELEGATERAWTIME_HPP +#endif // CONFIG_OSSELECTION_HPP :::diff # my-project/config/CMakeLists.txt register_fprime_config( ... - "${CMAKE_CURRENT_LIST_DIR}/OsDelegateRawTime.hpp" + "${CMAKE_CURRENT_LIST_DIR}/OsSelection.hpp" `Os::Mutex` and `Os::ConditionVariable` must be overridden together with a compatible pair (the condition variable operates on the mutex's handle); `Os/ConditionVariableInterface.hpp` `static_assert`s that either both or neither are the link-time delegates. The aliased implementation module must still be in the link (`CHOOSES_IMPLEMENTATIONS` / `DEPENDS`).Os::RawTimeSource on POSIX
default/config/Os/RawTimeSource.hpp now maps RAWTIME_DEFAULT/REALTIME/MONOTONIC/BOOTTIME onto POSIX clock IDs. Projects overriding this header should re-base on the new default.
Drv.LinuxUartDriver renamed to Drv.PosixUartDriver
The component, its directory, and its header are renamed; update topology instances and #includes.
Migration details
:::diff - instance uartDriver: Drv.LinuxUartDriver base id 0x4C00 + instance uartDriver: Drv.PosixUartDriver base id 0x4C00 :::diff -#include "Drv/LinuxUartDriver/LinuxUartDriver.hpp" +#include "Drv/PosixUartDriver/PosixUartDriver.hpp"register_fprime_config(BASE_CONFIG) deprecated
Replace with GLOBAL_IMPLICIT_DEPENDENCY; BASE_CONFIG still works but emits a CMake warning. FPRIME_ENABLE_JSON_MODEL_GENERATION is deprecated in favour of the native FPP Python bindings.
User Breaking Changes
parameterUpdated is now invoked for every parameter at load (FPP 3.4.0)
The generated parametersLoaded() hook now calls parameterUpdated(id) once per parameter after loadParameters(). Handlers written assuming a parameter is only VALID will assert on the DEFAULT case. Use the new FW_PARAM_OK macro, which accepts both VALID and DEFAULT.
Migration details
:::diff +#include "Fw/Prm/ParamValid.hpp" ... void Led::parameterUpdated(FwPrmIdType id) { Fw::ParamValid isValid = Fw::ParamValid::INVALID; U32 interval = this->paramGet_BLINK_INTERVAL(isValid); - FW_ASSERT(isValid == Fw::ParamValid::VALID, static_cast<fwassertargtype>(isValid)); + FW_ASSERT(FW_PARAM_OK(isValid), static_cast<fwassertargtype>(isValid)); Components that already iterate their parameters in `parametersLoaded()` should remove that loop (or override `parametersLoaded()` to restore the previous no-op) to avoid double handling.New Fw::CmdResponse values
Fw::CmdResponse gains CLEARED = 6 and DISPATCHED_UNTRACKED = 7; exhaustive switches over command responses must handle them.
Migration details
:::diff enum CmdResponse { ... BUSY = 5 + CLEARED = 6 @< Command tracking was cleared before the command completed + DISPATCHED_UNTRACKED = 7 @< Dispatched with a full sequence tracker; completion status is unknown } Sequencers and ground tooling that switch exhaustively over command responses must handle the new values.FileAnnounce / FileDispatch port file names are fixed-size
The file-name arguments of Svc.FileAnnounce and Svc.FileDispatch are now string size FileNameStringSize (default 240) rather than the unsized string (256 default). Handler implementations still receive const Fw::StringBase&, but the serialized port ABI and maximum file-name length change; file names longer than FileNameStringSize are rejected instead of truncated.
Svc.Ping input ports drop on overflow
PingIn on ActiveRateGroup, BufferAccumulator, BufferLogger, CmdDispatcher, CmdSequencer, ComLogger, EventManager, FileDownlink, FileManager, FileUplink, FpySequencer, PrmDb, TlmChan, and TlmPacketizer is now drop instead of asserting on queue overflow, so Svc::Health can report the wedged component.
Svc::TlmPacketizer accepts zero-channel packets
A packet definition with no channels is now valid (sent header-only on SEND_PKT); a non-empty packet with a null channel list still asserts. Projects that relied on the assert as a check must validate their packet definitions elsewhere.
Svc::ComQueue depth 0 disables a queue
Previously an assertion failure; now the entry is treated as full (messages are dropped through the QueueOverflow path and buffers returned). An all-zero table still asserts.
Svc::FileManager command paths are canonicalized
All ten path-bearing commands resolve their arguments with Os::FilePathUtils::resolveFromCwd before touching the filesystem and reject paths outside the sandbox with a PathOutsideSandbox WARNING_HI event and VALIDATION_ERROR. Errors telemetry increments on rejection.
.CRC32 files are endian-independent
Utils::CRCChecker now writes and reads the CRC through F Prime serialization (big-endian), matching Utils::Hash, Os::ValidatedFile, and Svc::ComLogger. .CRC32 sidecar files written by CRCChecker in earlier releases on little-endian hosts will fail validation and must be regenerated.
Developer Breaking Changes
Os::Mutex / Os::ConditionVariable are no longer concrete classes
Os/Mutex.hpp and Os/Condition.hpp now provide Os::Mutex / Os::ConditionVariable as aliases selected via config/OsSelection.hpp; Os::MutexInterface / Os::MutexHandle moved to Os/MutexInterface.hpp, Os::ConditionVariableInterface to Os/ConditionVariableInterface.hpp, and Os/Mutex.cpp was removed. lock()/unLock()/ScopeLock and wait() are defined inline on the interfaces. Code that forward-declared class Os::Mutex or subclassed it must include the new headers and use the alias; OSAL implementations of Os_Mutex must derive from Os::MutexInterface.
Svc.Ccsds.TmFramer serializes only
The framer no longer idle-fills; it asserts data.getSize() == TmDataFieldSize. Components feeding it directly must emit exactly-sized data fields (use Svc::Ccsds::Utils::IdlePacket for filling).
Os::RawTime::getTimeInterval across clock sources returns INVALID_PARAMS
Two Os::RawTime values read from different Os::RawTimeSource clocks no longer produce a meaningless difference; getTimeInterval()/getDiffUsec() return INVALID_PARAMS and leave the output unwritten, so callers must initialize and check. Utils::RateLimiter and Utils::TokenBucket no longer assert when driven with Fw::Time values in a different time base; they adopt the caller's base.
Os::Generic::PriorityQueue::receive size mismatch
Returns SIZE_MISMATCH and leaves the message on the queue rather than dropping it; callers must retry with a sufficiently large buffer.
Utils::CRCChecker new status
crc_stat_t gains FAILED_FILE_NAME_TOO_LONG (appended); switch statements over the enum need the new case.
Fw::LinearBufferBase bool serialization
Booleans are serialized through the U8 path and pointer size is static_asserted; custom serializable types with hand-written serialization should mirror this.
Unit tests and FwSizeStoreType
Tests that compare serialized sizes or offsets against literal byte counts (assuming a two-byte length prefix) must be expressed in terms of sizeof(FwSizeStoreType); the framework's own tests were updated accordingly.
Deprecations
register_fprime_config(BASE_CONFIG)— useGLOBAL_IMPLICIT_DEPENDENCY.FPRIME_ENABLE_JSON_MODEL_GENERATION— the FPP JSON model is superseded by the native FPP Python bindings.Drv/LinuxUartDriver— useDrv/PosixUartDriver.Svc::WasmSequencerhost importargs(fprime_wasm_get_args) is a no-op: sequence arguments were removed pending typed variant/vector argument support.
New Contributors
- @sylvesterkaczmarek made their first contribution in https://github.com/nasa/fprime/pull/5805
- @winklemad made their first contribution in https://github.com/nasa/fprime/pull/5775
- @claradavisb made their first contribution in https://github.com/nasa/fprime/pull/5795
- @thomas-bc-autowot made their first contribution in https://github.com/nasa/fprime/pull/5949
- @Dev-next-gen made their first contribution in https://github.com/nasa/fprime/pull/5972
- @Voyagerroc-Lab made their first contribution in https://github.com/nasa/fprime/pull/6010
- @sjsreehari made their first contribution in https://github.com/nasa/fprime/pull/6003
- @jrussino made their first contribution in https://github.com/nasa/fprime/pull/5936
- @weggert2 made their first contribution in https://github.com/nasa/fprime/pull/6069
- @ynielson-firefly made their first contribution in https://github.com/nasa/fprime/pull/5996
- @rcurtin made their first contribution in https://github.com/nasa/fprime/pull/6043
- @Nas01010101 made their first contribution in https://github.com/nasa/fprime/pull/6063
Full Changelog: https://github.com/nasa/fprime/compare/v4.3.0...v4.4.0