队列与队列集与解耦:
队列:是 “数据缓冲区”,实现不同任务 / 中断间的异步通信(如红外模块写队列→InputTask读队列解析数据写输入队列、编码器模块写队列→InputTask读队列解析数据写输入数据,应用任务读输入队列执行操作),解耦模块依赖。具体用法:创建队列,往队列放数据,接收队列的数据。
队列集:是 “多队列监听器”,让一个任务能同时等待多个队列,避免创建多个任务分别监听,节省系统资源(任务栈、调度开销)。(在InputTask任务中可以通过轮询方式读驱动队列但是轮询过程中接收队列不可以等待,该InputTask任务一直运行消耗cpu资源。故引入队列集,队列集没有队列句柄时可以阻塞等待,任意一个队列被写入数据后,队列集 会检测到该队列有数据,唤醒 InputTask
执行后续处理。)具体用法:创建队列集,往队列集加队列,读队列集接收到句柄,接收到的句柄(临时变量)与定义队列静态全局句柄比较判断,用静态全局句柄操作队列。
队列集只可以加入空队列,队列加入队列集要在写队列前面
例子:
xQueue = xQueueSelectFromSet(g_xQueueSetInput, portMAX_DELAY);
if (xQueue == g_xQueueIR) {
ProcessIRData(); // 处理红外队列
} else if (xQueue == g_xQueueRotary) {
ProcessRotaryData(); // 处理旋转编码器队列
}
static void ProcessIRData(void) {
struct ir_data idata;
static struct input_data input;
// 用全局句柄 g_xQueueIR 读取队列数据(而非 xQueue)
xQueueReceive(g_xQueueIR, &idata, 0);
// 解析数据、生成控制指令...
// 发送到挡球板队列
xQueueSend(g_xQueuePlatform, &input, 0);
}