Skip to main content
GPerk.1
Associate II
April 26, 2021
Question

Bootloader (STM32L496RG) application stuck at first HAL_Delay

  • April 26, 2021
  • 3 replies
  • 1554 views

I create 2 simple applications on Nucleo-L476RG.

Both application have default settings from STM32CUBEIDE.

1 - bootloader - just jump to 0x08010000

2 - Application - led flashings with HAL_Delay function

Bootloader jumps into application, pplication starts - then stuck into HAL_Delay.

See the modification to both app:

'Bootloader':

/* USER CODE BEGIN 0 */

typedef void (*pFunction)(void); /*!< Function pointer definition */

#define APP_ADDRESS (uint32_t)0x08010000

void jump2APP(){

uint32_t JumpAddress = *(__IO uint32_t*)(APP_ADDRESS + 4);

pFunction Jump  = (pFunction)JumpAddress;

HAL_RCC_DeInit();

HAL_DeInit();

__disable_irq();

SysTick->CTRL = 0;

SysTick->LOAD = 0;

 SysTick->VAL = 0;

SCB->VTOR = APP_ADDRESS;

__set_MSP(*(__IO uint32_t*)APP_ADDRESS);

Jump();

}

/* USER CODE END 0 */

[....]

 uint8_t i=20;

 HAL_GPIO_TogglePin(LD2_GPIO_Port,LD2_Pin);

 while (1)

 {

 /* USER CODE END WHILE */

 /* USER CODE BEGIN 3 */

  HAL_GPIO_TogglePin(LD2_GPIO_Port,LD2_Pin);

HAL_Delay(i*30+1);

if(!i--)

jump2APP();

 }

Application:

* USER CODE BEGIN WHILE */

volatile uint32_t cnt=0;

while(cnt++<500000);

cnt=0;

HAL_GPIO_TogglePin(LD2_GPIO_Port,LD2_Pin);

while(cnt++<5000000);

cnt=0;

HAL_GPIO_TogglePin(LD2_GPIO_Port,LD2_Pin);

while(cnt++<5000000);

cnt=0;

HAL_GPIO_TogglePin(LD2_GPIO_Port,LD2_Pin);

while(cnt++<5000000);

cnt=0;

HAL_GPIO_TogglePin(LD2_GPIO_Port,LD2_Pin);

while(cnt++<5000000);

 while (1)

 {

 /* USER CODE END WHILE */

 /* USER CODE BEGIN 3 */

  HAL_GPIO_TogglePin(LD2_GPIO_Port,LD2_Pin);

  HAL_Delay(100);

 }

 /* USER CODE END 3 */

And in the linker file:

MEMORY

{

 RAM  (xrw)  : ORIGIN = 0x20000000,  LENGTH = 96K

 RAM2  (xrw)  : ORIGIN = 0x10000000,  LENGTH = 32K

 FLASH  (rx)  : ORIGIN = 0x8010000,  LENGTH = 1024K

}

This topic has been closed for replies.

3 replies

Vangelis Fortounas
Associate II
April 26, 2021

Hello

>>then stuck into HAL_Delay

HAL_Delay uses SysTick but SysTick was disabled before.

DavidAlfa
Senior II
April 26, 2021

After __disable_irq(); SysTick will be dead.

You need to enable irq again before the​ delay.

And it will not count the time​ it was disabled, as SysTick was not updated.

GPerk.1
GPerk.1Author
Associate II
April 27, 2021

Thanks,

I added __enble_irq() in the app at the beginning.

But it is only part of the problem.

I had to add:

SCB->VTOR = APP_ADDRESS;

to the application and all works.

I found nowhere this description, maybe due it works without that in simple cases.

Tesla DeLorean
Guru
April 27, 2021

>>I found nowhere this description, maybe due it works without that in simple cases.

Usually done in SystemInit() code, but the way ST implements it's apt to be wrong unless defines are updated. More robust way is to use linker symbols.

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
GPerk.1
GPerk.1Author
Associate II
April 27, 2021

@Community member​ 

I was looking in system_stm32l4xx.c at SystemInit() and VTOR is not updated there at all(unless some defines are changed)

So it looks like it is changed somewhere after jump from bootloader.

Is there anything wrong in my solution? (except is not elegant)

Can you provide an example of this linker solution?

thanks