STM32 USB IAP Practice
IAP (In Application Programming) refers to the process of programming a portion of the User Flash during the runtime of a program. The purpose is to facilitate the update and upgrade of firmware programs in the product through a reserved communication port after the product has been released.
Here we will open two project packages, one for DFU and the other for the APP, which will be written according to our needs. The process is shown in the figure, and for convenience, we will always start with the DFU for development.
USB DFU Implementation considerations
As two separate programs are being burned, the flash memory is divided into two partitions. Therefore, it is important to pay attention to the proportion of flash memory used by the DFU program and the location where it jumps to the APP.
In the figure below, the first step is to confirm the proportion of flash memory used by the DFU program. Generally, some space is reserved to prevent overwriting of the APP flash memory.
It is important to note that the reserved space should be in increments of a single page. In this example generated by STM32CubeMX, 64kb is allocated for the DFU, hence the APP will be burned starting from 0x8010000. For more details, please refer to the reference manual for the respective series (this example is based on the STM32G0 series)
Notes on APP burning
When using STM32cubePrg to burn the APP, pay attention to the Start address to avoid overwriting the DFU program area, and make sure that the DFU jump position is the starting position of the APP.
Similarly, the ld file needs to be revised, but the starting position of the ld file needs to be revised.
The last step is to revise the Offset of the interrupt vector table. This needs to be changed according to individual needs.
Reference mechanism for jumping between programs
Here we provide an official example that uses a button for program switching. Alternatively, you can also use a specific flash position value to determine whether to execute DFU or jump directly to the APP program. Here, the starting address of the APP program is taken as 0x08010000 for illustration.
if (BSP_PB_GetState(BUTTON_USER) != GPIO_PIN_RESET)
/* Test if user code is programmed starting from address 0x08010000 */
if (((*(__IO uint32_t *) USBD_DFU_APP_DEFAULT_ADD) & 0xFFFF0000) ==
/* Jump to user application */
JumpAddress = *(__IO uint32_t *) (USBD_DFU_APP_DEFAULT_ADD + 4);
JumpToApplication = (pFunction) JumpAddress;
/* Initialize user application's Stack Pointer */
__set_MSP(*(__IO uint32_t *) USBD_DFU_APP_DEFAULT_ADD);