首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

FreeRTOS任务间通讯(2)

FreeRTOS任务间通讯(2)

二进制信号灯
二进制信号灯同时用于互斥和同步的目的。
二进制信号灯和互斥非常相似,但是有一些细微的不同:互斥包括优先级继承机制,而二级制信号没有。这使得二进制信号灯用于同步更方便 (在任务之间或任务与中断之间),而互斥用在简单的互相排斥更好。在怎样用互斥作为互相排斥的机制中 说明 二进制信号灯用法,这个子章节只说明使用二进制信号灯进行同步。

信号灯 API 函数可以指定阻塞的时间。阻塞时间代表任务因为等待获取信号灯而进入阻塞状态的最大'节拍'数。如果超过一个以上的任务因为同一个信号灯被阻塞,那么在信号灯可以使用时高优先级的任务先解除阻塞。

将一个二进制信号灯看作为队列,它只能保存一个项目,这个队列只能是空的或者是满的 (二进制)。使用队列的任务和中断不关心队列保存了什么 - 它们只关系队列是空的还是满的。这个机制可以用于同步任务和中断。

考虑这样一个情况,任务使用一个外设,轮询外设将浪费 CPU 资源,并阻止了其他任务的运行。因此最好是任务将大部分时间用于阻塞状态 (允许其他任务运行),只有真正需要操作时才去轮询。这就是在 '试图' 获得信号时使用二进制信号灯进行任务阻塞,而一个中断服务程序用于外设,当需要使用外设时 '给出' 信号。任务总是 '获取' 信号 (从队列读取直到队列为空),但是从不 '给出'。中断服务程序总是 '给出' 信号 (写入队列直到队列变满) 而从不获取。 xSemaphoreGiveFromISR() 源代码的文档中清楚的解释了这个方法。

可以使用任务的优先级保证及时的外设服务 - 有效的产生 '不同的中断' 方式。另外一种方法是使用队列代替信号,在中断服务程序中捕捉外设的数据并通过队列发送给任务。当队列的数据可以使用后任务解除阻塞,从队列读取数据后,进行数据处理。第二种方法允许中断程序尽可能的短,通过 post 处理而不是发生在一个任务中。

参考用户文档的 信号灯/互斥 小节中关于信号灯的 API 函数。搜索 FreeRTOS/Demo/Common/Minimal 文件夹下的文件可以获得很多这种用法的例子。注意中断里不能使用不是以 "FromISR" 结束的 API 函数。



   
使用信号灯同步任务和中断。中断只 '给出' 信号,而任务只 '获取' 信号。
继承事业,薪火相传
返回列表