信号量1. 二值信号量1.1 二值信号量运作机制1.2 计数信号量运作机制2. 信号量控制块 Queue_t3. 常用函数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_t3. 常用函数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_FULL3.3.2 信号量释放中断 xSemaphoreGiveFromISR()用于释放一个信号量带中断保护。它不能释放互斥量这是因为互斥量不可以在中断中使用互斥量的优先级继承机制只能在任务中起作用而在中断中毫无意义。如果可用信号量未满控制块结构体成员uxMessageWaiting 就会加 1然后判断是否有阻塞的任务如果有的话就会恢复阻塞的任务然后返回成功信息pdPASS如果恢复的任务优先级比当前任务优先级高那么在退出中断要进行任务切换一次如果信号量满则返回错误代码err_QUEUE_FULL表示信号量满3.4 信号量获取3.4.1 信号量获取任务 xSemaphoreTake()如果有可用信号量控制块结构体成员 uxMessageWaiting 就会减 1然后返回获取成功信息pdPASS如果信号量无效并且阻塞时间为0则返回错误代码errQUEUE_EMPTY如果信号量无效并且用户指定了阻塞时间则任务会因为等待信号量而进入阻塞状态任务会被挂接到延时列表中。3.4.2 信号量获取中断 xSemaphoreTakeFromISR()