cancel
Showing results for 
Search instead for 
Did you mean: 

STM32CubeF4 FreeRTOS Examples don't work correctly with HAL GetTick

dlkeng
Associate III
Posted on May 26, 2014 at 23:29

In the STM32CubeF4 FreeRTOS Application examples, any HAL functions that internally use the HAL_GetTick() function for timeout operations will not work correctly because the SysTick ISR has been assigned to the FreeRTOS xPortSysTickHandler() function without regard to HAL operations.

I think this can be corrected by calling HAL_IncTick() before calling xPortSysTickHandler() in SysTick_Handler() similar to as follows:

void SysTick_Handler(void)

 

{

 

  HAL_IncTick(); 

// for internal HAL function HAL_GetTick() use

 

 

 

// *must* be called last or a Hard Fault will be generated

 

  xPortSysTickHandler();

 

}

 

Note: For some reason, if the xPortSysTickHandler() function is not called last in SysTick_Handler(), a Hard Fault exception will occur!

Also note, it is quite confusing to see multiple instances of SysTick being initialized in these examples:

  1. in HAL_Init()
  2. in SystemClock_Config()
  3. in vTaskStartScheduler()
Also, HAL code initializes and expects the SysTicks generated to be 1 mS ticks, but the FreeRTOS can easily be configured (via FreeRTOSConfig.hconfigTICK_RATE_HZ) to be another value, which would cause the HAL-related timeouts to be incorrect.

#stm32cubef4 #freertos #freertos
4 REPLIES 4
Oussema Hajjem_O
Associate III
Posted on May 27, 2014 at 11:05

Hi Dan,

A hard fault occurs because we execute thexPortSysTickHandler() and the scheduler is not yet started, to avoid it you can add the following code into the systick interrupt:

void
SysTick_Handler(
void
)
{
if
(xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
{
xPortSysTickHandler();
}
HAL_IncTick();
}

Actually in this STM32Cube version we have to configure both HAL and FreeRTOS ticks with Systick interrupt and with the same frequency (every 1 ms), an update will be done on next releases Thanks and regards
dlkeng
Associate III
Posted on May 27, 2014 at 16:20

Sorry, I tried your suggestion and still get a Hard Fault - xPortSysTickHandler() *must* be last.

Also, see the following for possible issues of using xTaskGetSchedulerState() in an ISR:

http://www.freertos.org/FreeRTOS_Support_Forum_Archive/January_2013/freertos_xTaskGetSchedulerState_API_and_isr_6699880.html

Oussema Hajjem_O
Associate III
Posted on May 29, 2014 at 18:37

Can you describe the source of your hard fault, I'm sure that the position of xPortSysTickHandler() is not the issue.

Please check that you are not modifying the interrupt priority group fixed in the HAL_Init() API

dlkeng
Associate III
Posted on May 30, 2014 at 01:03

I am not using an IDE and don't have a debugger, so the info I have is minimal.

However, here's some of the SCB registers when the Hard Fault exception occurs:

 SCB->HFSR:  0x40000000

 SCB->CFSR:  0x00040000

 SCB->BFAR:  0xe000ed38

 SCB->AIRCR: 0xe000ed38

 SCB->MMFAR: 0xe000ed34

From what I can tell, it looks like an ''Invalid PC load usage fault'' is occurring.

Here's my test SysTick_Handler( ) - failing case:

uint32_t x;

void SysTick_Handler(void)

{

    xPortSysTickHandler();

    x = 1;

}

Here's my test SysTick_Handler( ) - working case:

uint32_t x;

void SysTick_Handler(void)

{

    x = 1;

    xPortSysTickHandler();

}

As you can see, even with a simple variable assignment, the xPortSysTickHandler( ) call must be last in the function!

I am not changing the interrupt priority group used in HAL_Init( )

  /* Set Interrupt Group Priority */

  HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);