Skip to main content
Visitor
October 6, 2026
Question

Basic Bootloader/App error: SysTick stops

  • October 6, 2026
  • 2 replies
  • 16 views

Hi forum,

I’m tasked to implement firmware update ability for an STM32-based application. Basically, I’m using this tutorial and change it to work on a NUCLEO G431RB board. In the end, we’ll have a bootloader and two application slots in the STM’s flash.

The situation now is this: Bootloader starts up, waits for a moment, checks for a condition (button pressed or not) and then transfers control to either application 0 or application 1. Both applications don’t do anything useful yet, they just differ in how they blink the one LED I’m able to manipulate easily.

Startup works, transfer works but application 1 doesn’t blink at all. Reason is that its HAL_GetTick() value doesn’t change. In bootloader, it does. In application 0, it does also. And if I flash application 1 onto flash address 0x08000000 all alone without the other two, it works.

And it also works if I change the marked line to initialize variable to zero.

#define NumberOfFlashes 3
static int _millisecondsUntilToggle = 5; // marked line
void LedMain_HandleMillisecondElapsed(void)
{
if(0 >= --_millisecondsUntilToggle)
{
static int flashesToGo = NumberOfFlashes;
if(HAL_GPIO_ReadPin(HWDO_Led2_GPIO_Port, HWDO_Led2_Pin))
{
// LED is currently ON; it is now time to turn it OFF
if(0 >= --flashesToGo)
{
_millisecondsUntilToggle = 980;
flashesToGo = NumberOfFlashes;
}
else
{
_millisecondsUntilToggle = 280;
}
}
else
{
// LED is currently OFF; it is now time to turn it ON
_millisecondsUntilToggle = 20;
}
HAL_GPIO_TogglePin(HWDO_Led2_GPIO_Port, HWDO_Led2_Pin);
}
}

/* USER CODE END 0 */

/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{

/* USER CODE BEGIN 1 */

/* USER CODE END 1 */

/* MCU Configuration--------------------------------------------------------*/

/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();

/* USER CODE BEGIN Init */
SCB->VTOR = Application0StartAddress;
__enable_irq();
/* USER CODE END Init */

/* Configure the system clock */
SystemClock_Config();

/* USER CODE BEGIN SysInit */

/* USER CODE END SysInit */

/* Initialize all configured peripherals */
MX_GPIO_Init();
/* USER CODE BEGIN 2 */
// _millisecondsUntilToggle = 20;
/* USER CODE END 2 */

/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
// Time-based UI tasks require a call every millisecond.
static int lastTick = 0;
int newTick = HAL_GetTick();
while(lastTick != newTick)
{
++lastTick;

LedMain_HandleMillisecondElapsed();
}

/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}

That’s a behaviour I don’t understand. Why should the initialization value have anything to do with a working or non-working HAL_GetTick()?

 

I’m new to this forum. What info should I provide? Should I upload the three projects here?

2 replies

mƎALLEm
ST Technical Moderator
October 6, 2026

Hello ​@lukeer and welcome to the ST community,

That solution is provided by “controllerstech” so you need to contact the author under his article:

Meanwhile, you can use the Open bootloader provided by ST over the github link: https://github.com/STMicroelectronics/stm32-mw-openbl/tree/main

With a useful introductory video series, in six parts, explaining how to use Open Bootloader step by step:

  • Part 1: Introduction
  • Part 2: Using a NUCLEO-G474RE
  • Part 3: Loading an application
  • Part 4: Adding support for the I2C interface
  • Part 5: STLINK-V3SET I2C setup
  • Part 6: Loading an application over I2C

Hope that helps.

To give better visibility on the answered topics, please click "Best answer" on the reply which solved your issue or answered your question.
TDK
October 6, 2026

Startup works, transfer works but application 1 doesn’t blink at all.

 

Application0StartAddress

Presumably, application 1 should be using Application1StartAddress.

"If you feel a post has answered your question, please click ""Accept as Solution""."