Skip to main content
Visitor 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

    This topic has been closed for replies.

    5 replies

    Technical Moderator
    May 6, 2025

    Hello @AndrewST 

    Did you try to ping without FreeRTOS? 

    AndrewSTAuthor
    Visitor 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

    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

     

    AndrewSTAuthor
    Visitor 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);

    Super User
    May 6, 2025

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

    AndrewSTAuthor
    Visitor 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.

    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

    AndrewSTAuthor
    Visitor 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.

    Graduate II
    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?