Skip to content

[BUG] Batching Stream Buffer Receiving Task Woken Before Trigger Level Exceeded #1375

@dougsummerville

Description

@dougsummerville

Describe the bug
When reading an empty batching stream buffer, once the trigger level is reached a task notification is sent to the receiving task, with xStreamBufferReceive() returning 0 bytes. The tigger level should be exceeded before the notification is sent, in which case xStreamBufferReceive() will return a non-zero number of bytes.

Target

  • Development board: Raspberry Pi Pico2
  • Instruction Set Architecture: ARM CM33
  • IDE and version: N/A bare metal
  • Toolchain and version: arm-none-eabi-gcc 14.2.0-2

Host

  • Host OS: Linux
  • Version: 6.18.8

To Reproduce

  1. Create a Batching Stream Buffer with xTriggerLevelBytes. For example stream_buf = xStreamBatchingBufferCreate( 25, 7);
  2. Create a task the fills the buffer one byte at a time.
void producer_task( void *param) {
        char data='0';
        while(1) {
                vTaskDelay(pdMS_TO_TICKS(1000));
                xStreamBufferSend(stream_buf, &data, 1, portMAX_DELAY);
                data = (data=='9')?'0':data+1;
        }
}
  1. Create a task that repeatedly calls xStreamBufferReceive() to drain the buffer up to N bytes at a time; when empty it will block.
        uint8_t buf[5];
        unsigned num_bytes;
        while(1){
                num_bytes=xStreamBufferReceive(stream_buf,buf,4,portMAX_DELAY);
                buf[num_bytes]=0;
                printf("%d Bytes Received %s\n",num_bytes,buf);
        }
}
  1. The receiving task wakes up when the buffer reaches xTriggerLevelBytes bytes, returning 0 bytes zero bytes. On the next call, xStreamBufferReceive will blocks again because the buffered bytes do not exceed the threshold.
0 Bytes Received 
4 Bytes Received 0123
0 Bytes Received 
4 Bytes Received 4567

Expected behavior
For batching stream buffers, xStreamBufferReceive() should not unblock the task until the number of bytes in the buffer exceeds xTriggerLevelBytes, which would eliminate waking up the task and returning zero bytes.

Screenshots
n/a

Additional context
The relevant code begins at line 921 of stream_buffers.c in function xStreamBufferSend

        /* Was a task waiting for the data? */
        if( prvBytesInBuffer( pxStreamBuffer ) >= pxStreamBuffer->xTriggerLevelBytes )
        {
            prvSEND_COMPLETED( pxStreamBuffer );
        }
        else
        {
            mtCOVERAGE_TEST_MARKER();
        }

and can be fixed with

        if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_BATCHING_BUFFER ) != ( uint8_t ) 0 )
        {
                if( prvBytesInBuffer( pxStreamBuffer ) > pxStreamBuffer->xTriggerLevelBytes )
                {
                    prvSEND_COMPLETED( pxStreamBuffer );
                }
                {
                    mtCOVERAGE_TEST_MARKER();
                }
        }
        else
        {
                if( prvBytesInBuffer( pxStreamBuffer ) >= pxStreamBuffer->xTriggerLevelBytes )
                {
                    prvSEND_COMPLETED( pxStreamBuffer );
                }
                else
                {
                    mtCOVERAGE_TEST_MARKER();
                }
        }

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions