I2C子系统优先级翻转与优先级继承

描述

优先级翻转与优先级继承

优先级翻转在可剥夺内核中是非常常见的,例子如下(H:High、M:Middle、L:Low)

子系统

任务 H 和任务 M 处于挂起状态,等待某一事件的发生,任务 L 正在运行。

某一时刻任务 L 想要访问共享资源,在此之前它必须先获得对应该资源的信号量。

任务 L 获得信号量并开始使用该共享资源。

由于任务 H 优先级高,它等待的事件发生后便剥夺了任务 L 的 CPU 使用权。

任务 H 开始运行。

任务 H 运行过程中也要使用任务 L 正在使用着的资源,由于该资源的信号量还被任务L 占用着,任务 H 只能进入挂起状态,等待任务 L
释放该信号量。

任务 L 继续运行。

由于任务 M 的优先级高于任务 L,当任务 M 等待的事件发生后,任务 M 剥夺了任务L 的 CPU 使用权。

任务 M 处理该处理的事。

任务 M 执行完毕后,将 CPU 使用权归还给任务 L。

任务 L 继续运行。

最终任务 L 完成所有的工作并释放了信号量,到此为止,由于实时内核知道有个高优先级的任务在等待这个信号量,故内核做任务切换。

任务 H 得到该信号量并接着运行。

在这种情况下,任务 H 的优先级实际上降到了任务 L 的优先级水平。因为任务 H 要一直等待直到任务 L 释放其占用的那个共享资源。由于任务 M剥夺了任务 L 的 CPU 使用权,使得任务 H 的情况更加恶化,这样就相当于任务 M 的优先级高于任务 H,导致优先级翻转。

Linux 用 rt_mutex 来解决该问题,rt_mutex 是带优先级继承的互斥锁。

当一个 rt_mutex 正在被一个低优先级的任务使用,而此时有个高优先级的任务也尝试获取这个 rt_mutex的话就会被阻塞。不过这个高优先级的任务会将低优先级任务的优先级提升到与自己相同的优先级,这就是优先级继承。优先级继承尽可能的降低了高优先级任务处于阻塞态的时间,并且将已经出现的“优先级翻转”的影响降到最低。

优先级继承并不能完全的消除优先级翻转,它只是尽可能的降低优先级翻转带来的影响。

rt_mutex 不能用于中断服务函数中,原因如下:

rt_mutex 有优先级继承的机制,所以只能用在任务中,不能用于中断服务函数。

中断服务函数中不能因为要等待 rt_mutex 而设置阻塞时间进入阻塞态。

在 i2c_transfer 调用 __i2c_transfer 之前,就加了 rt_mutex,保证 I2C 传输尽快执行。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分