USB DFU bootloader : start from source.
Hello,
I am trying to restart a STM32L072 into DFU bootloader mode (using STM32 LoRa Discovery kit) .
The bootloader is working and I can use it to flash my firmware using a jumper between BOOT0 and VCC.
Now I would like to enter bootloader from source. I used instruction from https://www.youtube.com/watch?v=cvKC-4tCRgw, https://stm32f4-discovery.net/2017/04/tutorial-jump-system-memory-software-stm32/ and various other sources.
I am running FreeRTOS, and I don't know any proper way to shut it down, so what I do is writing a byte into backup register, then trigger a reset. On startup, right after HAL_Init() and before SystemClock_Config(), I check this byte. If set to 'R', I do the following :
- RCC / systick reset
- Disabling IRQ
- Reset system flash memory
- Reset Vector table
- Set stack pointer to the adress in 0x1FF00000 (start of SystemMemory, according to AN2606)
- Jump to 0x1FF00004
int main(void)
{
HAL_Init();
bootloader_trigger_if_requested();
// Main continue to init MCU and start FreeRTOS, not relevant here.
}
void bootloader_trigger_if_requested(void){
RTC_HandleTypeDef RtcHandle;
RtcHandle.Instance = RTC;
if(HAL_RTCEx_BKUPRead(&RtcHandle, BOOTLOADER_REQUEST_BACKUP_REGISTER) == 'R'){
HAL_PWR_EnableBkUpAccess();
HAL_RTCEx_BKUPWrite(&RtcHandle, BOOTLOADER_REQUEST_BACKUP_REGISTER, 0);
HAL_PWR_DisableBkUpAccess();
bootloader_init();
}
}
/*!
* @brief Calling this will trigger the bootloader. Should be called only after a reset, to ensure no peripheral/IT/task/... will interfere.
*
*/
static void bootloader_init(void){
jump_to_bootloader = (void (*)(void)) (*((uint32_t *)(0x1FF00004)));
HAL_RCC_DeInit();
//Reset systick
SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;
/**
* Step: Disable all interrupts
*/
__disable_irq();
/* ARM Cortex-M Programming Guide to Memory Barrier Instructions.*/
__DSB();
__HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH();
SCB->VTOR=0; //Reset vector table
//Set Main Stack Pointer to it's default value
__set_MSP(*(__IO uint32_t*) 0x1FF00000);
jump_to_bootloader();
}Bootloader does not start, and my program reset. If I did not reset backup register, bootloader_init() run multiple times, if I do reset backup register, my application work as usual.
What did I miss ?
