Stream Buffer vs. Message Buffer

@aggarg Thanks for your reply.
I saw the documentation you are refering to but I have to admit that it looks a bit misleading to me.

The description of pucStreamBufferStorageArea states that you have to supply an array that is +1 byte bigger than the xBufferSizeBytes parameter states.
Although in the example sizeof( ucStoragegBuffer ) is used as value for xBufferSizeBytes which in turn results in pucStreamBufferStorageArea pointing to an area that is exactly the same size as xBufferSizeBytes, instead of +1 byte bigger. Do you know what I mean?
In my understanding of the description, the xBufferSizeBytes should be defined as sizeof( ucStoragegBuffer ) -1 to match the requirements. Because then the array is truly 1 byte larger than pointed out by xBufferSizeBytes.

But doing so will actually result in a buffer being the size of sizeof( ucStoragegBuffer )-2.

/* Used to dimension the array used to hold the messages.  The available space 
will actually be one less than this, so 999. */ 
#define STORAGE_SIZE_BYTES 1000 
 
/* Defines the memory that will actually hold the messages within the message 
buffer.  Should be one more than the value passed in the xBufferSizeBytes 
parameter. */ 
static uint8_t ucStorageBuffer[ STORAGE_SIZE_BYTES ]; 
 
/* The variable used to hold the message buffer structure. */ 
StaticMessageBuffer_t xMessageBufferStruct; 
 
void MyFunction( void ) 
{ 
MessageBufferHandle_t xMessageBuffer; 
 
    xMessageBuffer = xMessageBufferCreateStatic( sizeof( ucStoragegBuffer ), 
                                                 ucBufferStorage, 
                                                 &xMessageBufferStruct ); 
 
    /* As neither the pucMessageBufferStorageArea or pxStaticMessageBuffer 
    parameters were NULL, xMessageBuffer will not be NULL, and can be used to 
    reference the created message buffer in other message buffer API calls. */ 
 
    /* Other code that uses the message buffer can go here. */ 
} 

Best Regards,

Anyways, maybe it’s just me and everybody else understands the documentation just fine. After some clarifications I got there as well… :wink: And at least there apparently is no bug to report.
@richard-damon Thanks for solving my questions.

Best Regards,

I would say the documentation definitely has an error, as the documentation for the documentation for pucStreamBufferStorageArea says “Must point to a uint8_t array that is at least xBufferSizeBytes + 1 big. This is the array to which streams are copied when they are written to the stream buffer.”

This means the example fails to meet that requirement of the function.

The parameter xBufferSizeBytes says “The size, in bytes, of the buffer pointed to by the pucStreamBufferStorageArea parameter.”, which is in direct contradiction to the definition of pucStreamBufferStorageArea

Because of the similarity between xStreamBufferCreateStatic and xStreamBufferCreate, it would seem expected that the parameters would mostly align, and for xStreamBufferCreate the parameter xBufferSizeBytes is described as “The total number of bytes the stream buffer will be able to hold at any one time.”, which if THAT terminology were moved into xStreamBufferCreateStatic would remove the inconsistency between the definitions of the parameters, and make the two buffers behave the same as to buffer size.

The one problem is that any code that depends on the existing behavior will have a buffer overrun condition.

1 Like

Thank you @Stonebull and @richard-damon. Agree that there is a documentation error. I think we need to change the description of the xBufferSizeBytes description as @richard-damon poined out and the example code.

xBufferSizeBytes
    The total number of bytes the stream buffer will be able to hold at any one time.
/* The total number of bytes the stream buffer will be able to hold at any one time. */
#define STREAM_BUFFER_SIZE_BYTES 1000

/* Defines the memory that will actually hold the streams within the
 * stream buffer. Note that it needs to be of size (STREAM_BUFFER_SIZE_BYTES + 1). */
static uint8_t ucStreamBufferStorage[ STREAM_BUFFER_SIZE_BYTES + 1 ];
static uint8_t ucStreamBufferWithCallbackStorage[ STREAM_BUFFER_SIZE_BYTES + 1 ];

/* The variable used to hold the stream buffer structure. */
StaticStreamBuffer_t xStreamBufferStruct;
StaticStreamBuffer_t xStreamBufferWithCallbackStruct;

void vSendCallbackFunction( StreamBufferHandle_t xStreamBuffer,
                            BaseType_t xIsInsideISR,
                            BaseType_t * const pxHigherPriorityTaskWoken )
{
    /* Insert code here which is invoked when a data write operation
     * to the stream buffer causes the number of bytes in the buffer
     * to be more then the trigger level.
     * This is useful when a stream buffer is used to pass data between
     * cores on a multicore processor. In that scenario, this callback
     * can be implemented to generate an interrupt in the other CPU core,
     * and the interrupt's service routine can then use the
     * xStreamBufferSendCompletedFromISR() API function to check, and if
     * necessary unblock, a task that was waiting for the data. */
}

void vReceiveCallbackFunction( StreamBufferHandle_t xStreamBuffer,
                               BaseType_t xIsInsideISR,
                               BaseType_t * const pxHigherPriorityTaskWoken )
{
    /* Insert code here which is invoked when data is read from a stream
     * buffer.
     * This is useful when a stream buffer is used to pass data between
     * cores on a multicore processor. In that scenario, this callback
     * can be implemented to generate an interrupt in the other CPU core,
     * and the interrupt's service routine can then use the
     * xStreamBufferReceiveCompletedFromISR() API function to check, and if
     * necessary unblock, a task that was waiting to send the data. */
}

void MyFunction( void )
{
StreamBufferHandle_t xStreamBuffer, xStreamBufferWithCallback;
const size_t xTriggerLevel = 1;

    /* Create a stream buffer that uses the functions defined
     * using the sbSEND_COMPLETED() and sbRECEIVE_COMPLETED()
     * macros as send and receive completed callback functions. */
    xStreamBuffer = xStreamBufferCreateStatic( STREAM_BUFFER_SIZE_BYTES,
                                               xTriggerLevel,
                                               ucStreamBufferStorage,
                                               &xStreamBufferStruct );

    /* Create a stream buffer that uses the functions
     * vSendCallbackFunction and vReceiveCallbackFunction as send
     * and receive completed callback functions. */
    xStreamBufferWithCallback = xStreamBufferCreateStaticWithCallback(
                                    STREAM_BUFFER_SIZE_BYTES,
                                    xTriggerLevel,
                                    ucStreamBufferWithCallbackStorage,
                                    &xStreamBufferWithCallbackStruct,
                                    vSendCallbackFunction,
                                    vReceiveCallbackFunction );

    /* As neither the pucStreamBufferStorageArea or pxStaticStreamBuffer
     * parameters were NULL, xStreamBuffer and xStreamBufferWithCallback
     * will not be NULL, and can be used to reference the created stream
     * buffers in other stream buffer API calls. */
    
    /* Other code that uses the stream buffers can go here. */
}

I will forward this to our documentation team.

1 Like