cancel
Showing results for 
Search instead for 
Did you mean: 

Enabling Register Callback for Timer in CubeMX, when FreeRTOS is enabled generate incorrect code.

serg22
Associate II

In my project I have FreeRTOS enabled, which occupies SysTick and Time increment is handled by TIM1. I also want to use basic timer as TIM6.
However, I don't want them both processed in weak redefined 

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
Thus, I enabled register callback for TIM in CubeMX -> advance settings -> register callbacks.

The generated code appears in stm32f4xx_hal_timebase_tim.c and looks as following:
HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
{
  RCC_ClkInitTypeDef    clkconfig;
  uint32_t              uwTimclock = 0U;

  uint32_t              uwPrescalerValue = 0U;
  uint32_t              pFLatency;

  HAL_StatusTypeDef     status;

  /* Enable TIM1 clock */
  __HAL_RCC_TIM1_CLK_ENABLE();

  /* Get clock configuration */
  HAL_RCC_GetClockConfig(&clkconfig, &pFLatency);

  /* Compute TIM1 clock */
      uwTimclock = 2*HAL_RCC_GetPCLK2Freq();

  /* Compute the prescaler value to have TIM1 counter clock equal to 1MHz */
  uwPrescalerValue = (uint32_t) ((uwTimclock / 1000000U) - 1U);

  /* Initialize TIM1 */
  htim1.Instance = TIM1;

  /* Initialize TIMx peripheral as follow:
   * Period = [(TIM1CLK/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
   */
  htim1.Init.Period = (1000000U / 1000U) - 1U;
  htim1.Init.Prescaler = uwPrescalerValue;
  htim1.Init.ClockDivision = 0;
  htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;

  status = HAL_TIM_Base_Init(&htim1);
  if (status == HAL_OK)
  {
    /* Start the TIM time Base generation in interrupt mode */
    status = HAL_TIM_Base_Start_IT(&htim1);
    if (status == HAL_OK)
    {
    /* Enable the TIM1 global Interrupt */
        HAL_NVIC_EnableIRQ(TIM1_UP_TIM10_IRQn);
      /* Configure the SysTick IRQ priority */
      if (TickPriority < (1UL << __NVIC_PRIO_BITS))
      {
        /* Configure the TIM IRQ priority */
        HAL_NVIC_SetPriority(TIM1_UP_TIM10_IRQn, TickPriority, 0U);
        uwTickPrio = TickPriority;
      }
      else
      {
        status = HAL_ERROR;
      }
    }
  }

  HAL_TIM_RegisterCallback(&htim1, HAL_TIM_PERIOD_ELAPSED_CB_ID, TimeBase_TIM_PeriodElapsedCallback);

 /* Return function status */
  return status;
}

For some reason HAL_TIM_RegisterCallback() is called after HAL_TIM_Base_Start_IT(), which result's in setting custom callback, because Timer is already running. 
Moreover, the weak overwrite callback is still generated in main.c as following:

/**
  * @brief  Period elapsed callback in non blocking mode
  * @note   This function is called  when TIM1 interrupt took place, inside
  * HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment
  * a global variable "uwTick" used as application time base.
  * @PAram  htim : TIM handle
  * @retval None
  */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  /* USER CODE BEGIN Callback 0 */

  /* USER CODE END Callback 0 */
  if (htim->Instance == TIM1)
  {
    HAL_IncTick();
  }
  /* USER CODE BEGIN Callback 1 */

  /* USER CODE END Callback 1 */
}

So it doesn't look correct, or a am I missing something?

 

 

 

2 REPLIES 2
Ghofrane GSOURI
ST Employee

Hello @serg22 

First let me thank you posting.

I'm currently investigating this . I will get back to you asap.

THX

Ghofrane

Ghofrane GSOURI
ST Employee

Hello @serg22 

Your contribution is much appreciated .
Issue has been raised to the development team for fix.

Internal ticket number : 207314 

I'll keep you posted on any updates.

THX

Ghofrane