【FreeRTOS】队列集
队列集
队列集内部机制:(句柄简单来说就是对象的指针:句柄详解,什么是句柄?句柄有什么用?-CSDN博客)
在开发板上的实际操作:
创建队列集
QueueSetHandle_t xQueueCreateSet( const UBaseType_t uxEventQueueLength )
把队列加入队列集
BaseType_t xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore,
QueueSetHandle_t xQueueSet );
读取队列集
QueueSetMemberHandle_t xQueueSelectFromSet( QueueSetHandle_t xQueueSet,
TickType_t const xTicksToWait );
同一份数据分发给多个任务(重点)
解决方法:让驱动程序同时写多个队列,然后让不同任务各自读取各自的队列。
第一种方法:(不推荐)
第二种方法:
创建一个队列数组,所有需要分发数据的队列的句柄都被一个注册函数放入该队列数组中,然后由驱动层内部分发函数给数组内所有队列分发数据。
static QueueHandle_t g_xQueues[10];//需要被分发数据的队列的数组,数组内的值来自外部任务调用注册函数,//将自己的队列添加进该数组中,然后驱动层会将数据分发给该数组内所有队列
static int g_queue_cnt = 0;//队列数组成员计数,防止越界void IR_RegisterQueueHandle(QueueHandle_t queueHandle)//注册队列到队列数组
{if (g_queue_cnt < 10){g_xQueues[g_queue_cnt] = queueHandle;g_queue_cnt++;}
}#if 0
void LogoutQueueHandle(QueueHandle_t queueHandle)//将队列从队列数组中注销
{int i = 0;for (i = 0; i < g_queue_cnt; i++){if (g_xQueues[i] == queueHandle){g_xQueues[i] = g_xQueues[g_queue_cnt];g_queue_cnt--;}}
}
#endifstatic void DispatchKey(struct ir_data* pidata)//分发数据
{
#if 0//数据分发,同时写3个队列extern QueueHandle_t g_xQueueCar1; /* 任务队列 */extern QueueHandle_t g_xQueueCar2; /* 任务队列 */extern QueueHandle_t g_xQueueCar3; /* 任务队列 */xQueueSendFromISR(g_xQueueCar1, pidata, NULL);xQueueSendFromISR(g_xQueueCar2, pidata, NULL);xQueueSendFromISR(g_xQueueCar3, pidata, NULL);//可以这么写,但是这样写会让驱动层与应用层耦合性增强//每次增加任务都要在驱动层更改代码,代码太丑陋
#else//分发数据到队列数组int i = 0;for (i = 0; i < g_queue_cnt; i++){xQueueSendToBackFromISR(g_xQueues[i], pidata, NULL);}
#endif
}
当我们有一个任务需要用到数据时,就在该任务内创建一个队列,然后将该队列通过注册函数注册到队列数组中就好了。