API reference
This section provides a full reference of all the functions, macros and types that LibMicroBLT offers.
Macros
Macro | Description |
---|---|
BLT_VERSION_MAIN |
Main version number of LibMicroBLT. |
BLT_VERSION_MINOR |
Minor version number of LibMicroBLT. |
BLT_VERSION_PATCH |
Patch number of LibMicroBLT. |
BLT_SESSION_XCP_V10 |
Session type identifier for XCP version 1.0. |
BLT_FIRMWARE_READER_SRECORD |
Firmware type identifier for S-record firmware files. |
Types
tBltSessionSettingsXcpV10
typedef struct tBltSessionSettingsXcpV10
Structure layout of the XCP version 1.0 session settings.
Element | Description |
---|---|
timeoutT1 |
Command response timeout in milliseconds. |
timeoutT3 |
Start programming timeout in milliseconds. |
timeoutT4 |
Erase memory timeout in milliseconds. |
timeoutT5 |
Program memory and reset timeout in milliseconds. |
timeoutT6 |
Connect response timeout in milliseconds. |
timeoutT7 |
Busy wait timer timeout in milliseonds. |
connectMode |
Connection mode parameter in XCP connect command. |
tPortXcpPacket
typedef struct tPortXcpPacket
XCP packet type.
Element | Description |
---|---|
data |
Byte array with packet data. |
len |
Number of data bytes stored in the packet. |
tPort
typedef struct tPort
Port interface. The port interface links the hardware specific implementation to the hardware independent library.
Element | Description |
---|---|
SystemGetTime |
Function pointer to obtain the current system time in milliseconds. |
XcpTransmitPacket |
Function pointer to transmit an XCP packet using the transport layer implemented by the port. The transmission itself can be blocking. The function should return TBX_OK if the packet could be transmitted,TBX_ERROR otherwise. |
XcpReceivePacket |
Function pointer to receive an XCP packet using the transport layer implemented by the port. The reception should be non-blocking. The function should return TBX_TRUE if a packet was received, TBX_FALSE otherwise. A newly received packet should be stored in the rxPacket parameter. |
XcpComputeKeyFromSeed |
Function pointer to calculates the key to unlock the programming resource, based on the given seed. This function should return TBX_OK if the key could be calculated, TBX_ERROR otherwise. Note that it's okayto set this element to NULL , if you do not use the seed/key securityfeature of the OpenBLT bootloader. |
Functions
Port module
The port module makes it possible to connect your hardware specifics to the hardware independent LibMicroBLT library. In your own application you implement the port specific functions. For example for transmitting and receiving XCP communication packet on the transport layer of your choice. You then specify your port specific functions in a variable of type tPort. You pass this variable on as a parameter when calling function BltPortInit(), which links your hardware specifics to LibMicroBLT. For this reason, you should first call function BltPortInit(), before calling any other functions of LibMicroBLT.
BltPortInit
void BltPortInit(tPort const * port)
Initializes the port module by linking the port specified by the parameter. Typically called once during firmware initialization. Must be called before calling any other functions of LibMicroBLT.
Parameter | Description |
---|---|
port |
Pointer to the port to link (type tPort). |
Example
This example is taken from the LibMicroBLT demo application, where the application implements the hardware specific functions in:
AppPortSystemGetTime()
AppPortXcpTransmitPacket()
AppPortXcpReceivePacket()
AppPortXcpComputeKeyFromSeed()
Refer to the LibMicroBLT demo application for an example on how to implement or port these functions for your own hardware. Once these port functions are implemented, you link them to LibMicroBLT like this:
tPort const portInterface =
{
.SystemGetTime = AppPortSystemGetTime,
.XcpTransmitPacket = AppPortXcpTransmitPacket,
.XcpReceivePacket = AppPortXcpReceivePacket,
.XcpComputeKeyFromSeed = AppPortXcpComputeKeyFromSeed
};
BltPortInit(&portInterface);
BltPortTerminate
void BltPortTerminate(void)
Terminates the port module. Typically called once during firmware exit. Embedded firmware tends to be driven by an infinite program loop and never exits. In such cases, you can omit calling this function.
Session module
The session module implements all the functionality for communicating with the OpenBLT bootloader running the other microcontroller(s); The ones on which you want to perform a firmware update from the microcontroller that runs this LibMicroBLT library. The functionality of the session module encompasses:
- Connect and disconnect.
- Erase, write and read memory.
BltSessionInit
void BltSessionInit(uint32_t type, void const * settings)
Initializes the firmware update session for a specific communication protocol. This function is typically called at the start of the firmware update.
Parameter | Description |
---|---|
type |
The communication protocol to use for this session. It should be a BLT_SESSION_xxx value. |
settings |
Pointer to a structure with communication protocol specific settings. |
Example
Initialize the session module for communication using the XCP version 1.0 protocol:
tBltSessionSettingsXcpV10 const sessionSettings =
{
.timeoutT1 = 1000U,
.timeoutT3 = 2000U,
.timeoutT4 = 10000U,
.timeoutT5 = 1000U,
.timeoutT6 = 50U,
.timeoutT7 = 2000U,
.connectMode = 0
};
BltSessionInit(BLT_SESSION_XCP_V10, &sessionSettings);
BltSessionTerminate
void BltSessionTerminate(void)
Terminates the firmware update session. This function is typically called at the end of the firmware update.
BltSessionStart
uint8_t BltSessionStart(void)
Starts the firmware update session. This is were the library attempts to activate and connect with the bootloader running on the target, through the transport layer that was specified during the session's initialization.
Return value |
---|
TBX_OK if successful, TBX_ERROR otherwise. |
Example
When attempting to connect to the OpenBLT bootloader on the target microcontroller, the bootloader itself is often not yet active. Instead, the user's firmware is happily running. The firmware typically includes functionality to receive the connection request, after which it activates the bootloader by performing a software reset. If this functionality is not present, the user needs to manually reset the microcontroller.
It's therefore recommended to try connecting to the OpenBLT bootloader, by calling BltSessionStart()
repeatedly for a finite amount of time. Note that the following example also demonstrates how your own application can access the port specific functions:
uint32_t const connectTimeout = 5000U;
uint32_t connectStartTime;
uint32_t connectDeltaTime;
uint8_t connected = TBX_FALSE;
/* Store start time. */
connectStartTime = PortGet()->SystemGetTime();
/* Attempt to connect to the target. */
connected = BltSessionStart();
/* Repeat connection attempt for a finite amount of time. */
while (connected == TBX_FALSE)
{
/* Attempt to connect to the target. */
connected = BltSessionStart();
/* Handle timeout detection if not yet connected. */
if (connected == TBX_FALSE)
{
/* Calculate elapsed time while waiting for the connection to establish. Note
* that this calculation is 32-bit time overflow safe.
*/
connectDeltaTime = PortGet()->SystemGetTime() - connectStartTime;
/* Did a timeout occur? */
if (connectDeltaTime > connectTimeout)
{
/* Could not connect to the target. Stop connection attempts. */
break;
}
}
}
BltSessionStop
void BltSessionStop(void)
Stops the firmware update session. This is there the library disconnects the transport layer as well. Note that if you are currently connected to the OpenBLT bootloader on the target microcontroller, this requests the bootloader to start the user's firmware again, if a valid one is detected by the bootloader.
BltSessionClearMemory
uint8_t BltSessionClearMemory(uint32_t address, uint32_t len)
Requests the target to erase the specified range of memory on the target. Note that the target automatically aligns this to the erasable memory block sizes. This typically results in more memory being erased than the range that was specified here. Refer to the target implementation for details.
Parameter | Description |
---|---|
address |
The starting memory address for the erase operation. |
len |
The total number of bytes to erase from memory. |
Return value |
---|
TBX_OK if successful, TBX_ERROR otherwise. |
Example
The flash memory on the ST STM32F0 microcontroller starts at address 0x08000000
and consists of 2k sectors. The following code erases the first two 2k sectors, because the OpenBLT bootloader automatically aligns to the sectors of the microcontroller's flash.
BltSessionClearMemory(0x08000010, 2048);
BltSessionWriteData
uint8_t BltSessionWriteData(uint32_t address, uint32_t len, uint8_t const * data)
Requests the target to program the specified data to memory. Note that it is the responsibility of the application to make sure the memory range was erased beforehand.
Parameter | Description |
---|---|
address |
The starting memory address for the write operation. |
len |
The number of bytes in the data buffer that should be written. |
data |
Pointer to the byte array with data to write. |
Return value |
---|
TBX_OK if successful, TBX_ERROR otherwise. |
Example
This code snippet writes 16 bytes to the start of flash on an ST STM32F0 microcontroller:
uint8_t writeData[16] =
{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
};
BltSessionWriteData(0x08000000, 16, writeData);
BltSessionReadData
uint8_t BltSessionReadData(uint32_t address, uint32_t len, uint8_t * data)
Requests the target to upload the specified range from memory and store its contents in the specified data buffer.
Parameter | Description |
---|---|
address |
The starting memory address for the read operation. |
len |
The number of bytes to upload from the target and store in the data buffer. |
data |
Pointer to the byte array where the uploaded data should be stored. |
Return value |
---|
TBX_OK if successful, TBX_ERROR otherwise. |
Example
This code snippet reads 16 bytes from the start of flash on an ST STM32F0 microcontroller:
uint8_t readData[16];
BltSessionReadData(0x08000000, 16, readData);
Firmware module
The firmware module embeds all the functionality for reading firmware data from a firmware file. It handles all the file parsing of for example the S-record firmware file format. The current implementation of LibMicroBLT assumes that file is present on a locally attached FAT32 file system, which the library accesses with the help of FatFs.
BltFirmwareInit
void BltFirmwareInit(uint8_t readerType)
Initializes the firmware reader module for a specified firmware file reader. Typically called once upon application initialization.
Parameter | Description |
---|---|
readerType |
The firmware file reader to use in this module. It should be a BLT_FIRMWARE_READER_xxx value. |
Example
Initialize the firmware module to parse and read firmware data from S-record firmware files:
BltFirmwareInit(BLT_FIRMWARE_READER_SRECORD);
BltFirmwareTerminate
void BltPortTerminate(void)
Terminates the firmware reader module. Typically called at the end of the application when the firmware reader module is no longer needed.
BltFirmwareFileOpen
uint8_t BltFirmwareFileOpen(char const * firmwareFile)
Opens the firmware file and browses through its contents to collect information about the firmware data segments it contains.
Parameter | Description |
---|---|
firmwareFile |
Firmware filename including its full path. |
Return value |
---|
TBX_OK if successful, TBX_ERROR otherwise. |
Example
Code snippet that opens the firmware file demoprog_stm32f091.srec
, stored in the firmwares
directory on the SD cards' first FAT32 partition:
uint8_t fileOpened = TBX_FALSE;
if (BltFirmwareFileOpen("/firmwares/demoprog_stm32f091.srec") == TBX_OK)
{
fileOpened = TBX_TRUE;
}
BltFirmwareFileClose
void BltFirmwareFileClose(void)
Closes the previously opened firmware file.
BltFirmwareGetTotalSize
uint32_t BltFirmwareGetTotalSize(void)
Obtains the total number of data bytes present in all segments of the firmware file. You could for example use this number to track the progress of a firmware update, taking into account how many bytes you already programmed with BltSessionWriteData()
.
Return value |
---|
Total number of firmware data bytes present in all segments of the firmware file. |
BltFirmwareSegmentGetCount
uint8_t BltFirmwareSegmentGetCount(void)
Obtains the total number of firmware data segments encountered in the firmware file. A firmware data segment consists of a consecutive block of firmware data. A firmware file always has at least one segment. However, it can have more as well. For example if there is a gap between the vector table and the other program data.
Return value |
---|
Total number of firmware data segments present in the firmware file. |
BltFirmwareSegmentGetInfo
uint32_t BltFirmwareSegmentGetInfo(uint8_t idx, uint32_t * address)
Obtains information about the specified segment, such as the base memory address that its data belongs to and the total number of data bytes in the segment.
Parameter | Description |
---|---|
idx |
Zero-based segment index. Valid values are between 0 and(BltFirmwareSegmentGetCount() - 1) . |
address |
The base memory address of the segment's data is written to this pointer. |
Return value |
---|
The total number of data bytes inside this segment. |
Example
Code snippet that loops through all the firmware segments, obtains each segments' info and erases the related sectors in flash memory, on the connected microcontroller. This is what you need to do, before you write the data of the new firmware to flash memory. Note that error checking was left out for clarity.
uint8_t segmentIdx;
uint32_t segmentBase = 0U;
uint32_t segmentLen;
/* Erase the memory segments on the target that the firmware data covers. */
for (segmentIdx = 0U; segmentIdx < BltFirmwareSegmentGetCount(); segmentIdx++)
{
/* Obtain segment information such as its base memory adddress and length. */
segmentLen = BltFirmwareSegmentGetInfo(segmentIdx, &segmentBase);
/* Erase the segment. */
BltSessionClearMemory(segmentBase, segmentLen);
}
BltFirmwareSegmentOpen
void BltFirmwareSegmentOpen(uint8_t idx)
Opens the firmware data segment for reading. This should always be called before calling the BltFirmwareSegmentGetNextData()
function.
Parameter | Description |
---|---|
idx |
Zero-based segment index. Valid values are between 0 and(BltFirmwareSegmentGetCount() - 1) . |
BltFirmwareSegmentGetNextData
uint8_t const * BltFirmwareSegmentGetNextData(uint32_t * address, uint16_t * len)
Obtains a data pointer to the next chunk of firmware data in the segment that was opened with function BltFirmwareSegmentOpen()
. The idea is that you first open the segment and afterwards you can keep calling this function to read out the segment's firmware data. When all data is read, len
will be set to zero and a non-NULL
pointer is returned.
Note that there are three possible outcomes when calling this function:
len
>0
and a non-NULL
pointer is returned. This means valid data was read.len
=0
and a non-NULL
pointer is returned. This means the end of the segment is reached and therefore no new data was actually read.- A
NULL
pointer is returned. This happens only when an error occurred.
Parameter | Description |
---|---|
address |
The starting memory address of this chunk of firmware data is written to this pointer. |
len |
The length of the firmware data chunk is written to this pointer. |
Return value |
---|
Data pointer to the read firmware if successful, NULL otherwise. |
Example
Code snippet that presents a function to write the firmware data from a specific segment of the firmware file, to the flash memory on the connected microcontroller. Note that error checking was left out for clarity.
void writeFirmwareSegmentToFlash(uint8_t segmentIdx)
{
uint8_t const * chunkData;
uint16_t chunkLen = 0U;
uint32_t chunkBase = 0U;
/* Open the segment for reading. */
BltFirmwareSegmentOpen(segmentIdx);
/* Attempt to read the first chunk of data in this segment. */
chunkData = BltFirmwareSegmentGetNextData(&chunkBase, &chunkLen);
/* Enter loop to write all data chunks to flash. */
while ( (chunkData != NULL) && (chunkLen > 0U) )
{
/* Program the newly read data chunk. */
BltSessionWriteData(chunkBase, chunkLen, chunkData)
/* Attempt to read the next chunk of data in this segment. */
chunkData = BltFirmwareSegmentGetNextData(&chunkBase, &chunkLen);
}
}