cancel
Showing results for 
Search instead for 
Did you mean: 

HAL Tick does not get incremented on second debug session after reset (FreeRTOS)

NGajic
Associate III

I'm working on project that is including ADC, timers and virtual UART. I'm working on STM32MP157C-DK2 board. So I started from example OpenAMP_FreeRTOS_echo from CubeMP1 software package v1.2.0. I'm using CubeIDE v1.4.0. When I reboot STM32MP1 and debug for the first time after reboot, and place breakpoint into HAL_TIM_PeriodElapsedCallback function in which HAL_IncTick is called, everything is fine and the program is stopping here. Problem is that when I debug for the second time (and software on M4 is stopped before 2nd debug) program is not stopping on breakpoint and the HAL tick is not getting incremented. The code is not being modified, it is the same as in examples. On boot I choose the device tree number 3 which is used for M4 examples. Question is why is this happening and do I need to reboot the board every time I want to debug?

Thanks in advance,

Nenad

35 REPLIES 35

Hi @NGajic​ ,

Sorry to read this.

On my side on the pure OpenAMP_FreeRTOS_echo example, since I duplicate HAL_NVIC_EnableIRQ(TIM2_IRQn); just after the HAL_Init(), I'm unable to reproduce any issue after several terminate and relaunch operation ( at least 10 ).

Expert are still working to investigate root cause.

Olivier

Olivier GALLIEN
In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.

Hi @Community member​ ,

I'm not using debug mode. I'm running the firmware with echo start > /sys/class/remoteproc/remoteproc0/state. Here is my flow:

  1. Build the binary (HAL_NVIC_EnableIRQ(TIM2_IRQn) is added after HAL_Init)
  2. Transfer binary using SCP client (WinSCP)
  3. Copy binary to /lib/firmware
  4. echo OpenAMP_FreeRTOS_echo.elf > /sys/class/remoteproc/remoteproc0/firmware
  5. echo start > /sys/class/remoteproc/remoteproc0/state
  6. echo stop > /sys/class/remoteproc/remoteproc0/state

Do the 5. and 6. several times and the diode stop toggling. Code is OpenAMP_FreeRTOS_echo with added HAL_Delay(10) before if where diode is toggled (picture). Another question is how your TIM2_IRQHandler looks? Mine is on picture below.0693W000007DH94QAG.png0693W000007DH7hQAG.png

Hi @Community member​ ,

When I posted the above question I realized that I didn't tried combination to uncomment else which is doing HAL_NVIC_DisableIRQ in HAL_TIM2_IRQHandler above, with your suggestion to add HAL_NVIC_EnableIRQ after HAL_Init. It is working now! I tried 20 times maybe and diode is toggling every time (meaning HAL_Delay is not like while(1), and HAL tick is incrementing) when I stop and start firmware. Thank you!

Best regards,

Nenad

Hi @Community member​ ,

I think that I find out what is happening here... We are doing HAL_Init, and there HAL_InitTick is called, first HAL_NVIC_EnableIRQ is done, and several lines after htim2.Instance is set to TIM2. There's a problem, because interrupts are enabled, HAL_TIM2_IRQHandler is called and there:

 if (htim2.Instance != NULL)

 {

  HAL_TIM_IRQHandler(&htim2);

 }

 else

 {

  /* Disable the TIM2 global Interrupt */

  HAL_NVIC_DisableIRQ(TIM2_IRQn);

 }

So we will enter into else and TIM2_IRQn will be disabled because htim2 instance is not set. Because that if you add HAL_NVIC_EnableIRQ is working the job when placed after HAL_Init. So what is maybe better solution?

HAL_InitTick function (stm32mp1xx_hal_timebase_tim.c in OpenAMP_FreeRTOS) should be changed and htim2.Instance = TIM2; should be placed before HAL_NVIC_EnableIRQ(TIM2_IRQn).

It should look like:

HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)

{

 //RCC_ClkInitTypeDef  clkconfig;

 uint32_t       uwTimclock = 0;

 uint32_t       uwPrescalerValue = 0;

 //uint32_t       pFLatency;

 /*Configure the TIM2 IRQ priority */

 HAL_NVIC_SetPriority(TIM2_IRQn, TickPriority, 0);

htim2.Instance = TIM2; //ADD THIS HERE

 /* Enable the TIM2 global Interrupt */

 HAL_NVIC_EnableIRQ(TIM2_IRQn);

 /* Enable TIM2 clock */

 __HAL_RCC_TIM2_CLK_ENABLE();

 /* Get clock configuration */

 //HAL_RCC_GetClockConfig(&clkconfig, &pFLatency);

 __HAL_RCC_TIM2_FORCE_RESET();

 __HAL_RCC_TIM2_RELEASE_RESET();

 /* Compute TIM2 clock */

 uwTimclock = HAL_RCC_GetPCLK1Freq();

 /* Compute the prescaler value to have TIM2 counter clock equal to 1MHz */

 uwPrescalerValue = (uint32_t)((uwTimclock / 1000000) - 1);

 /* Initialize TIM2 */

 //htim2.Instance = TIM2; //Comment this

 /* Initialize TIMx peripheral as follow:

 + Period = [(TIM2CLK/1000) - 1]. to have a (1/1000) s time base.

 + Prescaler = (uwTimclock/1000000 - 1) to have a 1MHz counter clock.

 + ClockDivision = 0

 + Counter direction = Up

 */

 htim2.Init.Period = (1000000 / 1000) - 1;

 htim2.Init.Prescaler = uwPrescalerValue;

 htim2.Init.ClockDivision = 0;

 htim2.Init.CounterMode = TIM_COUNTERMODE_UP;

 if (HAL_TIM_Base_Init(&htim2) == HAL_OK)

 {

  /* Start the TIM time Base generation in interrupt mode */

  return HAL_TIM_Base_Start_IT(&htim2);

 }

 /* Return function status */

 return HAL_ERROR;

}

Best regards,

Nenad

Hi @NGajic​ ,

Great ! you find it !

Expert in ST reach same conclusion in // of you.

I come back this day with recommended patch.

Olivier

Olivier GALLIEN
In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.
Olivier GALLIEN
ST Employee

Hi @NGajic​ , @JCant.1​ ,

This is final explanation for the issue :

The issue is caused by one interrupt from the previous execution

that remains pending in the NVIC.

The new execution erroneously enable the TIM2 interrupts 'before'

setting in the handler:

/* Initialize TIM2 */

htim2.Instance = TIM2;

The pending interrupt immediately triggers the execution of the

IRQ handler TIM2_IRQHandler(), which finds 'htim2.Instance' not

initialized yet and, in response to this spurious interrupt,

disables the just enabled TIM2 interrupts.

This issue is more evident by using CubeIDE; to restart a new run

of the example, CubeIDE first halts the target core, then quits

from the debugger and restarts the firmware. When the core is

halted, TIM2 is still running, thus feeds in NVIC the interrupt

that will deterministically hang the next execution.

Patch attached.

Thanks for reporting and help to fix this issue !

Olivier

Olivier GALLIEN
In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.