TIDUEY4E August 2022 – November 2025
Absence of A/B swapping: Since A/B swapping is not supported, the user needs to build firmware for a specific Flash bank. For example, FW_version0 would be targeted to Bank0, FW_version1 to Bank1, FW_version2 to Bank0, FW_version3 to Bank1, and so on.
Ping-pong approach to code in RAM: Any old firmware running from RAM could be running during the LFU process and therefore has to be maintained and untouched by the new firmware. The init_lfu() function which copies code from Flash to RAM of code in the new firmware that needs to run from RAM, should not corrupt the RAM space the old firmware was using. In this sense, a ping-pong like scheme would need to be designed by the user, with a portion of the RAM memory allocated for the LFU image.
Interupt configuration: Interrupt mapping of existing interrupts to the shadow PIE vector table is done in init_lfu() using Shadow_Interrupt_register(). The same process can be followed for any new interrupts that need to be set up. However, they should be enabled (using Interrupt_enable()) only during the LFU switchover. Similarly, any interrupts in the old firmware that are removed will need to be disabled (using Interrupt_disable()) only during the LFU switchover.
Stack initialization: this is done in the LFU switchover in this example so that the SP is reset just prior to executing ISRs of the new firmware. However, main() of the new firmware has already begun executing. If there are local variables in main(), then resetting SP during the LFU switchover can cause a problem. Those local variable values can potentially be lost. An alternate option is to reset SP in the LFU entry point function c_int_lfu(). This entry point is branched to directly, and while inside this function, no ISRs are running, therefore it is safest to reset SP here.
Variables (symbol) management: Update variables are placed in the .TI.update section, whereas preserved variables are placed in the .TI.bound section. But an update variable in one firmware version would become a preserved variable in a later firmware version. It would therefore move from the .TI.update section to the .TI.bound section, while remaining at the same address. This is possible since .TI.bound sections are not required to be contiguous.
Management of static libraries: this example illustrates LFU management of global or static variables in the user's application. It is important to note that if the application links any static libraries which contain global or static variables, LFU management needs to consider those static libraries as well. Library source files need to specify attributes on global or static variables, and the library needs to be compiled by specifying a reference firmware image (just like the firmware it is linked in does). If this is not done, globals within the linked libraries may move location between firmware versions, where the user may incorrectly assume they are preserved.
#pragma DATA_SECTION: this pragma is used to put data in specific sections other than .bss. Another common use case is for peripheral memory mapped registers that have specific locations, and are marked NOINIT so as to avoid erroneous zero initialization on startup. The compiler does not perform LFU initialization of sections defined as DATA_SECTIONS.
Fapi_setActiveFlashBank(): application code does not need to execute Fapi_setActiveFlashBank(). This is managed in the Flash bootloader. Additionally, it is important to disable Flash prefetch before executing this function. Flash prefetch can be enabled after. Otherwise, it can cause an ITRAP. Details are present in the F28003x device errata.
Robustness: in the current example, Flash programming failures or communication issues are not handled as they should be. The user's LFU code should handle these. If a Flash Program/Verify occur occurs, no specific action is taken. In ldfuCopyData(), the section where the START field is programmed checks for a Flash FSM error and calls fmstatfail(). However, in the loop that programs the entire image, this check is not present. Instead a variable 'fail' is incremented.
DCSM Security: On F28003x, after LFU, reading DCSM space locks the device for that zone (no need of reset after DCSM configuration to lock the device).
Object output type: the compiler supports LFU only when the object output type for the application firmware is EABI.