Stream Buffer: 发送"ABC"+"12345" → 接收方可能一次收到"ABC12" Message Buffer: 发送"ABC"+"12345" → 接收方分两次收到"ABC"和"12345"

Stream Buffer用于在任务或中断之间传输连续字节流,典型用途包括:

  • UART接收数据;
  • 网络字节流;
  • DMA数据流;
  • 连续ADC采样;
  • 音频数据。
  1. Stream Buffer传输连续原始字节。
  2. Stream Buffer不保存Send调用之间的消息边界。
  3. 一次Send可能被拆成多次Receive。
  4. 多次Send也可能被一次Receive合并。
  5. 没有数据时Reader可以进入Blocked。
  6. 高优先级Reader可能在Send内部抢占Writer。
  7. Stream Buffer主要为单Writer、单Reader优化。
  8. 字节流协议需要应用层处理长度、帧头或分隔符。

创建StreamBuffer

static StreamBufferHandle_t xByteStream = NULL;
xByteStream = xStreamBufferCreate(16,1);//缓冲容量:16字节,触发级别:至少1字节

创建发送任务

低优先级

xTaskCreate(vStreamWriterTask,"StreamWriter",configMINIMAL_STACK_SIZE,NULL,1,NULL);
static void vStreamWriterTask(void *pvParameters)
{
    static const char pcFirstChunk[] = "ABC";
    static const char pcSecondChunk[] = "12345";

    (void)pvParameters;

    for (;;)
    {
        //发完第一次,停下来给Reader处理
        xStreamBufferSend(xByteStream,pcFirstChunk,sizeof(pcFirstChunk) - 1U,pdMS_TO_TICKS(100));
        vTaskDelay(pdMS_TO_TICKS(300));

        xStreamBufferSend(xByteStream,pcSecondChunk,sizeof(pcSecondChunk) - 1U,pdMS_TO_TICKS(100));;
        vTaskDelay(pdMS_TO_TICKS(300));
    }
}

创建接收任务

高优先级

xTaskCreate(vStreamReaderTask,"StreamReader",configMINIMAL_STACK_SIZE,NULL,2,NULL);
static void vStreamReaderTask(void *pvParameters)
{
    char pcReceiveBuffer[4 + 1U];//Reader每次最多读取4字节

    (void)pvParameters;

    for (;;)
    {
        xReceived = xStreamBufferReceive(xByteStream,pcReceiveBuffer,READER_CHUNK_BYTES,portMAX_DELAY);//没有数据时一直等待
        pcReceiveBuffer[xReceived] = '\0';
    }
}