cancel
Showing results for 
Search instead for 
Did you mean: 

STM32CubeMx 4.12.0 freertos missing HAL_IncTick() in SysTick_Handler() ?

thomfischer
Senior
Posted on December 08, 2015 at 11:04

I have read the following note in STM32CubeMX 4.12.0 release notes

333755 [MX-FreeRTOS/NVIC] HAL_IncTick must be removed and systick prio must be the lowest when FreeRTOS is activated

I have regenerated a project with 4.12 and indeed the call to

HAL_IncTick() is removed from

SysTick_Handler

()

HAL_GetTick() is used in many HAL drivers for timeout.

How can timeouts work if HAL_IncTick() is removed ?

best regards

#hal #freertos
3 REPLIES 3
thln47
Associate III
Posted on December 08, 2015 at 11:26

Hi Thomas,

The SysTick interrupt should call the xPortSysTickHandler for freeRTOS usage.

and for the Delay function, you can use vTaskDelay.

void Delay(uint32_t nTime) {

    vTaskDelay(nTime);

}

see in FreeRTOSConfig.h

...

#define vPortSVCHandler SVC_Handler

#define xPortPendSVHandler PendSV_Handler

#define xPortSysTickHandler SysTick_Handler

thomfischer
Senior
Posted on December 08, 2015 at 11:34

user delays are not the problem

the question is

HAL_GetTick() is used in many HAL drivers for timeout.

How can timeouts work if HAL_IncTick() is removed ?

thln47
Associate III
Posted on December 08, 2015 at 11:40

The SysTimer is used for freeRTOS internal ticks count. So we can't use it directy (as we used in standard mode).

So you can do this:

1) add this define:

#define USE_FREERTOS                  1

2) As I said below, the SysTick interrupt should call the xPortSysTickHandler, and Irq should not be implemented for freeRTOS usage :

#ifndef USE_FREERTOS

/**

  * @brief  This function handles SVCall exception.

  * @param  None

  * @retval None

  */

void SVC_Handler(void)

{

}

/**

  * @brief  This function handles PendSVC exception.

  * @param  None

  * @retval None

  */

void PendSV_Handler(void)

{

}

/**

  * @brief  This function handles SysTick Handler.

  * @param  None

  * @retval None

  */

void SysTick_Handler(void)

{

  HAL_IncTick();    // <-- Standard call !

}

#endif

3) The HAL functions (ex: HAL_IncTick) are implemented with __weak statement in stm32f*xxx_hal.c so we redefine it:

uint32_t HAL_GetTick(void)

{

    return xTaskGetTickCount();

}

/**

  * dummy function to avoid the standard initialization code

  */

HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)

{

    return HAL_OK;

}

4) launch freeRTOS application:

#define LED_TASK_PRIORITY         ( tskIDLE_PRIORITY + 1 )

#define ledSTACK_SIZE            configMINIMAL_STACK_SIZE

static portTASK_FUNCTION( vLEDFlashTask, pvParameters )

{

    portTickType xLastFlashTime, xFlashRate = 100;

    /* The parameters are not used. */

    ( void ) pvParameters;

    xLastFlashTime = xTaskGetTickCount();

    for(;;)

    {

        printf(''.\n'');

        HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_8);

        /* USB LED */

        HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_15);

        vTaskDelayUntil( &xLastFlashTime, xFlashRate );

    }

}

void vStart_Test_RT_Led_Tasks( unsigned portBASE_TYPE uxPriority ) {

    xTaskCreate( vLEDFlashTask, ( portCHAR * ) ''testLed'', ledSTACK_SIZE, NULL, uxPriority, ( xTaskHandle * ) NULL );

}

void start_FreeRTOS(void) {

    vStart_Test_RT_Led_Tasks( LED_TASK_PRIORITY );

    HAL_GetTick();     // <- used in many HAL drivers.

                    // Now It's working with freeRTOS 😉

    /* Start the scheduler. */

    vTaskStartScheduler();

    while(1);

}

You should start the scheduler before calling HAL_Delay !

so create a main task who call your HAL_Init function. This function call HAL initialization and the delay works.

static portTASK_FUNCTION( vMainTask, pvParameters ) {

    /* The parameters are not used. */

    ( void ) pvParameters;

    HAL_Init();

    printf(''waiting for some delay ...'');

    HAL_Delay(100);    // <- used in many HAL drivers.

                                     // Now It's working now with freeRTOS 😉

    printf(''done\n'');

    for(;;)    {

        portTickType xLastTickCount = xTaskGetTickCount();

        vTaskDelayUntil(&xLastTickCount, LOOP_TIME_MS);

    }

}