目录
2、函数xSemaphoreCreateMutexStatic()
1、函数xSemaphoreCreateRecursiveMutex()
2、函数xSemaphoreCreateRecursiveMutexStatic()
一、为应对优先级翻转而产生的互斥信号量
(1)什么是优先级翻转?
在使用二值信号量的时候会遇到很常见的一个问题——优先级翻转,优先级翻转在可剥夺 内核中是非常常见的,在实时系统中不允许出现这种现象,这样会破坏任务的预期顺序,可能 会导致严重的后果,下图就是一个优先级翻转的例子。
(1) 任务 H 和任务 M 处于挂起状态,等待某一事件的发生,任务 L 正在运行。
(2) 某一时刻任务 L 想要访问共享资源,在此之前它必须先获得对应该资源的信号量。
(3) 任务 L 获得信号量并开始使用该共享资源。
(4) 由于任务 H 优先级高,它等待的事件发生后便剥夺了任务 L 的 CPU 使用权。
(5) 任务 H 开始运行。
(6) 任务 H 运行过程中也要使用任务 L 正在使用着的资源,由于该资源的信号量还被任务 L 占用着,任务 H 只能进入挂起状态,等待任务 L 释放该信号量。
(7) 任务 L 继续运行。
(8) 由于任务 M 的优先级高于任务 L,当任务 M 等待的事件发生后,任务 M 剥夺了任务 L 的 CPU 使用权。
(9) 任务 M 处理该处理的事。
(10) 任务 M 执行完毕后,将 CPU 使用权归还给任务 L。
(11) 任务 L 继续运行。
(12) 最终任务 L 完成所有的工作并释放了信号量,到此为止,由于实时内核知道有个高 优先级的任务在等待这个信号量,故内核做任务切换。
(13) 任务 H 得到该信号量并接着运行。
在这种情况下,任务 H 的优先级实际上降到了任务 L 的优先级水平。因为任务H要一直 等待直到任务 L 释放其占用的那个共享资源。由于任务 M 剥夺了任务 L 的CPU使用权,使得任务 H 的情况更加恶化,这样就相当于任务 M 的优先级高于任务 H,导致优先级翻转。
因为有这样的情况,所以FreeRTOS中设置了互斥信号量!
(2)什么是互斥信号量?
互斥信号量其实就是一个拥有优先级继承的二值信号量,在同步的应用中(任务与任务或中 断与任务之间的同步)二值信号量最适合。互斥信号量适合用于那些需要互斥访问的应用中。在互斥访问中互斥信号量相当于一个钥匙,当任务想要使用资源的时候就必须先获得这个钥匙, 当使用完资源以后就必须归还这个钥匙,这样其他的任务就可以拿着这个钥匙去使用资源。
互斥信号量使用和二值信号量相同的 API 操作函数,所以互斥信号量也可以设置阻塞时间, 不同于二值信号量的是互斥信号量具有优先级继承的特性。当一个互斥信号量正在被一个低优先级的任务使用,而此时有个高优先级的任务也尝试获取这个互斥信号量的话就会被阻塞。不过这个高优先级的任务会将低优先级任务的优先级提升到与自己相同的优先级,这个过程就是优先级继承。优先级继承尽可能的降低了高优先级任务处于阻塞态的时间,并且将已经出现的“优先级翻转”的影响降到最低。
优先级继承并不能完全的消除优先级翻转,它只是尽可能的降低优先级翻转带来的影响。 硬实时应用应该在设计之初就要避免优先级翻转的发生。互斥信号量不能用于中断服务函数中, 原因如下:
● 互斥信号量有优先级继承的机制,所以只能用在任务中,不能用于中断服务函数。
● 中断服务函数中不能因为要等待互斥信号量而设置阻塞时间进入阻塞态。
1.创建互斥信号量
FreeRTOS 提供了两个互斥信号量创建函数,如表
1、函数xSemaphoreCreateMutex()
此函数用于创建一个互斥信号量,所需要的内存通过动态内存管理方法分配。此函数本质是一个宏,真正完成信号量创建的是函数 xQueueCreateMutex(),此函数原型如下:
SemaphoreHandle_t xSemaphoreCreateMutex( void )
参数:
无。
返回值:
NULL: 互斥信号量创建失败。
其他值: 创建成功的互斥信号量的句柄。
创建互斥信号量的过程
2、函数xSemaphoreCreateMutexStatic()
此函数也是创建互斥信号量的,只不过使用此函数创建互斥信号量的话信号量所需要的 RAM 需要由用户来分配,此函数是个宏,具体创建过程是通过函数 xQueueCreateMutexStatic() 来完成的,函数原型如下:
SemaphoreHandle_t xSemaphoreCreateMutexStatic(StaticSemaphore_t *pxMutexBuffer )
参数:
pxMutexBuffer:此参数指向一个 StaticSemaphore_t 类型的变量,用来保存信号量结构体。
返回值:
NULL: 互斥信号量创建失败。
其他值: 创建成功的互斥信号量的句柄。
2. 释放互斥信号量
释放互斥信号量的时候和二值信号量、计数型信号量一样,都是