我们都知道队列可以进行消息的管理,比如在一个task中发消息,另一个task监听队列中是否有消息,这样比读flag的效率要高很多,更好的利用资源。
一、介绍一下接下来需要使用到的接口函数:
创建队列:使用的是xQueueCreate(uxQueueLength, uxItemSize)
@para1(参数1) uxQueueLength是队列长度(应该叫做队列元素个数items number),
@para2(参数2) uxItemSize元素的大小,一般直接填写sizeof(Type)。
@return 它会返回一个QueueHandle_t 类型的句柄, 如果句柄为NULL 说明创建失败。
发送消息:xQueueSend(xQueue, pvItemToQueue, xTicksToWait)
@para xQueue队列的句柄,pvItemToQueue 消息的指针(也就是变量地址),xTicksToWait 等待时间
如果超过了等待时间就会往下执行,单位是Tick。为什么会等待?因为有可能队列满了需要等
@return 0失败 1成功
接收消息:xQueueReceive(xQueue, pvBuffer, xTicksToWait)
@para xQueue队列的句柄,pvBuffer 接收消息的指针(也就是变量地址),xTicksToWait 等待时间
如果超过了等待时间就会往下执行,单位是Tick。为什么会等待?因为有可能队列是空的
@return 0失败 1成功
创建队列集合:QueueSetHandle_t xQueueCreateSet(const UBaseType_t uxEventQueueLength)
@para uxEventQueueLength 时间的长度(也就是个数,简单了讲就是这个集合放多个队列)
@return 0失败 非0 成功 返回集合的handle(我比较喜欢说为指针或者地址)
将队列添加到集合:BaseType_t xQueueAddToSet(QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet)
@para xQueueOrSemaphore队列句柄,xQueueSet队列集合句柄
@return 0失败 1成功
从集合中取出队列:QueueSetMemberHandle_t xQueueSelectFromSet(QueueSetHandle_t xQueueSet, TickType_t const xTicksToWait)
类似Linux的selec 但是它遍历的方式是交叉遍历和线性遍历,肯定是,没有linux epoll高效,如果是中断中取出的话得用xQueueSelectFromSetFromISR
@para xQueueSet 集合的句柄,xTicksToWait等待时间
@return 0失败 其它返回有效队列句柄
二、具体流程
/*1.创建两个队列*/
/*2.创建一个队列集合*/
/*3.将队列放入队列集合*/
/*4.第三个task 读取队列集合*/
代码如下:
/******************************************/
QueueHandle_t Qhandle1,Qhandle2;
QueueSetHandle_t QueueSet;
static int SunFlag = 0;
unsigned int sun = 0;
void Task1Function()
{
volatile int i = 0;
while(1)
{
i++;
xQueueSend(Qhandle1,&i, portMAX_DELAY);
vTaskDelay(100);
}
}
void Task2Function()
{
int j = 0;
while(1)
{
j--;
xQueueSend(Qhandle2, &j, portMAX_DELAY);
vTaskDelay(200);
}
}
void Task3Function()
{
int temp;
QueueSetMemberHandle_t handle;
while(1)
{
handle = xQueueSelectFromSet(QueueSet, portMAX_DELAY);
xQueueReceive(handle, &temp, 0);
printf("set read :%d\n", temp);
}
}
/*************************************************/
void myTask()
{
printf("EEEENNNNNNNNN\n");
/*1.创建两个队列*/
Qhandle1 = xQueueCreate(2, sizeof(int));
if(Qhandle1 == NULL )
{
printf("Q1 Create Fail \n");
}
Qhandle2 = xQueueCreate(2, sizeof(int));
if(Qhandle2 == NULL )
{
printf("Q2 Create Fail \n");
}
/*2.创建一个队列集合*/ //可以存放3个队列
QueueSet = xQueueCreateSet(3);
/*3.将队列放入队列集合*/
xQueueAddToSet(Qhandle1, QueueSet);
xQueueAddToSet(Qhandle2, QueueSet);
/*4.第三个task 读取队列集合*/
xTaskCreate(Task1Function, "task1", 100, NULL, 19, NULL);//statc para handle
xTaskCreate(Task2Function, "task2", 100, NULL, 19, NULL);
xTaskCreate(Task3Function, "task3", 100, NULL, 19, NULL);
}
三、效果
set read :3
set read :-2
set read :4
set read :5
set read :-3
set read :6
set read :7
set read :-4
set read :8
set read :9
set read :-5
set read :10
set read :11
set read :-6
set read :12
set read :13
set read :-7
set read :14
set read :15
set read :-8
set read :16
set read :17
set read :-9
set read :18
set read :19
set read :-10
set read :20
set read :21
set read :-11
set read :22
set read :23
set read :-12
set read :24
set read :25
set read :-13
set read :26
set read :27
set read :-14
可以看出一个周期里task1 写入两次task2写入一次。