Adding Metadata to GBL Files

Introduction

Metadata

Metadata can be anything that can be put into a byte array. You can add text, structures, or binary data to your GBL files. Hence, when you update your device with a new firmware, you can also update other settings, e.g., a parameter set, that is stored in the persistent storage. You can also send extended version information along with the firmware, or you can send new security keys in a signed and encrypted GBL file. You can even send an extra firmware image as metadata intended to be sent to another device.

Adding Metadata to the GBL File

Metadata can be added when you create the GBL file with the „commander gbl create” command. Add the --metadata switch and the name of the file, that contains the metadata. For example:

commander gbl create application.gbl --app application.s37 --metadata metadata.bin

If you use the create_bl_files.bat file to create GBL files, edit the file and extend the commands with the --metadata switch.

Reading Metadata from the Uploaded Files

You can read the content of the metadata that was put into the GBL file as follows:

Note: Neither version is supported by the Bluetooth stack AppLoader because AppLoader decodes the GBL file on-the-fly, does not store the full GBL file anywhere, and does not allow accessing the metadata. To access metadata you have to implement an application uploader, as described in Implementing OTA Firmware Update in User Application and Uploading Images to Internal/External Flash Using OTA DFU.

Note that the application uploader can be used only in a device with an internal flash larger than 256k, or with a device that has an external flash.

Reading Metadata on-the-fly

When you upload a new firmware image, you will receive the image in chunks. These chunks are received by the application and they can be written into any storage slot using the API of Gecko Bootloader. At the same time, when you get a chunk of the uploaded image, you can run the GBL parser on it, using the API of Gecko Bootloader. When the parser finds metadata in the GBL file, it will call a callback function and pass the metadata to this function. It is good to note the following:

To initialize the GBL parser use the following code:

#define BTL_PARSER_CTX_SZ  0x200
static uint8_t parserContext[BTL_PARSER_CTX_SZ];
static BootloaderParserCallbacks_t parserCallbacks;

parserCallbacks.applicationCallback = NULL;
parserCallbacks.bootloaderCallback = NULL;
parserCallbacks.metadataCallback = metadataCallback;
bootloader_init();
bootloader_initParser((BootloaderParserContext_t *)parserContext,BTL_PARSER_CTX_SZ);

Note that the parser context size must be at least 384 bytes.

To run the parser on a received chunk of data (data,len) use the following command:

bootloader_parseBuffer((BootloaderParserContext_t *)parserContext,&parserCallbacks,data,len);

Finally, define the callback function, as follows:

void metadataCallback(uint32_t address, uint8_t *data, size_t length, void *context)
{
       //process the received chunk of metadata (data,length)
}

Reading Metadata from a Stored GBL File

A much easier solution, compared to on-the-fly parsing, is to retrieve the metadata from an already stored GBL file. To do so, first upload the GBL file without decoding it into a storage slot, defined by the bootloader. To retrieve the metadata from a GBL file stored in a storage slot, call

bootloader_verifyImage(slotID,metadataCallback);

and define the callback function, as follows:

void metadataCallback(uint32_t address, uint8_t *data, size_t length, void *context)
{
       //process the received chunk of metadata (data,length)
}

It’s important to note, that although the whole GBL file is available in the storage slot, you will still get the metadata in chunks because the parser has a limited buffer. The maximum size of a chunk is 64 bytes.

Implementing the Callback Function

The metadata callback function is called several times and provides metadata in chunks. The callback function receives 4 parameters, as follows:

To assembly the metadata from the chunks, use the following code snippet:

#define MAX_METADATA_LENGTH   512
uint8_t metadata[MAX_METADATA_LENGTH];

void metadataCallback(uint32_t address, uint8_t *data, size_t length, void *context)
{
    uint8_t i;

    for (i = 0; i < MIN(length , MAX_METADATA_LENGTH - address); i++)
    {
        metadata[address + i] = data[i];
    }
}

Example

This guide has a related code example here: Adding metadata to GBL files.