FreeRTOS队列集:原理、应用与避坑指南
1. 问题背景
在编写日益复杂的嵌入式应用程序时,有时需要从一个特定任务中阻塞多个FreeRTOS资源。例如,要编写一个程序,通过三个按钮获取GPIO输入,按钮按下时LED熄灭,释放时LED点亮,同时触发一些游戏事件。由于这是用于游戏,多个按钮可以同时按下。为了尽可能对按钮事件做出响应,将使用中断来检测GPIO信号的变化。
最初,可能会分配一个队列来发布所有按钮事件,但按钮触点可能会产生抖动,特别是金属触点的按钮。当游戏玩家想从另一个按钮激活智能炸弹时,单个队列可能会被一个按钮的抖动事件填满。由于ISR(中断服务程序)会将按钮事件排队,当队列满时事件将丢失(因为ISR在队列满时不能阻塞)。
为了避免队列因另一个按钮的抖动而变满,决定为每个按钮分配一个单独的消息队列。这样,如果某个有问题的按钮抖动过多,只会丢失该按钮的事件。但现在面临一个新问题,输入事件处理任务是一个单一任务,理想情况下,在循环开始时,该任务应阻塞,直到从这三个队列中的任何一个接收到事件。然而, xQueueReceive() 调用一次只能从一个队列接收数据。作为一种变通方法,可以对所有三个队列进行零超时轮询,但之后如果没有更多要处理的内容,希望暂停执行,以便为游戏代码的其余部分留出更多CPU时间。
2. 队列集的引入
为了解决在多个队列上阻塞的问题,FreeRTOS提供了队列集。首先要创建一个队列集资源,返回一个队列集句柄:
QueueSetHandle_t qsh;
qsh = xQueueCreateSet(const
超级会员免费看
订阅专栏 解锁全文
2176

被折叠的 条评论
为什么被折叠?



