目录
1.2.1 函数 xSemaphoreCreateMutex()
1.2.2 函数 xSemaphoreCreateMutexStatic()
1. 互斥信号量
1.1 互斥信号量简介
互斥信号量其实就是一个拥有优先级继承的二值信号量,在同步的应用中(任务与任务或中断与任务之间的同步)二值信号量最适合。互斥信号量适合用于那些需要互斥访问的应用中。在互斥访问中互斥信号量相当于一把钥匙,当任务想要使用资源的时候就必须先获得这个钥匙,当使用完资源以后就必须归还这个钥匙,这样其他的任务就可以拿着这个钥匙去使用资源。
互斥信号量使用和二值信号量相同的 API 操作函数,所以互斥信号量也可以设置阻塞时间,不同于二值信号量的是互斥信号量具有优先级继承的特性。当一个互斥信号量正在被一个低优先级的任务使用,而此时有个高优先级的任务也尝试获取这个互斥信号量的话就会被阻塞。这个高优先级的任务会将低优先级任务的优先级提升到与自己相同的优先级,这个过程就是优先级继承。优先级继承尽可能的降低了高优先级任务处于阻塞态的时间,并且将已经出现的 “优先级翻转” 的影响降到最低。
优先级继承尽可能的降低了高优先级任务处于阻塞态的时间,并且将已经出现的 “优先级翻转” 的影响降到最低。
意思就是说:低优先级的任务获得互斥信号量,此时高优先级的任务无法访问获得互斥信号量,其他中等优先级的任务也无法获得互斥信号量,这样一来,低优先级任务就不能被中等优先级任务所打断,高优先级任务只需要等待低优先级任务释放互斥信号量即可,不用担心被其他的中等任务所打断;这也就是为什么降低高优先级任务处于阻塞态的时间,降低了优先级翻转的可能性!
优先级继承并不能完全的消除优先级翻转,它只是尽可能的降低优先级翻转带来的影响。硬实时应用应该在设计之初就要避免优先级翻转的发生。
互斥信号量不能用于中断服务函数中:
互斥信号量具有优先级继承的机制,只能用在任务中,不能用于中断服务函数。
中断服务函数中不能因为要等待互斥信号量而设置阻塞时间进入阻塞态。
1.2 创建互斥信号量
FreeRTOS提供两个互斥信号量创建函数。
函数:
xSemaphoreCreateMutex() 使用动态方法创建互斥信号量
xSemaphoreCreateMutexStatic() 使用静态方法创建互斥信号量
1.2.1 函数 xSemaphoreCreateMutex()
此函数用于创建一个互斥信号量,所需要的内存通过动态内存管理方法分配。此函数本质是一个宏,真正完成信号量创建的是函数 xQueueCreateMutex(),此函数原型如下:
SemaphoreHandle_t xSemaphoreCreateMutex(void)
参数:
无。
返回值:
NULL:互斥信号量创建失败。
其他值:创建成功的互斥信号量的句柄。
1.2.2 函数 xSemaphoreCreateMutexStatic()
此函数也是创建互斥信号量的,只不过使用此函数创建互斥信号量的话信号量所需要的 RAM 需要由用户来分配,此函数是一个宏,具体创建过程是通过函数 xQueueCreateMutexStatic() 来完成的,函数原型如下:
SemaphoreHandle_t xSemaphoreCreateMutexStatic(StaticSemaphore_t *pxMutexBuffer)
参数:
pxMutexBuffer:此参数指向一个 StaticSemaphore_t 类型的变量,用来保存信号量结构体。
返回值:
NULL:互斥信号量创建失败。
其他值:创建成功的互斥信号量的句柄。
1.2.3 互斥信号量创建过程分析
这里只分析动态创建互斥信号量函数 xSemaphoreCreateMutex(),此函数是个宏,定义如下:
#define xSemaphoreCreateMutex() xQueueCreateMutex(queueQUEUE_TYPE_MUTEX)
可以看出,真正干事的是函数 xQueueCreateMutex(),此函数在文件 queue.c 中有如下定义,
QueueHandle_t xQueueCreateMutex( const uint8_t ucQueueType )
{
Queue_t *pxNewQueue;
const UBaseType_t uxMutexLength = ( UBaseType_t ) 1, uxMutexSize = ( UBaseType_t ) 0;
pxNewQueue = ( Queue_t * ) xQueueGenericCreate( uxMutexLength, uxMutexSize, (1)
ucQueueType );
prvInitialiseMutex( pxNewQueue ); (2)
return pxNewQueue;
}
(1)、调用函数 xQueueGenericCreate() 创建一个队列,队列长度为 1 ,队列项长度为 0 ,队列类

本文围绕FreeRTOS中的互斥信号量展开,介绍其是拥有优先级继承的二值信号量,适用于互斥访问场景。阐述了创建、释放和获取互斥信号量的函数及过程,分析了优先级继承机制以降低优先级翻转影响。还给出互斥信号量操作实验,展示其对系统响应性能的提升。

1465

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



