FreeRTOS学习笔记-MessageBuffer
概述
MessageBuffer与StreamBuffer使用基本相同,但有以下2点区别:
- MessageBuffer一次只能接收1条Message,StreamBuffer则根据长度接收
- MessageBuffer在接收缓冲区<1条消息大小时,不会接收,而StreamBuffer则会将数据截断接收
关键函数
#include "freertos/message_buffer.h"
//创建Message_buffer
MessageBufferHandle_t xMessageBufferCreate( size_t xBufferSizeBytes);//buffer 大小
//发送Message_buffer
size_t xMessageBufferSend(
MessageBufferHandle_t xMessageBuffer,//buffer 句柄
const void *pvTxData, //发送数据指针
size_t xDataLengthBytes,//从pvTxData拷贝到Message_buffer的数据量,同时会向buffer写入消息长度,占sizeof(size_t)==4Byte
TickType_t xTicksToWait );//若Message_buffer空间不够则需要等待的时间
//返回值: 正常返回 xDataLengthBytes 否则返回0,表示buffer空间不足
//从Message_buffer中接收数据
size_t xMessageBufferReceive(
MessageBufferHandle_t xMessageBuffer,//buffer 句柄
void *pvRxData,//接收数据指针
size_t xBufferLengthBytes,//设置可以接收消息的最大长度,如果太小不能容纳一条消息,则该消息将不被接收,并返回0。
TickType_t xTicksToWait );//若Message_buffer为空则需要等待的时间
课程示例
StreamBuffer 接收
#include <stdio.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_spi_flash.h"
#include "string.h"
#include "freertos/stream_buffer.h"
StreamBufferHandle_t sbuffer1;
void mytask1(void *pvParameter)
{
size_t send_size;
size_t send_len;
char send_str[50];
for (int i = 0; i < 3; i++)
{
send_len = sprintf(send_str, "Hello World NO%d \n", i);
send_size = xStreamBufferSend(
sbuffer1, // buffer 句柄
(void *)send_str, //发送数据指针
send_len, //从pvTxData拷贝到stream_buffer的数据量
portMAX_DELAY); //若stream_buffer空间不够则需要等待的时间
printf("task1 send len=%d , size = %d \n", send_len, send_size);
}
vTaskDelete(NULL);
}
void mytask2(void *pvParameter)
{
size_t rx_size;
char rx_str[50];
vTaskDelay(pdMS_TO_TICKS(2000));
while (1)
{
memset(rx_str, 0, sizeof(rx_str)); //三个参数分别为:数据指针、初始化值、初始化大小
rx_size = xStreamBufferReceive(
sbuffer1, // buffer 句柄
(void *)rx_str, //接收数据指针
sizeof(rx_str), //接收的字节数
portMAX_DELAY); //若stream_buffer为空则需要等待的时间
printf("task2 rx size = %d , rx str = %s\n", rx_size, rx_str);
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
void app_main(void)
{
sbuffer1 = xStreamBufferCreate(1000, 40);
if (sbuffer1 != NULL)
{
xTaskCreate(mytask1, "mytask1", 1024 * 5, NULL, 1, NULL);
xTaskCreate(mytask2, "mytask2", 1024 * 5, NULL, 1, NULL);
}
}
效果
task1 send len=17 , size = 17
task1 send len=17 , size = 17
task1 send len=17 , size = 17
task2 rx size = 50 , rx str = Hello World NO0
Hello World NO1
Hello World NO2 �?
task2 rx size = 1 , rx str =
修改任务2接收代码,接收数量为10,让一次接收内容小于1次发送内容,效果如下:
task1 send len=17 , size = 17
task1 send len=17 , size = 17
task1 send len=17 , size = 17
task2 rx size = 10 , rx str = Hello Worl
task2 rx size = 10 , rx str = d NO0
Hel
task2 rx size = 10 , rx str = lo World N
task2 rx size = 10 , rx str = O1
Hello
task2 rx size = 10 , rx str = World NO2
task2 rx size = 1 , rx str =
接收内容被截断接收。
MessageBuffer 接收
#include <stdio.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_spi_flash.h"
#include "string.h"
#include "freertos/message_buffer.h"
MessageBufferHandle_t sbuffer1;
void mytask1(void *pvParameter)
{
size_t send_size;
size_t send_len;
char send_str[50];
for (int i = 0; i < 3; i++)
{
send_len = sprintf(send_str, "Hello World NO%d \n", i);
send_size = xMessageBufferSend(
sbuffer1, // buffer 句柄
(void *)send_str, //发送数据指针
send_len, //从pvTxData拷贝到Message_buffer的数据量
portMAX_DELAY); //若Message_buffer空间不够则需要等待的时间
printf("task1 send len=%d , size = %d \n", send_len, send_size);
}
vTaskDelete(NULL);
}
void mytask2(void *pvParameter)
{
size_t rx_size;
char rx_str[50];
vTaskDelay(pdMS_TO_TICKS(2000));
while (1)
{
memset(rx_str, 0, sizeof(rx_str)); //三个参数分别为:数据指针、初始化值、初始化大小
rx_size = xMessageBufferReceive(
sbuffer1, // buffer 句柄
(void *)rx_str, //接收数据指针
sizeof(rx_str), //接收的字节数
portMAX_DELAY); //若Message_buffer为空则需要等待的时间
printf("task2 rx size = %d , rx str = %s\n", rx_size, rx_str);
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
void app_main(void)
{
sbuffer1 = xMessageBufferCreate(1000);
if (sbuffer1 != NULL)
{
xTaskCreate(mytask1, "mytask1", 1024 * 5, NULL, 1, NULL);
xTaskCreate(mytask2, "mytask2", 1024 * 5, NULL, 1, NULL);
}
}
效果:
task1 send len=17 , size = 17
task1 send len=17 , size = 17
task1 send len=17 , size = 17
task2 rx size = 17 , rx str = Hello World NO0
task2 rx size = 17 , rx str = Hello World NO1
task2 rx size = 17 , rx str = Hello World NO2
同样修改任务2接收代码,接收数量为10,让一次接收内容小于1次发送内容,效果如下:
task1 send len=17 , size = 17
task1 send len=17 , size = 17
task1 send len=17 , size = 17
task2 rx size = 0 , rx str =
task2 rx size = 0 , rx str =
task2 rx size = 0 , rx str =
task2 rx size = 0 , rx str =
task2 rx size = 0 , rx str =
task2 rx size = 0 , rx str =
task2 rx size = 0 , rx str =
task2 rx size = 0 , rx str =
任务2一直不能接收到数据,但消息一直存在于buffer中。