freeRTOS使用方法 freertos从入门到精通( 二 )


计数信号量与二值信号量的不同在于 , 二值信号量只能被一个地方申请使用 , 只有在这个申请使用的地方了释放了才能被其他处申请使用 。而计数信号量是可以创建一定数量的信号量的 , 多个地方可以同时申请使用 , 直到达到最大的计数信号量的阈值 。
计数信号量相关的API函数:
(1)创建计数信号量
SemaphoreHandle_t xSemaphoreCreateCounting( UBaseType_t uxMaxCount, /* 支持的最大计数值 */ UBaseType_t uxInitialCount); /* 初始计数值 */参数说明:
uxMaxCount:设置此计数信号量支持的最大计数值 。uxInitialCount:设置计数信号量的初始值 。(为0则不起作用)返回值:如果创建成功会返回消息队列的句柄 , 创建失败会返回 NULL 。
(2)获取信号量
1)在任务代码中获取信号量
xSemaphoreTake( SemaphoreHandle_t xSemaphore, /* 信号量句柄 */ TickType_t xTicksToWait ); /* 等待信号量可用的最大等待时间 */说明:函数 xSemaphoreTake 用于在任务代码中获取信号量 。
xSemaphore:是信号量句柄 。xTicksToWait:是没有信号量可用时 , 等待信号量可用的最大等待时间 , 单位系统时钟节拍 。返回值:如果信号量获取成功会返回 pdTRUE , 否则返回 pdFALSE 。2)在中断中获取信号量
xSemaphoreTakeFromISR( xSemaphore, pxHigherPriorityTaskWoken )函数描述:函数 xSemaphoreTakeFromISR 用于在中断中获取信号量 。
xSemaphore:是要获取的信号量的句柄 。这是创建信号量时返回的句柄 。pxHigherPriorityTaskWoken:是如果采用信号量导致任务取消阻止 , 并且未阻止的任务的优先级高于当前运行的任务 , 则xSemaphoreTakeFromISR()会将pxHigherPriorityTaskWoken设置为pdTRUE 。如果xSemaphoreTakeFromISR()将此值设置为pdTRUE , 则应在退出中断之前请求上下文切换 。返回值:如果创建成功会获取信号量返回 pdTRUE , 否则返回 pdFALSE 。
(3)释放信号量
1)在任务代码中释放信号量
xSemaphoreGive( SemaphoreHandle_t xSemaphore ); /* 信号量句柄 */函数 xSemaphoreGive 用于在任务代码中释放信号量 。
【freeRTOS使用方法 freertos从入门到精通】xSemaphore:是信号量句柄 。返回值:如果信号量释放成功返回 pdTRUE , 否则返回 pdFALSE , 因为计数信号量的实现是基于消息队列 , 返回失败的主要原因是消息队列已经满了 。2)在中断中释放信号量
xSemaphoreGiveFromISR( SemaphoreHandle_t xSemaphore, /* 信号量句柄 */ signed BaseType_t *pxHigherPriorityTaskWoken /* 高优先级任务是否被唤醒的状态保存 */ )xSemaphore:是信号量句柄 。pxHigherPriorityTaskWoken:用于保存是否有高优先级任务准备就绪 。如果函数执行完毕后 , 此参数的数值是pdTRUE , 说明有高优先级任务要执行 , 否则没有 。返回值:如果信号量释放成功返回 pdTRUE , 否则返回 errQUEUE_FULL 。
3、优先级反转 & 互斥信号量在实时操作系统中 , 优先级反转的问题是不容忽视的 , 程序设计的过程中 , 也是要充分考虑这个问题的 。
那优先级反转到底是什么呢?
优先反转是指:
假如一个系统中有高(H)、中(M)、低(L)三个优先级的任务 , 并有一个二值信号量 。在某一个时刻二值信号量被低(L)优先级的任务使用了 , 并在运行过程中 , 高优先级任务(H)抢占了低优先级(L)的CPU使用权 , 但是也想要获取二值信号量被低优先(L)的任务占有着 , 高优先级任务(H)由此被挂起等待了 , 中优先级任务(M)因为不需要二值信号量 , 会抢占低优先级(L)任务的执行而得到运行 , 而高优先级任务(H)依然只能等到低优先级任务(L)释放二值信号量才能得到执行 。
由此造成了高优先级任务得不到及时的执行 , 而低优先级任务却能比高优先级任务更多的得到执行 。这就是优先级反转 。
优先级互斥的示意图如下:

freeRTOS使用方法 freertos从入门到精通

文章插图
freeRTOS使用方法 freertos从入门到精通

文章插图

解决优先级反转的问题最好的办法是使用互斥信号量 。

推荐阅读