As in the previous example Serial port and stream buffer, the serial communication interrupt is used now using the messages buffer. This is a similar application but now the data must be sent in a complete message, to do that, in this example the serial data received is stored in an array to send a message to the buffer.

Code Example:

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

#define RESET_VALUE 0               /* Value to reset an element */
#define BUFFER_SIZE 100             /* Size of stream buffer */

UART_HandleTypeDef UartHandle;        /* UART handler structure */
MessageBufferHandle_t xMessageBuffer; /* Handle of message buffer */

uint8_t RxBuffer[ 50 ];             /* buffer for message received */
uint8_t RxByte;                     /* temporary reception buffer */

void Task1( void *pvParameters );   /* Task1 To Receive the stream buffer */

int main( void )
{
    HAL_Init();

    SEGGER_SYSVIEW_Conf( );
    SEGGER_SYSVIEW_Start( );

    xMessageBuffer = xMessageBufferCreate( BUFFER_SIZE );           /* Create the message buffer */

    /* --- --- UART configuration options --- --- */
    UartHandle.Instance         = USART2;
    UartHandle.Init.BaudRate    = 9600;
    UartHandle.Init.WordLength  = UART_WORDLENGTH_8B;
    UartHandle.Init.StopBits    = UART_STOPBITS_1;
    UartHandle.Init.Parity      = UART_PARITY_NONE;
    UartHandle.Init.HwFlowCtl   = UART_HWCONTROL_NONE;
    UartHandle.Init.Mode        = UART_MODE_TX_RX;
    UartHandle.Init.OverSampling = UART_OVERSAMPLING_16;
    HAL_UART_Init( &UartHandle );                            /* Init the UART */
    HAL_UART_Receive_IT( &UartHandle, &RxByte, 1 );          /* Enable and set the reception using Interruption */   

    xTaskCreate( Task1, "T1_Reception", 240, NULL, 2, NULL ); /* Register Task1 to Receive stream buffer */
    
    vTaskStartScheduler();                                   /* Init the Kernel */
}

void Task1( void *pvParameters )
{
    char receiver_data[BUFFER_SIZE];                    /* Variable to receive the message buffer */
    size_t bytes_read;                                  /* Variable that indicate the bytes receved from the buffer */
    for(;;)
    {
        bytes_read = xMessageBufferReceive( xMessageBuffer, &receiver_data, BUFFER_SIZE, portMAX_DELAY );   /* Receive the message from buffer */

        if(bytes_read > 0)                                  /* Verify that message is received */
        {
            SEGGER_SYSVIEW_PrintfHost( receiver_data );     /* Process the message buffer received */
        }

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

/* Callback of Serial data reception */
void HAL_UART_RxCpltCallback( UART_HandleTypeDef *huart )
{
    static uint32_t i = 0;
    RxBuffer[i] = RxByte;                                   /* store data received*/
    i++;                                                    /* increase index pointer */
    
    if( RxBuffer[i-1] == '\r' )                             /* look for the end of the string */
    {
        RxBuffer[i] = '\0'; /*set end of the string*/       /* add a temination character to message */
        i = 0;                                              /* restart buffer index */
        xMessageBufferSendFromISR( xMessageBuffer, RxBuffer, sizeof(RxBuffer), NULL ); /* Send the message to the buffer */
    }

    HAL_UART_Receive_IT( &UartHandle, &RxByte, 1 );         /* Enable the interruptpion reception again */
}

Observe the code, and notice that the callback of serial port reception now has an algorithm to store each data in an array until the enter key is pressed. When the key is pressed the complete array is sent to the message buffer, the task in charge of receiving the data of the buffer just reads the element this time without waiting for a termination character as in the Stream buffer example, the task only processes the data and print on terminal the message received.

SystemView Output:

Observe the work of the callback that puts together the data to make a message and send it to the message buffer. Notice that each message on Terminal did not correspond to the period of task in charge of receiving the message, this indicates that the message is stored in the buffer just when the Enter key is pressed.

Document

TimeLine:

Document

First, Task “T1_Reception“ try to get data from the message buffer but it is empty and task pass to the blocked state until a data is received or the max ticks registered elapsed.

Compare the time elapsed between the last capture and this image. A message is received and processed to be printed on the terminal.
Elapsed time not correspond to the current task period, this is because in the las execution task enter to blocked state and the reception of a message in the buffer unlocks the task.

Now observe that this time the task execute in the established period, but again the buffer is empty and task is sent to the blocked state again until a new element on buffer is received.