2022-07-08 06:49 AM
I have a project (for STM32L0) that use TIM6 to generate an Interrupt every 5ms and everything works perfectly both in release and debug when built wih no optimization.
Then I built the same project with -Os(optimize for Size) -ffunction-section -fdata-section and -WI, --gc-section (Discards the unused sections) and the project works no more.
The reason is that the application spends almost all the time in the Interrupt of TIM6.
(The programs enters TIM6 Interrupt, every 50us)
Here' s a scheme of the interrupt
void TIM6_DAC_IRQHandler(void)
{
/* USER CODE BEGIN TIM6_DAC_IRQn 0 */
/* USER CODE END TIM6_DAC_IRQn 0 */
HAL_TIM_IRQHandler(&htim6);
/* USER CODE BEGIN TIM6_DAC_IRQn 1 */
// dummy = dummy +1; // explained bellow
/* USER CODE END TIM6_DAC_IRQn 1 */
}
The following is part of the HAL:
void HAL_TIM_IRQHandler(TIM_HandleTypeDef *htim)
{
...
/* TIM Update event */
if (__HAL_TIM_GET_FLAG(htim, TIM_FLAG_UPDATE) != RESET)
{
if (__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_UPDATE) != RESET)
{
__HAL_TIM_CLEAR_IT(htim, TIM_IT_UPDATE);
HAL_TIM_PeriodElapsedCallback(htim);
}
}
}
// My callback
void HAL_TIM_PeriodElapsedCallback()
{
.....
}
Beyong the TIM6 interrupt I have other interrupts as well but when built with optimization
I discover that HAL_TIM_IRQHandler() is called continuosly but not my callback as if
TIM_FLAG_UPDATE is always cleared ( So why the handler is get called ?)
There's no way to sort out the things: no clear pending interrupt, no memory barriers ( I saw someone who solved similar problems with that).
It's not a time issue 'cause I set a lot of NOP and nothing changes.
The only one solution I found is to put a dummy instruction like the one commented in the code above. That solved my problem but I can't explain why.
Can someone can explain why or has a better solution ?
Thanks
Marco V.
2022-07-12 04:19 AM
Systick of course
I tried to change the priority of this interrupt but the problem is still there.
Optimized code runs OK as I already written but only if I omit the options mentioned
I think the problem is in the struct htim6 which is not aligned with the flag in the real TIM6 registers. But I can't declare it as volatile because it's used as pointer and the compiler warns tha pointers discards volatile or something like that.
It can't be differently. I just wonder why forcing a R/W operation into memory
solve the issue.