cancel
Showing results for 
Search instead for 
Did you mean: 

FreeRTOS: Semaphore Issues When Using a Timer as the Timebase Source

KR1
Associate III

Howdy,

As the title suggests, I seem to be having some issues with FreeRTOS if I try to use a timer as the timebase source. The processor that I am using is STM32F745VET, but the MWE that I will try to describe should work on any system.

The SMT32CubeMX configuration goes as follows:

1. Configure the HSE in RCC tab for Crystal/Ceramic Resonator:

0690X0000098AqjQAE.png

2. Configure the system clock to run at 216 MHz in the Clock Configuration tab:

0690X0000098AqoQAE.png

3. Set the Timebase source as TIM6 in the SYS tab:

0690X0000098AqyQAE.png

4. Enable FreeRTOS in the Middleware tab (CMSIS_V1) and add a single binary semaphore to the stack:

0690X0000098Ar3QAE.png

5. Set two pins as output for LEDs:

0690X0000098Ar8QAE.png

6. Finally, build the project for SW4STM32.

If I modify my default thread code to:

void StartDefaultTask(void const * argument)
{
  /* USER CODE BEGIN 5 */
  /* Infinite loop */
  for(;;)
  {
    HAL_GPIO_TogglePin(LED0_GPIO_Port, LED0_Pin);
    osDelay(100);
  }
  /* USER CODE END 5 */ 
}

and build it, I can see LED0 flashing properly.

Now I can incorporate the semaphore code to the main thread:

void StartDefaultTask(void const * argument)
{
  /* USER CODE BEGIN 5 */
  /* Infinite loop */
  for(;;)
  {
	HAL_GPIO_TogglePin(LED0_GPIO_Port, LED0_Pin);
	if(osSemaphoreWait(myBinarySem01Handle, 5000) == osOK)
	{
		HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);
	}
    osDelay(100);
  }
  /* USER CODE END 5 */ 
}

and the periodic callback:

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  /* USER CODE BEGIN Callback 0 */
 
  /* USER CODE END Callback 0 */
  if (htim->Instance == TIM6) {
    HAL_IncTick();
  }
  /* USER CODE BEGIN Callback 1 */
  if ((HAL_GetTick() % 3000) == 0)
	  osSemaphoreRelease(myBinarySem01Handle);
  /* USER CODE END Callback 1 */
}

Pretty much the whole idea is to release the semaphore from this instance.

If I run the code now, LED0 blinks a couple of times, LED1 turns on and the system freezes in the vPortRaiseBASEPRI subroutine.

The weird thing is that all the Stm32Cube examples (that actually utilize SysTick) work just fine. Now I am pretty sure that these examples use SysTick, since the line:

#define xPortSysTickHandler SysTick_Handler

is always commented-out in the Stm32Cube-based FreeRTOSConfig.h's.

So, am I missing a certain step here? What does it take to get the timebase source running properly from a timer? Why does the system get stuck in this subroutine after the semaphore is released?

Thanks in advance!

P. S. I have found that it even not necessary to add the semaphore release code to HAL_TIM_PeriodElapsedCallback. The system will freeze on the first attempt to osSemaphoreWait(), if the prompt is left in the main thread.

2 REPLIES 2

Hi. Don`t call any FreeRTOS function when you in Timebase Interrupt Handler.

At "FreeRTOSConfig.h" you can find next:

/* The highest interrupt priority that can be used by any interrupt service
routine that makes calls to interrupt safe FreeRTOS API functions.  DO NOT CALL
INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
PRIORITY THAN THIS! (higher priorities are lower numeric values. */
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5

Interrupt priority for timebase timer is 0 (highest priority).

For your project you can configure any other timer for interrupt generation with priority lower that configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY (ex. 6, 7 ...). And put Semaphore Release function to that interrupt handler.

Tilen MAJERLE
ST Employee

I suggest you to enable configASSERT to find issues with environment setup.