In this application, a communication task is used to transfer data from a task designed only to transmit the data, and another task to receive each data. Using a stream buffer the data is stored in the buffer, after being received to be processed.

Code Example:

#include "bsp.h"
#include <math.h>

#define BUFFER_SIZE 100                 /* Define the size of the buffer */
StreamBufferHandle_t xStreamBuffer;     /* Define the stram buffer handle */

uint32_t LEDpin[8] = { GPIO_PIN_0, GPIO_PIN_1, GPIO_PIN_2, GPIO_PIN_3, GPIO_PIN_4, GPIO_PIN_5, GPIO_PIN_6, GPIO_PIN_7 }; /* Array of LED pins */

void Task1( void *pvParameters );   /* Task1 To turn on LEDs */
void Task2( void *pvParameters );   /* Task2 to turn off LEDs */

int main( void )
{
    HAL_Init();

    SEGGER_SYSVIEW_Conf( );
    SEGGER_SYSVIEW_Start( );

    xStreamBuffer = xStreamBufferCreate( BUFFER_SIZE, 1 );
    
    xTaskCreate( Task1, "SendData", 240, NULL, 2, NULL );     /* Register Task1 to Send pin LEDs */
    xTaskCreate( Task2, "ReceiveData", 240, NULL, 1, NULL );  /* Register Task2 to receive pin LEDs */
    
    vTaskStartScheduler();      /* Init the Kernel */
}

void Task1( void *pvParameters )
{
    uint32_t data_to_send = (uint32_t)LEDpin;   /* Data to send to buffer */
    size_t data_length = sizeof( uint32_t );    /* size of data to send */

    uint8_t iter = 0;                           /* variable to iterate array position */

    for(;;)
    {
        if(iter >= 8)                           /* loop to restart iteration */
        {
            iter = 0;                           /* Restart array position */
        }

        data_to_send = LEDpin[iter];            /* store the data to send */
        xStreamBufferSend( xStreamBuffer, &data_to_send, data_length, portMAX_DELAY );  /* Send the data to buffer */

        iter++;                                 /* increment iteration */

        vTaskDelay(200);                        /* Period of the task */
    }
}

void Task2( void *pvParameters )
{
    uint32_t receiver_data;                     /* variable to store data received */
    size_t bytes_read;                          /* Variable to know if there are data to read */
    uint32_t PrintLED;                          /* Variable to print the LED Number */
    for(;;)
    {
        do{
            bytes_read = xStreamBufferReceive(xStreamBuffer, &receiver_data, BUFFER_SIZE, portMAX_DELAY);   /* Read data from buffer */
            HAL_GPIO_TogglePin(GPIOC, receiver_data);                   /* Change LED status */
            
            PrintLED = log2( receiver_data );
            SEGGER_SYSVIEW_PrintfHost( "LED %d", PrintLED );            /* Print on terminal the data received */
        }while (bytes_read > 0);                                        /* Do the loop while there are data in buffer */

        vTaskDelay(1000);                    /* Period of the task */
    }   
}

Observe the code, the data to send is the pin info where an LED is connected. The first task is designed to transfer this pin data to the second task. The second task is intended to receive from the stream buffer the data sent by the first task to process the pin info and change the state of the LED.

Notice that the first task will send data each 200ms to the buffer, when the second task executes there are enough data to be received and processed, the second task will execute each second, to avoid a data overload the second task will perform a loop to read all the buffer elements until buffer was empty.

SystemView Output:

Observe that the data is read correctly without any jump in data, the LEDs must be turned on in series. Also, observe that the data is received just when the first task sends the data in the buffer.

Document

TimeLine:

Document

Observe in timeline the execution of the task, the task in charge of send the data is executed writing the pin info in buffer, when the task finish, the second task is executed receiving the data from buffer and processing it.

Observe the time execution between the last image and this. The first task is executed again sending the data, after second task starts and receive and process the pin info. “ReceiveData” task is executed each 200ms as the “SendData“ task, although the “ReceiveData” period is 1000ms.