Now a message buffer is configured to send data to a task, remember that a message buffer can send a complete message in the buffer, this example is a basic example of how to send a complete message into the buffer to be received and processed.

Code Example:

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

#define BUFFER_SIZE 100
MessageBufferHandle_t xMessageBuffer;

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( );

    xMessageBuffer = xMessageBufferCreate( BUFFER_SIZE );           /* Create the message buffer */
    
    xTaskCreate( Task1, "Task1_SendData", 240, NULL, 2, NULL );     /* Register Task1 to turn on LEDs */
    xTaskCreate( Task2, "Task2_ReceiveData", 240, NULL, 1, NULL );  /* Register Task2 to turn off LEDs */
    
    vTaskStartScheduler();                                          /* Init the Kernel */
}

void Task1( void *pvParameters )
{
    size_t data_length = ( sizeof( uint32_t ) * 8 );                /* Variable to indicate the size of message */

    for(;;)
    {
        xMessageBufferSend( xMessageBuffer, LEDpin, data_length, portMAX_DELAY );   /* Send the message data */

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

void Task2( void *pvParameters )
{
    uint32_t receiver_data[8];                                      /* Variable to receive the message data */
    size_t bytes_read;                                              /* variable to indicate if message is received */
    for(;;)
    {
        bytes_read = xMessageBufferReceive( xMessageBuffer, &receiver_data, BUFFER_SIZE, portMAX_DELAY );   /* Receive the message */

        if(bytes_read > 0)                                          /* if there are message to read */
        {
            for (uint8_t i = 0; i < 8; i++)                         /* We expect to receive an array of elements, loop to iter in each position array */
            {
                HAL_GPIO_TogglePin(GPIOC, receiver_data[i]);        /* Process each data */
                SEGGER_SYSVIEW_PrintfHost( "%d",receiver_data[i] ); /* Process each data */
            }
        }

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

Observe that the code is similar to the Stream buffer, now the difference is that the first task sends the complete array that contains all the data of LED pins, the second task receives all the array, and after processing each element. If we use Instead a stream buffer it can do the same, the difference is the lecture of data, A stream buffer receptor is designed to read only a single data from a message, which means that the data stored will take more space filling faster the buffer because the receiver will take an element from the complete message every execution.

SystemView Output:

The terminal prints the data received in the message. The task in charge of receiving the messages from the buffer unpacks the data and prints each one. Notice that time is the same for all the data, also, observe the last element in the terminal, other messages arrive and the task reads the elements a second later.

Document

TimeLine:

Now observe the timeline, “Task1_SendData“ is the task that sends the array to the message buffer, starts first, and sends the data to the buffer, after “Task2_ReceiveDa“receives the message from the buffer, observe that after the task unpacks each element from the array and prints on the terminal.

Document