互斥量
互斥信号量其实就是一个拥有优先级继承的二值信号量,在同步的应用中(任务与任务或中断与任务之间的同步)二值信号量最适合。互斥信号量适合用于那些需要互斥访问的应用中。在互斥访问中互斥信号量相当于一个钥匙,当任务想要使用资源的时候就必须先获得这个钥匙,当使用完资源以后就必须归还这个钥匙,这样其他的任务就可以拿着这个钥匙去使用资源。
互斥信号量的优先继承机制
互斥信号量为什么能实现优先继承?
在FreeRTOS中,为了降低优先级翻转的问题,利用了优先级翻转的算法,优先级翻转的算法实际上是:暂时提高某个占用某种资源的低优先级任务。
优先级翻转的意思就是高优先级的任务也得等待低优先级的任务执行完成后,再去执行 (正常高优先级任务应该比低优先级任务能抢占资源)
(理解一下面这句话)
将低优先级任务的优先级 提高到 与所有等待资源的任务中 优先级最高的任务的优先级 相同。
当这个低优先级的任务释放这个资源后,它的优先级又会恢复到原本的优先级
优先级翻转的危害:
假设有三个任务 H M L 优先级为H>M>L
一般优先级高的都是紧急任务,当有一个资源,L正在使用,此时H也要使用这个资源,但是由于L正在使用,所以H只能进入阻塞状态,等待L使用完,但是,此时M任务被触发了,由于M的优先级比L高,所以L会进入阻塞状态,等待M运行完,才会去运行L,等待L运行完,释放这个资源,H才可以去运行。
在这个过程中,H阻塞的时间为M和L运行的时间,如果中间的任务很多,阻塞的时间就会更长,紧急任务H就无法得到处理,导致系统紊乱。
因此优先级翻转的算法:将正在占用某个资源的任务的优先级提高到与所有等待资源的任务中 优先级最高的任务的优先级 相同。
互斥量应用场景
互斥量更适合于:
●可能会引起优先级翻转的情况
递归互斥量更适用于:
●任务可能会多次获取互斥量的情况下。这样可以避免同一任务多次递归持有而造成死锁的问题。
控制块函数(查看消息队列控制块)
互斥量API函数
在使用互斥量函数的时候,需要在Config文件中将互斥量的宏定义(configUSE_MUTEXES)打开,以及动态分配内存()的定义打开。
互斥量创建函数 xSemaphoreCreateMutex()
递归互斥量创建函数 xSemaphoreCreateRecursiveMutex()
互斥量删除函数 vSemaphoreDelete()
互斥量获取函数 xSemaphoreTake()
递归互斥量获取函数 xSemaphoreTakeRecursive()
互斥量释放函数 xSemaphoreGive()
递归互斥量释放函数 xSemaphoreGiveRecursive()
- 创建函数
互斥量创建函数 xSemaphoreCreateMutex
递归互斥量创建函数 xSemaphoreCreateRecursiveMutex()
使用动态创建函数,需要将FreeRTOS配置文件中的动态内存分配打开。
- 删除函数
- 获取函数
互斥量获取函数 xSemaphoreTake()
递归互斥量获取函数 xSemaphoreTakeRecursive()
- 释放函数
互斥量释放函数 xSemaphoreGive()
递归互斥量释放函数 xSemaphoreGiveRecursive()