fprime/Fw/Buffer/docs/sdd.md
Vince Woo 48e4720419
Created new SerialBufferBase as a parent of SerializeBufferBase (now renamed LinearBufferBase). (#4288)
* Created new SerialBufferBase as a parent of SerializeBufferBase. Renaming interface functions to be less confusing.

* Deprecating copyRawOffset. No direct use-cases in F' core.

* Make SerialBufferBase a true pure virtual interface.

* Changing Serializable to work with SerialBufferBase parent interface.

* Changing copyRaw and copyRawOffset to work with SerialBufferBase

* Updating documentation for SerialBufferBase usage

* Adding some documentation. Adding missing ASSERT in copyRaw. Fixing some bugs that new ASSERT uncovered.

* Renaming SerializeBufferBase to LinearBufferBase. Add a using declaration to maintain backwards compatability. Properly mark LinearBufferBase functions as override.

* Filling in the rest of the docstrings for the classes in Serializable

* Removing redundant virtual keyword on override function

* Applying clang formatting

* Incorporating PR comments

* Fix compile issues

* Bump version to alpha

* Format

* v

---------

Co-authored-by: M Starch <LeStarch@googlemail.com>
2025-11-06 16:23:20 -08:00

4.3 KiB

Fw::Buffer Serializable / Fw::BufferGet Port / Fw::BufferSend Port

1 Introduction

This module provides the following elements:

  • A type Fw::Buffer representing a wrapper around a variable-size buffer. This allows for passing a reference to the allocated memory around without a copy. Typically the memory is allocated in a buffer manager or similar component but this is not required.

  • A port Fw::BufferGet for requesting a buffer of type Fw::Buffer from a BufferManager and similar components.

  • A port Fw::BufferSend for sending a buffer of type Fw::Buffer from one component to another.

2 Design

The Fw::Buffer type wraps a pointer to memory and the size of that memory region. Thus, allowing users to pass the pointer and size around as a pair without incurring a copy of the data at each step. Note: Fw::Buffer is not safe to pass outside a given address space.

2.1 The Type Fw::Buffer

Fw::Buffer is a serializable class defining the following (private) fields. These fields are accessed through accessor functions.

Name Type Accessors Purpose
m_bufferData U8* getData()/setData() Pointer to the raw memory wrapped by this buffer
m_size U32 getSize()/setSize() Size of the raw memory region wrapped by this buffer
m_context U32 getContext()/setContext() Context of buffer's origin. Used to track buffers created by BufferManager

A value B of type Fw::Buffer is valid if m_bufferData != nullptr and m_size > 0; otherwise it is invalid. The interface function isValid reports whether a buffer is valid. Calling this function on a buffer B returns true if B is valid, otherwise false.

If a buffer B is invalid, then the pointer returned by B .getData() and the serialization interfaces returned by B .getSerializer() and B .getDeserializer() are considered invalid and should not be used.

2.2 The Port Fw::BufferGet

As shown in the following diagram, Fw::BufferGet has one argument size of type U32. It returns a value of type Fw::Buffer. The returned Fw::Buffer must be checked for validity before using.

Fw::BufferGet Diagram

2.3 The Port Fw::BufferSend

As shown in the following diagram, Fw::BufferSend has one argument fwBuffer of type Fw::Buffer.

Fw::BufferSend Diagram

3 Usage Notes

Components allocating Fw::Buffer objects may use the m_context field at their discretion. This field is typically used to track the origin of the buffer for eventual allocation.

When a component fails to allocate memory, it must set the m_bufferData field to nullptr and/or set the m_size field to zero to indicate that the buffer is invalid.

A receiver of an Fw::Buffer object B must check that B is valid before accessing the data stored in B. To check validity, you can call the interface function isValid().

Serializing and Deserializing with Fw::Buffer

Users can obtain a serialization buffer, sb, by calling either getSerializer() or getDeserializer(). Note that both of these methods return a Fw::ExternalSerializeBufferWithMemberCopy object that is meant to be managed by the caller and only affects the data of the underlying buffer.

Serializing to Fw::Buffer

U32 my_data = 10001;
U8  my_byte = 2;
auto sb = my_fw_buffer.getSerializer();
// Defaults to big-endian
sb.serializeFrom(my_data);
sb.serializeFrom(my_byte);
// Or for little-endian
sb.serializeFrom(my_data, Fw::Endianness::LITTLE);
sb.serializeFrom(my_byte, Fw::Endianness::LITTLE);

Deserializing from Fw::Buffer

U32 my_data = 0;
U8  my_byte = 0;
auto sb = my_fw_buffer.getDeserializer();
// Defaults to big-endian
sb.deserializeTo(my_data);
sb.deserializeTo(my_byte);
// Or for little-endian
sb.deserializeTo(my_data, Fw::Endianness::LITTLE);
sb.deserializeTo(my_byte, Fw::Endianness::LITTLE);

The objects returned by getSerializer() and getDeserializer() implement the Fw::SerialBufferBase interface. This allows them to be passed directly to Fw::Serializable::serializeTo and Fw::Serializable::deserializeFrom on user-defined serializable types.