cancel
Showing results for 
Search instead for 
Did you mean: 

Use of "HAL_Delay" after "osThreadCreate"

Dev1
Associate II

Hi all,

I am working with the Nucleo-L476RG board.

I generated a project with CubeMx and enabling FreeRTOS.

At this point the project is running fine.

I debug the project and all is working.

I put a breack point inside the "SysTick_Handler" and this hadler is always launching.

Now, in main function, I add "HAL_Delay(1000)" after creation of the default task with "osThreadCreate" function:

0690X000008A7VVQA0.png

When I debug this code, the "SysTick_Handler" is never launching.

And the code hangs in the "HAL_Delay" function where "HAL_GetTick()" function returns always 0.

I read at https://community.st.com/s/question/0D50X00009XkYFaSAN/freertos-stm32-tick

that If Iwant to use HAL_Delay() before vTaskStartScheduler (osKernelStart), I need to check scheduler state before call xPortSysTickHandler:

I add this check in "SysTick_Handler":

0690X000008A7qYQAS.png

BUT the problem persists because the "SysTick_Handler" was never launched.

Can anyone please found the cause of this problem.

I now that I can overwrite the "HAL_Delay" function since it is "weak", but I need to know the cause of this problem.

Is there any missing configuration ?

Thank you.

8 REPLIES 8
Sirac
Associate III

Do you call a function like System_clockConfig ?

You need to init the systick and Irq, otherwise it will never start:

 HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
 HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
 HAL_NVIC_SetPriority(SysTick_IRQn, 15, 0);

Dev1
Associate II

The problem is after adding "HAL_Delay" function.

SysTick_Handler is launched before adding "HAL_Delay" line code in main function.

As I said "I put a breack point inside the "SysTick_Handler" and this hadler is always launching."

"HAL_SYSTICK_Config(SystemCoreClock/1000UL)" was called in "HAL_Init()".

"RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;" and "HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0)" are called in "SystemClock_Config"

"HAL_NVIC_SetPriority(SysTick_IRQn, 15, 0);" was called in "HAL_Init()".

Thanks.

Sirac
Associate III

A ok. For me it works but for you, firstly, remove this:

" if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)"

beacause it's already done in the osSystickHandler.

The HAL tick and the Os tick are completly independant. Normally, you have to use the TIM 1 as timer for the HAL tick. Is it done ?

If you use HAL_Delay, is your code is blocked ? or it continue to run ?

Dev1
Associate II

1) I don't use TIM1 for the HAL tick, both FreeRTOS and HAL use SysTick.

Timebase source is configured to SysTick in Cube Mx.

2) If I use HAL_Delay, the code is blocked inside this function. Since HAL_GetTick returns always 0 (SysTick_Handler was never launched to increment the ticks).

Thanks.

Sirac
Associate III

SysTick_Handler is handle by freeRtos so since you don't start the kernel, SysTick_Handler will never be called.

You have to use an other timer to use HAL_Delay before the scheduler is started.

Dev1
Associate II

Thanks,

But, if I call HAL_Delay before osThreadCreate, SysTick_Handler is always launched.

In the following code SysTick_Handler is never called:

 0690X000008AActQAG.png

And in the following code SysTick handler is always called (no problem with this code):

 0690X000008AAfnQAG.png

What is the difference ?

Sirac
Associate III

I don't know exactly what happen in the freeRTOS source code, but I think osThreadCreate will change the Systick.

You juste have to read the code of freeRtos te be sure.

Rob.Riggs
Senior

I just ran into this issue and I thought I would leave an answer which explains what is happening for anyone else experiencing this issue and how to avoid it. FreeRTOS raises the NVIC base priority as soon as any FreeRTOS function (such as osThreadCreate) is called. This disables most interrupts, including SysTick. It is only after the scheduler starts that the the NVIC priority is lowered to normal, re-enabling interrupts.

It is best to do all of the FreeRTOS/CMSIS-OS initialization in one block, doing nothing else within that block. Everything else should be done either before the first FreeRTOS call or within a FreeRTOS thread.

It would be helpful if the STM32CubeIDE templates included this information in a comment in main().

Reference: https://www.freertos.org/FreeRTOS_Support_Forum_Archive/December_2012/freertos_Using_interrupts_before_kernel_starts_6447124.html