2026-05-28 1:01 AM - last edited on 2026-06-02 1:59 AM by mƎALLEm
I have a STM32F427 bootloader code, the jump from bootloader to application is working before enabled IWDG. The IWDG configuration is as followings: -
hiwdg.Instance = IWDG;
hiwdg.Init.Prescaler = IWDG_PRESCALER_256;
hiwdg.Init.Reload = 1000; // 8S, 1000*8ms=8000ms=8S
After enable the IWDG, the jump from bootloader to application is failed, and it keep reseting every 8 seconds. There is Watchdog refresh code before and after time consuming functions and the main while loop: -
while (1)
{
...
if (bl_uart_status==BL_NACK)
{
#ifdef ENABLE_WATCHDOG
HAL_IWDG_Refresh(&hiwdg);
#endif
bl_retry_cnt++;
LED0=0;
}else {
#ifdef ENABLE_WATCHDOG
HAL_IWDG_Refresh(&hiwdg);
#endif
...
The bootloader is running with the following clock setting: -
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
Do you have any idea why the watchdog timeout happens even HAL_IWDG_Refresh(&hiwdg) is added?
FYI, I have also added the watchdog refresh at bootloader before jumping and at the application's SystemInit().
Thank you.
Melfice
2026-05-28 1:32 AM - edited 2026-05-28 1:34 AM
@melfice wrote:There is Watchdog refresh code before and after time consuming functions
And you're certain that these "time consuming functions" complete within the WD timeout period?
PS:
@melfice wrote:After enable the IWDG, the jump from bootloader to application is failed, and it keep reseting every 8 seconds.
How do you know that it's the jump from bootloader which fails ?
Does the main application run correctly without the bootloader?
2026-05-28 1:35 AM - edited 2026-05-28 1:40 AM
Yes, its timeout value is 1.5 Seconds. And if performing flash section erase, it is about Max 4 seconds.
There is LED blinking in bootloader, the first reset at the 3rd time and then it reset at the 2nd time. The jump happens after the 3rd time. Observing the second time reset, it is in bootloader.
2026-05-28 5:36 AM
If the watchdog is resetting the chip, the watchdog is not being refreshed in time. Recheck your assumptions here. Enabling the watchdog will not affect how the jump performs.
If the jump isn't working, it would be useful to show the code you are using to jump.
2026-05-28 7:41 PM
Do you have this line also in the app code?
hiwdg.Instance = IWDG;
2026-05-28 7:42 PM
Yes
2026-05-28 8:14 PM
Set a breakpoint near HAL_IWDG_Refresh() in your app and step in (better in disassembly mode). Will you see the function correctly fetches the IWDG instance address (&hiwdg)->Instance ?
#define __HAL_IWDG_RELOAD_COUNTER(__HANDLE__) WRITE_REG((__HANDLE__)->Instance->KR, IWDG_KEY_RELOAD)
......
HAL_StatusTypeDef HAL_IWDG_Refresh(IWDG_HandleTypeDef *hiwdg)
{
__HAL_IWDG_RELOAD_COUNTER(hiwdg);
return HAL_OK;
}
2026-05-28 9:38 PM
This is the working Jump code without IWDG: -
if(0xFFFFFFFF != *((volatile uint32_t *)FLASH_SECTOR2_BASE_ADDRESS))
{
/* Value of the main stack pointer of our main application */
uint32_t MSP_Value = *((volatile uint32_t *)FLASH_SECTOR2_BASE_ADDRESS);
/* Reset Handler definition function of our main application */
uint32_t MainAppAddr = *((volatile uint32_t *)(FLASH_SECTOR2_BASE_ADDRESS + 4));
/* Fetch the reset handler address of the user application */
pMainApp ResetHandler_Address = (pMainApp)MainAppAddr;
/* Set Main Stack Pointer */
__set_MSP(MSP_Value);
// 關閉 SysTick
SysTick->CTRL = 0;
SysTick->VAL = 0;
SysTick->LOAD = 0;
// 使用 HAL 庫重置硬體外設
HAL_RCC_DeInit();
HAL_DeInit();
// 清理 NVIC 的安全寫法 (僅針對 F4 實際存在的暫存器範圍)
// F427 的中斷數量約 90 個,其實只需要清理 ICER[0..2] 即可
NVIC->ICER[0] = 0xFFFFFFFF;
NVIC->ICER[1] = 0xFFFFFFFF;
NVIC->ICER[2] = 0xFFFFFFFF;
NVIC->ICPR[0] = 0xFFFFFFFF;
NVIC->ICPR[1] = 0xFFFFFFFF;
NVIC->ICPR[2] = 0xFFFFFFFF;
/* Jump to Application Reset Handler */
ResetHandler_Address();
}
2026-05-29 5:31 PM - edited 2026-05-29 5:33 PM
OK. then you set a breakpoint in your app, at the first call to HAL_IWDG_Refresh(&hiwdg) - this should be somewhere in main(), after IWDG_Init - and what do you see in the hiwdg struct?
(Note: debugger should suspend IWDG while it stops, so the MCU should not reset. Else check the debugger config.)
2026-05-31 9:02 PM
Hi, Pavel,
I have done a test with bootloader watchdog setting as 8S, and modified it in application's system_stm32f4xx.c's SystemInit() to be 32S. And the code reset at more than 30S. That means the bootloader can jump to application, but the code reset in the application after the watchdog timeout or hardfault. But I individually debug the application, it can run normally. The bootloader and application are two Keils projects, how can I debug them as from bootloader to application?
Thank you.
Melfice
We’re moving the ST Community to a new platform to give you a better and more reliable community experience.