队列:先入先出(FIFO,first in first out)
使用方法:
API | 功能 |
---|---|
xQueueCreate() | 创建一个队列 |
xQueueSend() | 往队列里写数据 |
xQueueReceive | 从队列里读数据 |
uxQueueMessagesWaiting(队列句柄) | 返回值为队列中参数的个数,可用于接收数据时,先判断一下队列里是否有数据 |
// 创建一个队列
QueueHandle_t xQueueCreate(UBaseType_t uxQueueLength, UBaseType_t uxItemSize); // API
QueueHandle_t Qhandle = xQueueCreate(5, sizeof(int)); // 创建一个队列,长度为5,每个空间的大小为int
// 发送队列数据API
BaseType_t xQueueSend(
QueueHandle_t xQueue,
const void *pvItemToQueue,
TickType_t xTicksToWait);
// 示例
void send(void *pt)
{
QueueHandle_t Qhandle = (QueueHandle_t)pt; // 进行强制类型转换,转换为队列句柄
BaseType_t xStatus; // 记录数据是否发送成功
char i = 0; // 要发送的数据
while (1)
{
/*参数1:队列的句柄;参数2:要发送的数据; 参数3:超时等待时间*/
xStatus = xQueueSend(Qhandle, &i, 0);
if (xStatus != pdPASS)
{
Serial.println("发送失败");
}
else
Serial.println("发送成功");
i++;
if (i == 8)
i = 0;
vTaskDelay(1000);
}
}
// 接收队列API
BaseType_t xQueueReceive(
QueueHandle_t xQueue,
void *pvBuffer,
TickType_t xTicksToWait);
// 示例
void receive(void *pt)
{
int j = 0; // 接收数据
while (1)
{
if (xQueueReceive(Qhandle, &j, 0) != pdPASS)
{
Serial.println("接收失败");
}
else
{
Serial.print("接收成功:");
Serial.println(j);
}
vTaskDelay(1000);
}
}
#include
// 创建队列全局变量,全局变量
QueueHandle_t Qhandle = xQueueCreate(5, sizeof(int)); // 创建一个队列,长度为5,每个空间的大小为int
void send(void *pt)
{
int i = 0; // 要发送的数据
while (1)
{
/*参数1:队列的句柄;参数2:要发送的数据; 参数3:超时等待时间*/
if (xQueueSend(Qhandle, &i, 0) != pdPASS)
{
Serial.println("发送失败");
}
else
{
Serial.print("发送成功:");
Serial.println(i);
}
i++;
if (i == 8)
i = 0;
vTaskDelay(1000);
}
}
void receive(void *pt)
{
int j = 0; // 接收数据
while (1)
{
if (xQueueReceive(Qhandle, &j, 0) != pdPASS)
{
Serial.println("接收失败:");
}
else
{
Serial.print("接收成功:");
Serial.println(j);
}
vTaskDelay(1000);
}
}
void setup()
{
Serial.begin(9600);
if (Qhandle != NULL)
{
Serial.println("队列创建成功");
xTaskCreatePinnedToCore(send, "", 1024 * 5, NULL, 1, NULL, 1); // 发送数据
xTaskCreatePinnedToCore(receive, "", 1024 * 5, NULL, 1, NULL, 1); // 接收数据
}
else
{
Serial.println("队列创建失败");
}
}
void loop()
{
}
// 声明一个结构体
struct Struct
{
int id;
int a;
};
QueueHandle_t Qhandle = xQueueCreate(5, sizeof(xStruct));
在上个程序的基础上进行创建的队列每个空间的大小#include
struct Struct
{
int id;
int a;
};
// 创建队列全局变量,全局变量
QueueHandle_t Qhandle = xQueueCreate(5, sizeof(Struct)); // 创建一个队列,长度为5,每个空间的大小为int
void send(void *pt)
{
Struct xUSB = {1, 55}; // 要发送的数据
while (1)
{
/*参数1:队列的句柄;参数2:要发送的数据; 参数3:超时等待时间*/
if (xQueueSend(Qhandle, &xUSB, 0) != pdPASS)
{
Serial.println("发送失败");
}
else
{
Serial.println("发送成功");
xUSB.id++;
}
vTaskDelay(1000);
}
}
void receive(void *pt)
{
Struct yUSB; // 定义一个接收结构体
while (1)
{
if (xQueueReceive(Qhandle, &yUSB, 0) != pdPASS)
{
Serial.println("接收失败");
}
else
{
Serial.print("接收成功:");
Serial.println(yUSB.id);
Serial.println(yUSB.a);
}
vTaskDelay(1000);
}
}
void setup()
{
Serial.begin(9600);
if (Qhandle != NULL)
{
Serial.println("队列创建成功");
xTaskCreatePinnedToCore(send, "", 1024 * 5, NULL, 1, NULL, 1); // 发送数据
xTaskCreatePinnedToCore(receive, "", 1024 * 5, NULL, 1, NULL, 1); // 接收数据
}
else
{
Serial.println("队列创建失败");
}
}
void loop()
{
}
运行结果:
发送成功
接收成功:1
55
发送成功
接收成功:2
55
malloc()
函数使用:在使用malloc开辟空间时,使用完一定要释放空间,如果不释放会造成内存泄漏。malloc()
函数返回的实际是一个无类型指针,必须在其前面加上指针类型强制转换才可以使用。指针自身 = (指针类型*)malloc(sizeof(指针类型)*数据数量)
int *p = NULL;
int n = 10;
p = (int *)malloc(sizeof(int)*n);
free()
释放malloc()
函数给指针变量分配的内存空间。注意:使用后该指针变量一定要重新指向NULL,防止野指针(悬空指针、失效指针)出现。int *p = (int *)malloc(sizeof(int));
*p = 100;
free(p);
p = NULL;
多个任务输入一个队列,一个任务读队列中的数据,此时注意设置任务的优先级别,设置写入的任务级别为1(各任务之间轮流发送数据),读任务的优先级别为2。
portMAX_DELAY
一直等待,直到队列中有数据就开始读#include
QueueHandle_t Qhandle = xQueueCreate(5, sizeof(int)); // 创建一个队列,长度为5,每个空间的大小为int
void send1(void *pt)
{
int i = 1; // 任务1要发送的数据
while (1)
{
if (xQueueSend(Qhandle, &i, 0) != pdPASS)
{
Serial.println("发送失败");
}
else
{
Serial.println("发送成功");
}
vTaskDelay(1000);
}
}
void send2(void *pt)
{
int i = 2; // 任务2要发送的数据
while (1)
{
if (xQueueSend(Qhandle, &i, 0) != pdPASS)
{
Serial.println("发送失败");
}
else
{
Serial.println("发送成功");
}
vTaskDelay(1000);
}
}
void receive(void *pt)
{
int i; // 存储接收数据
while (1)
{
if (xQueueReceive(Qhandle, &i, portMAX_DELAY) != pdPASS) // portMAX_DELAY,一直等待,直到队列中有数据。等待时间设置为0,表示队列中如果没有数据,立即返回
{
Serial.println("接收失败");
}
else
{
Serial.print("接收成功:");
Serial.println(i);
}
// vTaskDelay(1000); // 采用了portMAX_DELAY,这里就不需要delay了
}
}
void setup()
{
Serial.begin(9600);
if (Qhandle != NULL)
{
Serial.println("队列创建成功");
xTaskCreatePinnedToCore(send1, "", 1024 * 5, NULL, 1, NULL, 1); // 两个相同的优先级别,轮流发送数据
xTaskCreatePinnedToCore(send2, "", 1024 * 5, NULL, 1, NULL, 1);
xTaskCreatePinnedToCore(receive, "", 1024 * 5, NULL, 2, NULL, 1); // 优先级别2,只要队列中有数据,就读
}
else
{
Serial.println("队列创建失败");
}
}
void loop()
{
}
运行结果:
发送成功
接收成功:2
发送成功
接收成功:1
xQueueCreateSet( const UBaseType_t uxEventQueueLength )
参数为队列集合的总长度/*把队列加入到集合中
参数1:需要加入的队列句柄;参数2:队列集合的句柄*/
BaseType_t xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore,
QueueSetHandle_t xQueueSet );
// 从队列集合中选择有数据的队列
QueueSetMemberHandle_t xQueueSelectFromSet( QueueSetHandle_t xQueueSet,
const TickType_t xTicksToWait );
#include
QueueHandle_t Qhandle1 = xQueueCreate(5, sizeof(int)); // 队列1
QueueHandle_t Qhandle2 = xQueueCreate(5, sizeof(int)); // 队列2
QueueSetHandle_t QueueSet = xQueueCreateSet(10); // 队列集合句柄
xQueueAddToSet(Qhandle1, QueueSet); // 把队列1加入到队列集合中
xQueueAddToSet(Qhandle2, QueueSet); // 把队列2加入到队列集合中
QueueSetMemberHandle_t QueueData = xQueueSelectFromSet(QueueSet, portMAX_DELAY); // 从队列集合中获取有数据的队列
void send1(void *pt)
{
int i = 1; // 任务1要发送的数据
while (1)
{
if (xQueueSend(Qhandle1, &i, 0) != pdPASS)
{
Serial.println("发送失败");
}
else
{
Serial.println("发送成功");
}
vTaskDelay(1000);
}
}
void send2(void *pt)
{
int i = 2; // 任务2要发送的数据
while (1)
{
if (xQueueSend(Qhandle2, &i, 0) != pdPASS)
{
Serial.println("发送失败");
}
else
{
Serial.println("发送成功");
}
vTaskDelay(1000);
}
}
void receive(void *pt)
{
int i; // 存储接收数据
while (1)
{
if (xQueueReceive(QueueData, &i, portMAX_DELAY) != pdPASS) // portMAX_DELAY,一直等待,直到队列中有数据
{
Serial.println("接收失败");
}
else
{
Serial.print("接收成功:");
Serial.println(i);
}
// vTaskDelay(1000); // 采用了portMAX_DELAY,这里就不需要delay了
}
}
void setup()
{
Serial.begin(9600);
Serial.println("队列创建成功");
xTaskCreatePinnedToCore(send1, "", 1024 * 5, NULL, 1, NULL, 1); // 两个相同的优先级别,轮流发送数据
xTaskCreatePinnedToCore(send2, "", 1024 * 5, NULL, 1, NULL, 1);
xTaskCreatePinnedToCore(receive, "", 1024 * 5, NULL, 2, NULL, 1); // 优先级别2,只要队列中有数据,就读
}
void loop()
{
}
BaseType_t xQueueOverwrite( QueueHandle_t xQueue, const void *pvItemToQueue );
往队列邮箱中写入数据// 从队列邮箱中读数据
BaseType_t xQueuePeek( QueueHandle_t xQueue,
void *pvBuffer, TickType_t
xTicksToWait );
#include
QueueHandle_t Mailbox = xQueueCreate(1, sizeof(int));
void send(void *pt)
{
int i = 1; // 任务1要发送的数据
while (1)
{
if (xQueueOverwrite(Mailbox, &i) != pdPASS)
{
Serial.println("发送失败");
}
else
{
Serial.println("发送成功");
i++;
}
vTaskDelay(1000);
}
}
void receive1(void *pt)
{
int i; // 存储接收数据
while (1)
{
if (xQueuePeek(Mailbox, &i, 0) != pdPASS) // portMAX_DELAY,一直等待,直到队列中有数据
{
Serial.println("接收失败");
}
else
{
Serial.print("接收成功:");
Serial.println(i);
}
}
}
void receive2(void *pt)
{
int i; // 存储接收数据
while (1)
{
if (xQueuePeek(Mailbox, &i, 0) != pdPASS) // portMAX_DELAY,一直等待,直到队列中有数据
{
Serial.println("接收失败");
}
else
{
Serial.print("接收成功:");
Serial.println(i);
}
}
}
void setup()
{
Serial.begin(9600);
Serial.println("队列创建成功");
xTaskCreatePinnedToCore(send, "", 1024 * 5, NULL, 1, NULL, 1);
xTaskCreatePinnedToCore(receive1, "", 1024 * 5, NULL, 2, NULL, 1);
xTaskCreatePinnedToCore(receive2, "", 1024 * 5, NULL, 2, NULL, 1);
}
void loop()
{
}