Tasks within FreeRTOS have continuous execution, and if they have appropriate priorities, their execution can be periodic, which makes it much easier to create routines that need to run every x time. A very basic example is blinking an LED every 200ms or sending serial messages every 30 minutes. However, the issue is that creating a task for simple actions can be costly in terms of memory consumption; it usually requires at least 512 to 1k of heap memory reserved by FreeRTOS. A simple and efficient solution is to leverage the time base generated from the tick interrupt. By counting these ticks, we can create periodic routines without the need to create tasks. FreeRTOS provides timers that utilize this time base through a special task and offer the ability to execute a callback function each time they reach their timeout.

Code Example:

#include "bsp.h"

#define TIMER_ID    1                               /* Timer ID */
TimerHandle_t xTimer;                               /* Timer handler */

void vTimerCallback( TimerHandle_t pxTimer );       /* Funcion Callback */

int main( void )
{
    HAL_Init();
    /*enable RTT and system view*/
    SEGGER_SYSVIEW_Conf( );
    SEGGER_SYSVIEW_Start( );

    xTimer = xTimerCreate( "timer", 250, pdTRUE, TIMER_ID, vTimerCallback); /* Creation of timer with a time of 250 ticks, in auto reload mode*/

    xTimerStart( xTimer, 0 );                       /* Init the timer */

    vTaskStartScheduler();                          /* Start the Kernel */
}

void vTimerCallback( TimerHandle_t pxTimer )        /* Function callback of timer */
{
    SEGGER_RTT_printf(0,"Completed Time\n");         /* Send a message to the terminal */
}

In the previous code, a single timer is created, which will call the vTimerCallback function whenever the count reaches its end, in this case, after 250 ticks. Once the count is completed, the timer will be reloaded (indicated by the third parameter pdTRUE). When the timer is created, it doesn't start immediately; xTimerStart function is used for initialization. It's important that the scheduler has already started; otherwise, the timer will begin its count only after the scheduler starts, and not before. The callback function will print a simple message to the screen.

💡
NOTE: To use timers the definition configUSE_TIMERSpxTimer must be enabled on file “FreeRTOSConfig.h”
💡
Before continuing: modify the timer to count only once and explain why timers start their count only after the scheduler has started. Add two more timers to the previous program, each with different time intervals and different callback functions.

SystemView Output:

The Terminal shows the concurrent execution of the timer callback, sending the message to the terminal to indicate that the time of the timer has elapsed Reloading the timer and printing again on Termninal.

Document

TimeLine:

Document

When Task init, the timer is started. The start timer count init.
Observe time execution on the image, after 250 ticks, the timer must execute the callback function.

When the timer reaches 250 ticks the callback is executed printing a message on the terminal, and reloading the timer count to be executed again.