计数_二值_互斥信号量

计数型信号量:用于资源的管理,允许多个任务获取信号量访问共享资源,会限制任务的数目,

访问的任务数达到可支持的最大数目时,会阻塞其他试图获取该信号量的任务,直到有任务释放
了信号量。(一个任务控制另一个任务的次数)
比如某个资源限定只能有3个任务访问,那么第4个任务访问的时候,会因为获取不到信号量
而进入阻塞,等到有任务(比如任务1)释放掉该资源的时候,第4个任务才能获取到信号量从而进行资源的访问。(能够控制任务的执行次数)。
创建计数型信号量
SemaphoreHandle_t xSemaphoreCreateCounting( UBaseType_t uxMaxCount,
                                            UBaseType_t uxInitialCount);

创建计数信号量 并返回句柄,通过该句柄可以引用新创建的信号量。

参数:

uxMaxCount  可以达到的最大计数值。 当信号量达到此值时,它不能再被“给定”。
uxInitialCount  创建信号量时分配给信号量的计数值。

返回:

如果已成功创建信号量,则将返回该信号量的句柄 。 如果因为保留信号量所需的RAM 无法分配而无法创建信号量, 则会返回 NULL。

释放信号量

xSemaphoreGive( SemaphoreHandle_t xSemaphore );

xSemaphoreGive()是一个用于释放信号量的宏,真正的实现过程是调用消息队列通用发送函数。释
放的信号量对象必须是已经被创建的,可以用于二值信号量、计数信号量、互斥量的释放,但不能释
放由函数xSemaphoreCreateRecursiveMutex()创建的递归互斥量。此外该函数不能在中断中使用。

参数:

xSemaphore 要释放的信号量的句柄。这是创建信号量时返回的句柄。

返回:

如果信号量释放成功,则返回 pdTRUE;如果发生错误,则返回 pdFALSE。信号量的实现基于队列。发布消息时,如果队列上没有空间,那么可能会发生错误,这表明最初未能正确获取信号量。

接收信号量
xSemaphoreTake( SemaphoreHandle_t xSemaphore, TickType_t xTicksToWait );

xSemaphoreTake()函数用于获取信号量,不带中断保护。获取的信号量对象可以是二 值信号量、
计数信号量和互斥量,但是递归互斥量并不能使用这个 API 函数获取。其实获 取信号量是一个宏,真正调用的函数是 xQueueGenericReceive ()。该宏不能在中断使用, 而是必须由具体中断保护功能 的 xQueueReceiveFromISR()版本代替。

参数:

xSemaphore 正在获取的信号量的句柄——在创建信号量时获得。
xTicksToWait 等待信号量变为可用的时间(以滴答为单位)。宏 portTICK_PERIOD_MS 可用于将其转换为实时。可以用一个为零的阻塞时间来轮询信号量。

如果 INCLUDE_vTaskSuspend 设置为 “1” ,则将阻塞时间指定为 portMAX_DELAY 会导致任务无限期地阻塞(没有超时)。

返回:

如果获得信号量,则返回 pdTRUE;如果 xTicksToWait 过期,信号量不可用,则返回 pdFALSE。

二值型信号量:二值信号量通常用于互斥访问或同步,二值信号量和互斥信号量非常类似,但是还是有一些细微的 差别,互斥信号量拥有优先级继承机制,二值信号量没有优先级继承。因此二值信号另更适合用于同步(任务与任务或任务与中断的同步,即控制任务的执行),而互斥信号量适合用于简单的互斥访问。

创建二值型信号量

SemaphoreHandle_t xSemaphoreCreateBinary( void );

返回值:

NULL  创建信号量失败, 因为 FreeRTOS堆栈 不足。
其它值  信号量已成功创建。 返回 值是一个句柄,通过该句柄可以引用信号量。

信号量是在“空”状态下创建的,这意味着必须先用 xSemaphoreGive() API 函数给出信号量, 然后才能使用 xSemaphoreTake() 函数来获取(获得)该信号量。

优先级翻转:

优先级翻转是当一个高优先级任务通过信号量机制访问共享资源时,该信号量已被一低优先级任务
占有,因此造成高优先级任务被许多具有较低优先级任务阻塞,实时性难以得到保证。

对于二值信号量,当一个较低优先级的任务接收信号量后,在未释放信号量时,一个最高优先级准备就绪,执行最高优先级任务,最低优先级由运行态变为就绪态,与最低优先级公用一个信号量,最低优先级任务没有释放信号量,最高优先级任务进入阻塞态,等待信号量接收,最低优先级变为运行态开始运行,但是在就绪表中较高优先级已经准备就绪,又要运行较高优先级任务,最高优先级不能迅速进行,与操作系统实现不相同。解决方法:

优先级继承:

优先级继承是指将低优先级任务的优先级提升到等待它所
占有的资源的最高优先级任务的优先级。当高优先级任务由于等待资源而被阻塞时,此时 资源的拥有者的优先级将会临时自动被提升 ,以使该任务不被其他任务所打断,从而能尽快的使用完共享资源并释 放,再恢复该任务原来的优先级别。(互斥信号量 ,互斥锁)
互斥信号量:(二值信号量+优先级继承)
互斥量又称互斥信号量(本质是信号量),是一种特殊的二值信号量,它和信号量不同的是,它支持互斥量所有权、递归访问以及防止优先级翻转的特性,用于实现对临界资 源的独占式处理。

 创建互斥型信号量

SemaphoreHandle_t xSemaphoreCreateMutex ( void )
但是使用互斥量的时候一定需要注意:在获得互斥量后,请尽快释放互斥量,同时需要注意的是在任务持有互斥量的这段时间,不得更改任务的优先级。FreeRTOS 的优先级继承机制不能解决优先级反转,只能 将这种情况的影响降低到最小,硬实时系统在一开始设计时就要避免优先级翻转发生。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值