信号量
- 1. 二值信号量
- 1.1 二值信号量运作机制
- 1.2 计数信号量运作机制
- 2. 信号量控制块 Queue_t
- 3. 常用函数
- 3.1 创建信号量
- 3.1.1 创建二值信号量 xSemaphoreCreateBinary()
- 3.1.2 创建计数信号量 xSemaphoreCreateCounting()
- 3.2 信号量删除 vSemaphoreDelete()
- 3.3 信号量释放
- 3.3.1 信号量释放(任务) xSemaphoreGive()
- 3.3.2 信号量释放(中断) xSemaphoreGiveFromISR()
- 3.4 信号量获取
- 3.4.1 信号量获取(任务) xSemaphoreTake()
- 3.4.2 信号量获取(中断) xSemaphoreTakeFromISR()
二值信号量:用于临界资源访问也可以用于同步功能计数信号量:用于事件计数与资源管理互斥信号量:用于保护临界资源( 特殊的二值信号量,其特有的优先级继承机制 )递归信号量:
1. 二值信号量
1.1 二值信号量运作机制
1.2 计数信号量运作机制
计数信号量可以用于资源管理,允许多个任务获取信号量访问共享资源,但会限制任务的最大数目。访问的任务数达到可支持的最大数目时,会阻塞其他试图获取该信号量的任务,直到有任务释放了信号量。这就是计数型信号量的运作机制,虽然计数信号量允许多个任务访问同一个资源,但是也有限定,比如某个资源限定只能有3 个任务访问,那么第 4 个任务访问的时候,会因为获取不到信号量而进入阻塞,等到有任务(比如任务 1)释放掉该资源的时候,第 4 个任务才能获取到信号量从而进行资源的访问
2. 信号量控制块 Queue_t
3. 常用函数
3.1 创建信号量
3.1.1 创建二值信号量 xSemaphoreCreateBinary()
(1)表示信号量的最大可用个数(uxQueueLength = 1 表示创建的队列长度为1)(2)表示创建的消息空间(队列项)大小(semSEMAPHORE_QUEUE_ITEM_LENGTH = 0)(3)表示创建消息队列的类型
3.1.2 创建计数信号量 xSemaphoreCreateCounting()
3.2 信号量删除 vSemaphoreDelete()
删除信号量过程其实就是删除消息队列过程,因为信号量其实就是消息队列,只不过是无法存储消息的队列而已
3.3 信号量释放
3.3.1 信号量释放(任务) xSemaphoreGive()
释放信号量实际上是一次入队操作,并且是不允许入队阻塞,因为阻塞时间为semGIVE_BLOCK_TIME,该宏的值为0
如果信号量未满,控制块结构体成员uxMessageWaiting就会加 1,然后判断是否有阻塞的任务,如果有的话就会恢复阻塞的任务,然后返回成功信息(pdPASS);如果信号量已满,则返回错误代码(err_QUEUE_FULL)
3.3.2 信号量释放(中断) xSemaphoreGiveFromISR()
用于释放一个信号量,带中断保护。它不能释放互斥量,这是因为互斥量不可以在中断中使用,互斥量的优先级继承机制只能在任务中起作用,而在中断中毫无意义。
如果可用信号量未满,控制块结构体成员uxMessageWaiting 就会加 1,然后判断是否有阻塞的任务,如果有的话就会恢复阻塞的任务,然后返回成功信息(pdPASS),如果恢复的任务优先级比当前任务优先级高,那么在退出中断要进行任务切换一次;如果信号量满,则返回错误代码(err_QUEUE_FULL),表示信号量满
3.4 信号量获取
3.4.1 信号量获取(任务) xSemaphoreTake()
如果有可用信号量,控制块结构体成员 uxMessageWaiting 就会减 1,然后返回获取成功信息(pdPASS);
如果信号量无效并且阻塞时间为0,则返回错误代码(errQUEUE_EMPTY);
如果信号量无效并且用户指定了阻塞时间,则任务会因为等待信号量而进入阻塞状态,任务会被挂接到延时列表中。