Code Example:

#include "bsp.h"

#define TIMER_ID    1                           /* ID timer */

void vTimerCallback( TimerHandle_t pxTimer );   /* Timer callback */
void vTask( void *pvParameters );               /* Task Function */

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

    xTaskCreate( vTask, "task1", 240, NULL, 1, NULL );  /* Register Task in Kernel with a priority of 1 */
    
    vTaskStartScheduler();                      /* Kernel execution */
}

void vTask( void *pvParameters )
{
    TimerHandle_t xTimer;                                                       /* Timer Handler */
    xTimer = xTimerCreate( "timer", 500, pdFALSE, TIMER_ID, vTimerCallback );   /* Create the Timer with a period of 500 ticks */
    
    for(;;)
    {
        //SEGGER_RTT_printf("Starting timer\n");         /* Friendly message 1 */
        SEGGER_SYSVIEW_PrintfHost( " Starting Timer " );
        xTimerStart( xTimer, 0 );                       /* Start the Timer */
        vTaskDelay(2000);                               /* Change task state for 2000 ticks */
    }
}

void vTimerCallback( TimerHandle_t pxTimer )
{ 
    /* This function is called at the 500 ticks since the task1 */
    SEGGER_RTT_printf("Completed Time\n");              /* Friendly message 1 */
}

We create a simple task that in turn creates a timer, which will not be reloaded once it expires (check the third parameter). Inside the for loop, the task sends a message and starts the created timer, which will trigger sending a message to the screen through its callback after 500 ticks. This sequence will repeat every 2000 ticks indefinitely. The timer's handler is declared within the task and is perfectly valid since it doesn't need to be used outside the scope of the vTask function.

💡
Before continuing: Research the purpose of the second parameter in the xTimerStart function.

SystemView Output:

When the task executes the initialization, The Timer is created with the reload mode disabled and is started in the loop task function, printing on the terminal the message when the timer is started. Next, when the Period is elapsed, the callback of the timer is executed printing a message on the Terminal.

Document

Timeline:

Document

Timeline shows the execution of task1 to start the Timer count, task1 prints a message on terminal when the timer is started.

After 500 ticks the callback of Timer is executed printing a message to indicate that the period has elapsed, now the timer is disabled, and wait until the next execution of the task1 to start again.