天天看点

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的是否继承了其他的优先级

{

释放最后一个信号量

释放信号量的任务一定是正在运行的任务

移除就绪列表,且当前优先级没有了其他任务,取消就绪态

重置优先级

复位事件列表项值

优先级恢复后加入到就绪列表

}
           

}

继续阅读