FreeRTOS信号量

二值信号量

vSemaphoreCreateBinary()//创建二值信号量,老版本,调用take会得到
xSemaphoreCreateBinary()//返回handle,需要的内存是自动分配,创建要先give
xSemaphoreCreateBinaryStatic()//静态创建
队列长度为1, 用于任务同步,不用优先级继承机制

发送:Post an item on a queue
xQueueSend()宏 xQueueGenericSend
xSemaphoreGive()释放信号量 xQueueGenericSend 在prvCopyDataToQueue函数中uxMessagesWaiting会加1
xSemaphoreGiveFromISR() //mutex不能使用

获取信号量xSemaphoreTake() xQueueGenericReceive();
xSemaphoreTakeFromISR() mutex不能使用

计数型信号量

xSemaphoreCreateCounting( UBaseType_t uxMaxCount, UBaseType_t uxInitialCount )
主要用于:
1,计数事件:事件发生后,事件handle释放信号量(增加信号量的值),事件处理后,获得信号量(信号量减1),初始化为0!
2,资源管理:计数值表示可用资源的数量,为了获得资源,首先要获得信号量(信号量减1),当到达0时,没有可用资源,
当任务使用完资源后,释放信号量,(信号量加1),初始化值为最大值,表面所有资源是可用的
xSemaphoreCreateCountingStatic()
优先级翻转*
使用二值信号量会存在优先级翻转
中等优先级的任务运行,高优先级的任务等待信号量,挂起,好像中等优先级高于高优先级

互斥信号量

优先级继承,
当低优先级任务使用信号量,高优先级也尝试获取就会阻塞,但高优先级会将低优先级提升到与自己相同的
xSemaphoreCreateMutex()
******************xTaskPriorityDisinherit()//处理优先级继承
任务只有使用信号量,才会有继承优先级,如果mutex由task拿着,mutex不能从中断释放.如果mutex由拿着的任务释放,它必须是运行态的任务。
每释放一次信号量,uxMutexheld减1;
是否存在优先级继承
是否该任务还有其他互斥信号量
从状态列表移除
如果继承来的优先级对应的就绪表中没有其他任务,就取消这个优先级的就绪态
对优先级做处理
复位任务的事件列表项
添加的就绪列表

*****信号量
****binary
vSemaphoreCreateBinary() 长度为1,类型为queueQUEUE_TYPE_BINARY_SEMAPHORE ,item长度为0,发送信号量
xSemaphoreCreateBinary() 不会发送信号量
****计数信号量
xSemaphoreCreateCounting( uxMaxCount, uxInitialCount )
xQueueCreateCountingSemaphore()
{
xQueueGenericCreate( uxMaxCount, queueSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_COUNTING_SEMAPHORE )
(( Queue_t * ) xHandle )->uxMessagesWaiting = uxInitialCount;//赋初值
}
****互斥信号量
#define pxMutexHolder pcTail
#define uxQueueType pcHead
#define queueQUEUE_IS_MUTEX NULL
xSemaphoreCreateMutex() xQueueCreateMutex( queueQUEUE_TYPE_MUTEX )
{
xQueueGenericCreate( uxMutexLength, uxMutexSize, ucQueueType );
prvInitialiseMutex( pxNewQueue );
{
会覆盖一些成员,是为了优先级继承
pxNewQueue->pxMutexHolder = NULL;
pxNewQueue->uxQueueType = queueQUEUE_IS_MUTEX;
会释放一次信号量
}
}
***递归互斥信号量
#define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex( queueQUEUE_TYPE_RECURSIVE_MUTEX )

***释放信号量
#define xSemaphoreGive( xSemaphore ) xQueueGenericSend( ( QueueHandle_t ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )
**获得信号量
#define xSemaphoreTake( xSemaphore, xBlockTime ) xQueueGenericReceive( ( QueueHandle_t ) ( xSemaphore ), NULL, ( xBlockTime ), pdFALSE )

vTaskPriorityInherit( ( void * ) pxQueue->pxMutexHolder );

prvCopyDataToQueue
{
xReturn = xTaskPriorityDisinherit( ( void * ) pxQueue->pxMutexHolder );
pxQueue->pxMutexHolder = NULL;
}

xTaskPriorityDisinherit
{
( pxTCB->uxMutexesHeld )–;//任务可以hold多个信号量
pxTCB->uxPriority != pxTCB->uxBasePriority 持有mutex的是否继承了其他的优先级
{
释放最后一个信号量
释放信号量的任务一定是正在运行的任务
移除就绪列表,且当前优先级没有了其他任务,取消就绪态
重置优先级
复位事件列表项值
优先级恢复后加入到就绪列表

}

}

上一篇:哲学家进餐问题


下一篇:C# 异步锁