Skip to main content
AndrewST
Associate II
May 5, 2025
Question

F767 + FreeRTOS + LWIP => HAL_Delay fails

  • May 5, 2025
  • 5 replies
  • 1166 views

Hello,

I can run older TCP/IP examples on my F767 Nucleo but I want to start fresh and understand what is going on.

Basic project started with CubeIDE/CubeMX code generation. FreeRTOS, LWIP, fixed IP => Does not answer to ping. Turns out MX_LWIP_Init() never returns.

If I step into the ethernetif initialisation code, I see that anywhere  HAL_Delay(ETH_REG_WRITE_DELAY) is called within stm32f7xx_hal_eth.c, it never returns, unless I step into it from the debugger and go step by step (and see uwTickFreq increment) until HAL_Delay returns.

I understand the time base is a common issue often because of the interrupt priorities, but I think I have everything setup correctly. I am using Timer 6 as a tick source, with its IT priority set to 0. 

Again, I do see uwTickFreq increment if I run the code step by step.

I removed MX_LWIP_Init() from the code and added some HAL_Delay(1000) in the for(;;) loop in the defaulttask and it returns every second, which tells me HAL_Delay() and FreeRTOS work together in the configuration I have.

I am sure I am missing something simple but I cannot tell what...

SYStick.JPGNVIC.JPG

5 replies

Technical Moderator
May 6, 2025

Hello @AndrewST 

Did you try to ping without FreeRTOS? 

"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.Saket_Om"
AndrewST
AndrewSTAuthor
Associate II
May 7, 2025

Yes. Ping works if I remove FreeRTOS.

Technical Moderator
May 7, 2025

Hellà @AndrewST 

Could you please Try with ETH preemptive interrupt higher that other peripherals. Or just test the ping functionality with all other peripherals disabled

"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.Saket_Om"
Guillaume K
ST Employee
May 6, 2025

@AndrewST wrote:

I am using Timer 6 as a tick source, with its IT priority set to 0. 

Why set it to 0 ? (highest priority)

if FreeRTOS is used, the interrupts shouldn't be higher priority (so lower value) than FreeRTOS's configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY in FreeRTOSConfig.h:

 

/* 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

 

AndrewST
AndrewSTAuthor
Associate II
May 7, 2025

I think you have it backwards. 

configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY is the highest priority level that can be assigned to an ISR calling a FreeRTOS API. That's what the comment you copy/paste states.

What I described is the other way around: FreeRTOS is calling the HAL driver API functions which are using HAL_Delay which is NOT a FreeRTOS API, so it is fine.

 

Ironically, the code example you suggest in your second answer sets TIMER6 's ISR priority exactly to the same level, 0:

/*Configure the TIM6 IRQ priority */

HAL_NVIC_SetPriority(TIM6_DAC_IRQn, TickPriority ,0U);

Andrew Neil
Super User
May 6, 2025

If you're using FreeRTOS, surely it has its own timers ... ?

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
AndrewST
AndrewSTAuthor
Associate II
May 7, 2025

Sorry if I am missing your point? FreeRTOS has its own timer, sure. But the HAL drivers are set to use an external timer (TIM6 here) that has a higher tick priority which should work, but it doe snot, and I am trying to figure out why.

Guillaume K
ST Employee
May 6, 2025

By default the STM32 HAL uses the Cortex M internal hardware timer SYSTICK to increment the global variable uwTick which is the tick counter used by HAL_Delay().

By default, systick is initialized in HAL_InitTick() weak function in stm32f7xx_hal.c

If you are using an RTOS (like FreeRTOS or ThreadX), the RTOS requires the Systick for its own purpose.

In that case the application should configure the HAL to use another HW timer (e.g. TIM interrupt) than Systick to increment the HAL tick.

The HW timer must be initialised correctly and the function HAL_InitTick() must be overriden (weak function) to initialize the HW TIM instead of systick.

Usually it's done in an additional source file stm32f7xx_hal_timebase_tim.c added in the application project.

example:

STM32CubeF7/Projects/STM32F769I-Discovery/Applications/LwIP/LwIP_HTTP_Server_Socket_RTOS/Src/stm32f7xx_hal_timebase_tim.c at master · STMicroelectronics/STM32CubeF7 · GitHub

AndrewST
AndrewSTAuthor
Associate II
May 7, 2025

Everything you are saying is done by setting "Timebase source" to TIM6, which is what I have done already.

stm32f7xx_hal_timebase_tim.c is generated automatically by CubeMX and is identical to the one in the example linked.

Associate
September 10, 2025

I had nearly the same problem with the `MX_ETH_Init()` function never returning and getting stuck in the `HAL_Delay()`. In my case the problem was that I was creating a task before the hardware initialised. I assumed this should be harmless as I have not started the scheduler yet.

BaseType_t taskCreationRetVal;
taskCreationRetVal = xTaskCreate(uartDMATask, "uart_DMA_Print", STACK_SIZE, NULL, tskIDLE_PRIORITY + 2, &uartTskHndl);
assert_param(taskCreationRetVal == pdPASS);

Turns out this is not allowed. My solution came from this link: https://forums.freertos.org/t/problem-with-hal-delay-function-in-freertos/12288/2

Basically: Inside the main function, do not put any FreeRTOS code before the hardware has had a chance to initialise. 

@AndrewST check if anywhere in your main function there is FreeRTOS code before all the init's?