Memory Objects and Firmware Updates

🢀 Back to programming guide


Memory Objects

Memory objects are binary blobs that AVB devices expose to the network through the AVB ATDECC protocol. They can have many purposes, but commonly the two main uses of them are:

Stack Architecture

Hive Controller showing an AVB entity with its logo, supplied via memory object

Memory Object Configuration

To add a memory object to an AVB device you include a <memory_object> section in the entity config xml file. Each <memory_object> must sit within a <memory_objects> node within a <configuration> node of the XML. Here is an example of a memory object description:

<memory_object>
    <object_name>Entity PNG</object_name>
    <memory_object_type>0xA</memory_object_type>          <!-- 0xA is PNG_ENTITY -->
    <target_descriptor_type>0</target_descriptor_type>    <!-- 0 is AEM_DT_ENTITY -->
    <target_descriptor_index>0</target_descriptor_index>
    <start_address>0x100000</start_address>
    <maximum_length>0x100000</maximum_length>
    <length>0</length>
    <permissions>1</permissions>
</memory_object>

The <memory_object_type> describes the type of the memory object. Values are from Table 7.19 of 1722.1-2013, and can also be found in stackTypes.h. They are summarised here:

value type
0x0000 AVDECC Entity specific firmware image.
0x0001 Vendor specific object.
0x0002 AVDECC Entity specific crash information
0x0003 AVDECC Entity specific UTF-8 encoded logging information.
0x0004 AVDECC Entity specific settings storage used at system startup.
0x0005 AVDECC Entity specific settings storage. See 7.2.10.3.
0x0006 An image of the manufacturer’s logo in the Scalable Vector Graphic (SVG) format.
0x0007 An image representation of the entity in Scalable Vector Graphic (SVG) format.
0x0008 A generic image in Scalable Vector Graphic (SVG) format.
0x0009 An image of the manufacturer’s logo in the Portable Network Graphic (PNG) format.
0x000a An image of the entity in the Portable Network Graphic (PNG) format.
0x000b A generic image in the Portable Network Graphic (PNG) format.
0x000c COLLADA DAE 3D model of the manufacturer’s logo using the COLLADA Digital Asset
0x000d COLLADA DAE 3D model of the entity using the COLLADA Digital Asset Schema.
0x000e Generic COLLADA DAE 3D model using the COLLADA Digital Asset Schema.
0x000f to ffff16 Reserved for future use.

<target_descriptor_type> is usually set to 0 (ENTITY descriptor type) and <target_descriptor_index> is usually set to 0 as the target of the memory object is usually the entity itself.

Each memory object maps into a global address space, a strange design choice in our opinion, but one we must adhere to. Therefore each memory object requires <start_address>, <length> and <maximum_length>tags. As memory objects can be written as well as read, they require both a <length> tag (current length) and a <maximum_length>tag (the maximum size the memory object can ever be). The <length> tag can be set to zero or omitted if the application returns this at runtime via the callback function appGetMemoryObjectSize().

As memory objects can be read, written and even executed, the <permissions> tag specifies which operations are permitted on the memory object. The value is a bit field taken from the following bit values:

value permission
0 NONE (default)
1 READ
2 WRITE
4 EXECUTE

Typically, vendor and device PNGs would only have the READ permission bit set.

Memory Object Access Interface API

The Sienda Stack requests the actual data contained in a memory object from the application using the following stack callbacks:

bool appGetMemoryObjectSize(uint32_t memoryObjectIndex, uint64_t &size, void *pContext);
bool appReadMemoryObject(uint32_t memoryObjectIndex, uint64_t offset, uint64_t size, uint8_t *pData, void *pContext);

appGetMemoryObjectSize() is used to retrieve the current size of the memory object at runtime. This way, things such as PNG files can be loaded at runtime and the size is not required to be known when the XML configuration file is created. If the sizes of the memory objects are specified in the configuration XML then the function can be left unimplemented (or return false for a particular memory object index).

appReadMemoryObject() requests a block of data from the specified memory object memoryObjectIndex, to be copied into pData from offset offset with size size. Return true if the data was successfully copied, or false otherwise.

!!! info Although the memory object descriptors require a <start_address> in the global address space, these global addresses are abstracted by the stack and so the callback function appReadMemoryObject() requests data at offset offset from the start of that specific memory object. There is no need for the application to be aware of, or compensate for, the <start_address> specified in the entity model XML. offset 0 is the first byte of the specified memory object data.

Firmware Updates

Firmware Update configuration

AVB device firmware updates can be performed over the network via an AVB controller. The firmware image is represented as a memory object of type FIRMWARE_IMAGE (value 0x0, 1722.1-2013 Table 7.19). Firmware memory objects must have the <permissions> tag set to WRITE to allow the memory object to be written. Note that the READ|WRITE permissions are not advertised to the controller but are used internally by the Sienda Stack to ensure that only memory objects with WRITE permission can be written.

A device containing a memory object for firmware updates would have a <memory_object> section such as this in the configuration XML:

<memory_object>
    <object_name>Firmware Update</object_name>
    <memory_object_type>0</memory_object_type>            <!-- 0 is FIRMWARE_IMAGE -->
    <target_descriptor_type>0</target_descriptor_type>    <!-- 0 is AEM_DT_ENTITY -->
    <target_descriptor_index>0</target_descriptor_index>
    <start_address>0x200000</start_address>
    <maximum_length>10485760</maximum_length>
    <length>0</length>
    <maximum_segment_length>10485760</maximum_segment_length>
    <permissions>2</permissions>
</memory_object>

Note that there is an extra field <maximum_segment_length> here (compared to read-only memory objects). The <maximum_segment_length> tag specifies the maximum amount of data that the device can receive in a single chunk before committing the data to persistent storage. For devices with plenty of RAM, this can be set to the same value as <length> or <maximum_length>, and the whole firmware image will be transferred to the device (and stored in RAM) before a command is sent to write the image to persistent storage. Devices with very little available RAM can set this to a sensible buffer size, and the controller should honour this value and only send <maximum_segment_length> bytes of data before committing the data to persistent storage. The controller will repeat this upload->write cycle several/many times until the whole firmware image is uploaded and written to persistent storage.

!!! info The Hive AVB Controller, as of September 2022, does NOT honour the <maximum_segment_length> field and so cannot be used to update the firmware in small memory constrained AVB devices. If you require a controller that can perform such firmware updates, please contact Sienda.

Devices supporting ATDECC firmware updates should also advertise the capability in the <entity_capabilities> field of the <entity> descriptor in the configuration XML. The bit field value 0x1 (EFU_MODE) should be present to indicate support of firmware updates.

Firmware Update access interface API

Firmware update requests are communicated to the application through the following stack callback functions:

bool appStartFirmwareUpload(uint32_t memoryObjectIndex, uint64_t totalSize, void *pContext);
bool appFirmwareUpload(uint32_t memoryObjectIndex, uint64_t offset, uint64_t size, uint8_t *pData, void *pContext);
bool appStartFirmwareWrite(uint32_t memoryObjectIndex, uint64_t offset, uint64_t size, void *pContext);
bool appReboot(void *pContext);

During a firmware update procedure (orchestrated via an AVB controller), the application should expect to receive callbacks in the following order:

!!! info for IEEE standards eagles: the perMill values and their interpretations are from 1722.1-2021. 1722.1-2013 defines the values to be returned in case of error differently. The stack expects the 1722.1-2021 values, but will attempt to appease 1722.1-2013 controllers by also sending value 0 in case of error, and by rounding value 0 (indicating 0% in 1722.1-2021 but ‘incomplete and stopped’ in 1722.1-2013 to 1 (0.01%))


🢀 Back to programming guide