Table of Contents
Events Module
When performing firmware updates using a PC tool such as MicroBoot or BootCommander, you can see the firmware update progress on the PC tool's user interface. In contrast, if you perform firmware updates from a locally attached file system, e.g. an SD-Card or a USB flash drive, it's a bit of a black box. A blinking LED might indicate that the bootloader is running and doing something, but that's about all you can see. Wouldn't it be great the OpenBLT bootloader offers a feature that allows you to detect and respond to all firmware update related events? That's exactly what the events module is for.
The events module emits event signals during a firmware update. For example when memory is being erase and programmed, when the firmware update completes, or in case an error occurred. Each time the events module emits such a signal, it calls the EventsHook() function and passes on the event identifier and event related information. You can implement this hook-function yourself any way you see fit. Some ideas: You can implement the EventsHook() function to update a user interface, log to a file, or output information on a debug terminal.
Note that the Master/Slave Gateway add-on module also fully supports emitting events. Meaning that the master system can track the firmware update progress of a firmware update that is ongoing on a slave system.
How to use the events module
Using the events module in your OpenBLT based bootloader is in essence nothing more than enabling it with the help of a configuration macro in your “blt_conf.h” configuration header-file. Next, you implement the EventsHook() function. For example in the “hooks.c” source-file.
Enable the events module
To enable the events module, add the BOOT_EVENTS_ENABLE configuration macro with a value of 1 to your “blt_conf.h” configuration header-file:
/** \brief Enable/disable the events module. */ #define BOOT_EVENTS_ENABLE (1)
If this macro was already present, then all you need to do is set it to a value of 1.
Implement the events module hook-function
As a next step, you implement the EventsHook() function, for example in “hooks.c”. You can use this template as a starting point:
#if (BOOT_EVENTS_ENABLE > 0) /***********************************************************************************//** ** \brief Callback that gets called when a firmware update related event gets ** triggered. Implement your event handling here. For example for updating ** a user interface or for logging purposes. ** Cast the opaque info pointer to the correct structure type (tEventsInfoXxx) ** to access additional event related information. ** \param id The identifier of the event that occurred. ** \param info Opaque pointer to event identifier related information. Can be ** BLT_NULL depending on the event identifer. For example when no additional ** information available for the event. ** \return none ** ****************************************************************************************/ void EventsHook(tEventsId id, void const *info) { blt_addr base_addr; blt_int32u num_bytes; blt_int8u progress; blt_char const * filename; blt_int8u node_id; tEventsErrorId error_id; static blt_bool update_from_file = BLT_FALSE; /* Filter on the events identifier. */ switch (id) { /* Event EVENT_ID_ON_ENTRY triggers once after a power-on or reset event, when the * bootloader finished its initialization. */ case EVENT_ID_ON_ENTRY: break; /* Event EVENT_ID_ON_START triggers at the start of a firmware update. Info * parameters: * filename: The filename for the firmware updates. Only applicable for firmware * updates from a locally attached FAT filesystem (e.g. SD-card). For * firmware updates via a communication interface (e.g. RS232, CAN, etc.) * the parameter value is BLT_NULL. * node_id: 8-bit node identifier of the node targeted for the firmware update. */ case EVENT_ID_ON_START: update_from_file = BLT_FALSE; filename = ((tEventsInfoStart const *)info)->filename; node_id = ((tEventsInfoStart const *)info)->node_id; if (filename != BLT_NULL) { update_from_file = BLT_TRUE; } break; /* Event EVENT_ID_ON_ERASE triggers each time when a part of non-volatile memory is * about to be erased. Info parameters: * base_addr: The start memory address of the erase operation. * num_bytes: The number of bytes that are to be erased, starting at base_addr. */ case EVENT_ID_ON_ERASE: base_addr = ((tEventsInfoErase const *)info)->base_addr; num_bytes = ((tEventsInfoErase const *)info)->num_bytes; break; /* Event EVENT_ID_ON_WRITE triggers each time when a part of non-volatile memory is * about to be programmed. Info parameters: * base_addr: The start memory address of the program operation. * num_bytes: The number of bytes that are to be programmed, starting at base_addr. * progress: Overall firmware update progress as a percentage (0..100). */ case EVENT_ID_ON_WRITE: base_addr = ((tEventsInfoWrite const *)info)->base_addr; num_bytes = ((tEventsInfoWrite const *)info)->num_bytes; progress = ((tEventsInfoWrite const *)info)->progress; break; /* Event EVENT_ID_ON_SUCCESS triggers after the firmware update successfully * completed. */ case EVENT_ID_ON_SUCCESS: break; /* Event EVENT_ID_ON_ERROR triggers upon detection of an error during the firmware * update. Info parameter: * error_id: The error identifier. Refer to tEventsErrorId for a list of available * error identifiers (EVENT_ERROR_ID_xxx) and their meaning. */ case EVENT_ID_ON_ERROR: error_id = ((tEventsInfoError const *)info)->error_id; break; /* Event EVENT_ID_ON_SUPPRESS triggers when the bootloader intended to start the * user program, yet decided against it. This can for example happen when the * checksum verification failed or the logic in CpuUserProgramStartHook() requested * the bootloader to stay active. */ case EVENT_ID_ON_SUPPRESS: break; /* Event EVENT_ID_ON_EXIT triggers when the bootloader is about to hand over control * to the user program by starting it. */ case EVENT_ID_ON_EXIT: break; default: break; } } /*** end of EventsHook ***/ #endif /* BOOT_EVENTS_ENABLE > 0 */
Examples that showcase the use of the events module
Some of the OpenBLT demo programs come with the events module enabled and preconfigured. You can use these as a further reference on how to implement the EventsHook() function. A small selection:
- The STM32F723 Discovery Kit CubeIDE demo bootloader uses the event module to show firmware update progress on the TFT LCD.
- The Infineon XMC4700 Relax Kit CMake demo bootloader uses the event module to log all events through SEGGER's Real-Time Transfer.
- The Olimexino-STM32F3 CubeIDE demo bootloader uses the event module to create a log-file on the SD-card when performing firmware updates from the SD-card.
Known Limitations
The events module feature is available starting with OpenBLT stable release 1.22. If you read this before the release of version 1.22, it is already present in the development trunk. Refer to the download page for details on where to download stable releases and how to access the development trunk.