freertos通讯---信号量与队列
哈喽,又见面了.
一.信号量
1.1创建二进制信号量
#define xSemaphoreCreateBinary() xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE )
上篇队列已经提到,信号量也是用队列实现的.这里semSEMAPHORE_QUEUE_ITEM_LENGTH是0,最后一个参数queueQUEUE_TYPE_BINARY_SEMAPHORE其实没有使用.
1.2创建计数信号量
#define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( ( uxMaxCount ), ( uxInitialCount ) )
计数信号量和二进制其实一样
1.3创建互斥锁
#define xSemaphoreCreateMutex() xQueueCreateMutex( queueQUEUE_TYPE_MUTEX )
互斥锁创建稍有不同.其中uxQueueType是一个宏定义,本质上是pchead.用NULL指针来区分信号量和互斥锁.
亲爱的观众朋友们,是不是特别眼熟,不是脸盲(美女我还是认得清楚,哈哈)
这不是就是队列发送的套路吗?
为什么要在这里释放一次了?秘密就在prvCopyDataToQueue函数,来再看一眼
这里我截取了互斥锁的操作.
优先级反转恢复.
互斥锁只能用于任务,中断中不能使用.互斥锁必须获取后再释放.必须形成一个闭环的操作.而信号量不需要,信号量只是单身狗,
注定是要孤独一辈子的.
2.1信号量释放
#define xSemaphoreGive( xSemaphore ) xQueueGenericSend( ( QueueHandle_t ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )
熟悉吗?互斥锁创建时也释放了一次,因为uxMessagesWaiting是0,任务要获取锁成功,所以创建时必须主动释放.
3.2信号量获取
#define xSemaphoreTake( xSemaphore, xBlockTime ) xQueueSemaphoreTake( ( xSemaphore ), ( xBlockTime ) )
哈哈,脸熟,脸盲.
就是多了互斥锁的一些操作,其他和队列的获取基本一致.
来看看互斥锁多了哪些操作
1.首先当前任务pxCurrentTCB->uxMutexesHeld加1.表明当前任务在使用互斥锁了
2.如果阻塞等待,判断是否需要优先级继承.函数xTaskPriorityInherit处理这部分
3.如果获取到互斥锁的任务发生了优先级继承,此时另外一个任务等待超时后,仍然没有获取到锁,那么恢复获取到互斥锁任务的优先级到初始的优先级.
以上就是继承和反继承的代码.逻辑还是很清晰的
4.思考与总结
信号量和互斥量作为任务通讯的方式,由于使用队列实现,效率不高
所以作者推荐使用任务通知的方式实现简单信号量和互斥锁的功能
下一章讲解任务的通知