Similar to the previous example, this application uses two tasks but this time using a function, Tasks now are created to pass a struct as a parameter to control the time delay and the pins to control.

Code Example:

#include "bsp.h"

/*struct defining the pin and time for each task*/
typedef struct
{
    uint32_t Pin;   /*pin to toggle*/
    uint32_t Time;  /*period time to toggle*/
}_TogglePin;

/*Functions to act as tasks*/
static void vTask( void *parameters );

int main( void )
{
    /*Declare a static array with the information of pins and time to pass at each task as parameters*/
    static _TogglePin TogglePin[ 2u ] = 
    {
        {
            .Pin = GPIO_PIN_0, 
            .Time = 1000u
        }, 
        {
            .Pin = GPIO_PIN_1, 
            .Time = 2000u 
        }
    };

    HAL_Init( );     /*Inicializamos la librería*/

    /*enable RTT and system view*/
    SEGGER_SYSVIEW_Conf( );
    SEGGER_SYSVIEW_Start( );

    /*register first task using the function vTask with (128*4) bytes de stack, TogglePin[0] as parameter, 
    priority of 1 and no task handler registered*/
    xTaskCreate( vTask, "Task1", 128u, (void*)&TogglePin[0], 1u, NULL );

    /*register a second task using the function vTask with (128*4) bytes de stack, TogglePin[1] as parameter, 
    priority of 1 and no task handler registered*/
    xTaskCreate( vTask, "Task2", 128u, (void*)&TogglePin[1], 1u, NULL );
    
    /*run the RTOS scheduler*/
    vTaskStartScheduler( ); 
    
    return 0u;
}

/*Simple task that initialize pin C0 or C1 as output and toggle the pin state every 1000ms or 2000ms
the parameters variable will receive this information at the call of xTaskCreate*/
static void vTask( void *parameters )
{
    GPIO_InitTypeDef GPIO_InitStruct;
    /*declare a variable of type _TogglePin and assig after a cast the parameters passed
    at the moment the task is created (or registered)*/
    _TogglePin *TogglePin = (_TogglePin*)parameters;        /* Cast to use the Function parameter */

    __HAL_RCC_GPIOC_CLK_ENABLE( );                          /* Enable the clock for the GPIO port C */

    GPIO_InitStruct.Mode  = GPIO_MODE_OUTPUT_PP;            /* Configure the Pin as output */
    GPIO_InitStruct.Pull  = GPIO_NOPULL;                    /* Configure pin as no pull up - no pull down */
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;           /* Configure frequency of pin as High */
    GPIO_InitStruct.Pin   = TogglePin->Pin;                 /* Configure Pin passed as parameter */
    HAL_GPIO_Init( GPIOC, &GPIO_InitStruct );               /* Initialize the GPIO */ 

    for( ; ; )
    {
        HAL_GPIO_TogglePin( GPIOC, TogglePin->Pin );        /* change the state of pin */
        HAL_Delay( TogglePin->Time );                       /* HAL Delay */
    }
}

SystemView Output

Notice that the behavior of this application is similar to the previous example, the difference is that now a function is in charge of the control of LEDs using a struct parameter.