2023-08-27 07:51 PM
Hi,
I have scoured the web for a solution to this problem, but I cannot find one, typically the replies are the same, but the solution is never found. I have tried every other solution you will find.
I was playing around with the cube mx trying to solve my problem with this, and I'm not sure what changed, but the cube mx generated a program which actually made HAL_Delay work correctly.
I have used the STM32CubeIDE with CubeMX generated code for many projects in the past with relatively no issues.
To summarise the problem, the application will freeze at HAL_Delay();
The reason for this is because within the file stm32f1xx_t.c , the SysTick_Handler will not be called, and hence HAL_IncTick(); will also never increment the uwTick counter. Clearly the Systick Interrupt isn't being triggered.
void SysTick_Handler(void)
{
/* USER CODE BEGIN SysTick_IRQn 0 */
/* USER CODE END SysTick_IRQn 0 */
HAL_IncTick();
/* USER CODE BEGIN SysTick_IRQn 1 */
/* USER CODE END SysTick_IRQn 1 */
}
The following call stack will be shown when you try and Step-Over HAL_Delay(); while debugging.
Thread #1 [main] 1 [core: 0] (Suspended : Signal : SIGTRAP:Trace/breakpoint trap)
uwTickPrio() at 0x20000004
<signal handler called>() at 0xfffffff9
HAL_GetTick() at stm32f1xx_hal.c:307 0x8000806
HAL_Delay() at stm32f1xx_hal.c:382 0x800083c
main() at main.c:98 0x8000546
I have found that for whatever reason the file system_stm32f1xx.c (located in Core/Src is related. In my working.rar which I have attached you will find that the system_stm32f1xx.c file is different to the not working.rar
If I copy the system_stm32f1xx.c file from the working project into the not working project, it will compile and debug correctly. There is major differences between the files but I do not understand them.
Perhaps someone with more experience with the inners of how the ST generation behaves can shed some light on why this would happen.
Solved! Go to Solution.
2023-08-27 08:16 PM - edited 2023-08-27 08:20 PM
The issue is likely related to the vector table address. Here's what happens in the "working" scenario:
#ifdef VECT_TAB_SRAM
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
#else
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
#endif
Here's what happens in the "not working" scenario:
#if defined(USER_VECT_TAB_ADDRESS)
SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
#endif /* USER_VECT_TAB_ADDRESS */
But this is never executed since USER_VECT_TAB_ADDRESS isn't defined.
This was a decision made by ST. There have been at least a couple threads on it, and someone from ST said it was deliberate. I and others here said it was a mistake and would cause users hard to find problems. Will link the thread if I can find it.
And in case it isn't clear, here's what you need to add in your system startup file:
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET;
or uncomment the line that defines USER_VECT_TAB_ADDRESS.
So SysTick is happening, it's just not at a useful address.
There's a chance I'm wrong here as well. There's also a bug in GCC where "weak" definitions aren't properly overridden by strong definitions. Not sure if it's fixed in the latest compiler CubeIDE is using.
2023-08-27 08:16 PM - edited 2023-08-27 08:20 PM
The issue is likely related to the vector table address. Here's what happens in the "working" scenario:
#ifdef VECT_TAB_SRAM
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
#else
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
#endif
Here's what happens in the "not working" scenario:
#if defined(USER_VECT_TAB_ADDRESS)
SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
#endif /* USER_VECT_TAB_ADDRESS */
But this is never executed since USER_VECT_TAB_ADDRESS isn't defined.
This was a decision made by ST. There have been at least a couple threads on it, and someone from ST said it was deliberate. I and others here said it was a mistake and would cause users hard to find problems. Will link the thread if I can find it.
And in case it isn't clear, here's what you need to add in your system startup file:
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET;
or uncomment the line that defines USER_VECT_TAB_ADDRESS.
So SysTick is happening, it's just not at a useful address.
There's a chance I'm wrong here as well. There's also a bug in GCC where "weak" definitions aren't properly overridden by strong definitions. Not sure if it's fixed in the latest compiler CubeIDE is using.
2023-08-27 08:19 PM
Here's one thread about it, there are others:
2023-08-27 08:45 PM
Hello, thank you very much for your reply and helpful insight,
I uncommented the #define USER_VECT_TAB_ADDRESS line as you say, and the project now works with no problems.
Definitely a strange choice by ST, especially as I had generated this project without any complexity...
So clearly in the working project I must have generated it under a different version where this wasn't a thing yet?
Hopefully this post can at least help some lost souls in finding a solution. I uncommented this line within system_stm32f1xx.c
/* Note: Following vector table addresses must be defined in line with linker
configuration. */
/*!< Uncomment the following line if you need to relocate the vector table
anywhere in Flash or Sram, else the vector table is kept at the automatic
remap of boot address selected */
#define USER_VECT_TAB_ADDRESS
2024-01-06 08:01 PM
Hello I hope someone at ST is reading this issue -- it took me quite a while to figure this out today. Only hope was finding this thread. I love STM32s but this kind of experience will drive people away as it kills out-of-the-box "hello world" type demos.
2024-01-06 08:43 PM
It is truly bizarre that a tool like CubeMX which is designed to create simple programs with a few clicks does all pin initialization, clock initialization, peripheral calls, linker script, etc and yet when it comes to the vector table they say "oh no, the user definitely knows what's best there, let's just not change it".
And it was a decision made partway through the CubeMX project with little announcement to those using the tool.
2024-05-27 02:17 AM
Hello, I tried both possibilities, relocate vector table on "SRAM" or "FLASH" but in both ways, behave same. Do you know any third option or possible another workaround? I am using the STM32G4 series MCU.
2024-06-12 08:16 AM
Uncomment that not worked to me, instead of using this:
#define DELAY_US(us) \
do { \
uint32_t start = SysTick->VAL; \
uint32_t ticks = (us * SYSTICK_LOAD)-SYSTICK_DELAY_CALIB; \
while((start - SysTick->VAL) < ticks); \
} while (0)
I used this delay_us1(). I calculated for a 480Mhz micro:
void delay_us1(uint16_t us) //depende de optimizaciones
{
for (uint16_t i=0;i<us;i++)
{
__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
}
}