uxBasePriority“基础优先级”原始值是任务的“出身”轻易不变。uxPriority“当前生效优先级”动态值是调度器实际用来调度的优先级。1.pxQueue-u.xSemaphore.xMutexHolder pvTaskIncrementMutexHeldCount(); 获取持有锁的任务tcb.TaskHandle_t pvTaskIncrementMutexHeldCount( void ){TCB_t * pxTCB;traceENTER_pvTaskIncrementMutexHeldCount();pxTCB pxCurrentTCB;/* If xSemaphoreCreateMutex() is called before any tasks have been created* then pxCurrentTCB will be NULL. */if( pxTCB ! NULL ){( pxTCB-uxMutexesHeld );}traceRETURN_pvTaskIncrementMutexHeldCount( pxTCB );return pxTCB;}( pxTCB-uxMutexesHeld ); 这个变量会累加2.如果设置没有超过超时时间则将任务挂起xInheritanceOccurred xTaskPriorityInherit( pxQueue-u.xSemaphore.xMutexHolder );if( pxMutexHolderTCB-uxPriority pxCurrentTCB-uxPriority ) 如果当前的任务活动线动态值比持有锁的任务的活动线动态值高pxMutexHolderTCB-uxPriority pxCurrentTCB-uxPriority;将当前任务活动线动态值的赋值给持有锁的活动线动态值。如果持有锁的任务不是在就绪列表则把他放到就绪列表里面。xReturn pdTRUE;if( pxMutexHolderTCB-uxBasePriority pxCurrentTCB-uxPriority )如果当前任务的活动线动态值比持有锁任务创建任务的的基础活动线原始值高。xReturn pdTRUE;3.如果设置的超时时间超时将挂起的任务的优先级设置到最高放到就绪列表里面调度。if( xInheritanceOccurred ! pdFALSE ){taskENTER_CRITICAL();{UBaseType_t uxHighestWaitingPriority;/* This task blocking on the mutex caused another* task to inherit this tasks priority. Now this task* has timed out the priority should be disinherited* again, but only as low as the next highest priority* task that is waiting for the same mutex. */uxHighestWaitingPriority prvGetDisinheritPriorityAfterTimeout( pxQueue );/* vTaskPriorityDisinheritAfterTimeout uses the uxHighestWaitingPriority* parameter to index pxReadyTasksLists when adding the task holding* mutex to the ready list for its new priority. Coverity thinks that* it can result in out-of-bounds access which is not true because* uxHighestWaitingPriority, as returned by prvGetDisinheritPriorityAfterTimeout,* is capped at ( configMAX_PRIORITIES - 1 ). *//* coverity[overrun] */vTaskPriorityDisinheritAfterTimeout( pxQueue-u.xSemaphore.xMutexHolder, uxHighestWaitingPriority );}taskEXIT_CRITICAL();}4.xReturn xTaskPriorityDisinherit( pxQueue-u.xSemaphore.xMutexHolder ); 将其加入到就绪列表。( pxTCB-uxMutexesHeld )--;if( pxTCB-uxPriority ! pxTCB-uxBasePriority )如果持有锁的任务的活动线动态值和基础活动线原始值不一致。则会将原始值赋值给当前动态值if( pxTCB-uxMutexesHeld ( UBaseType_t ) 0 ) 减到0 才会将原始值赋值给动态值pxTCB-uxPriority pxTCB-uxBasePriority;listSET_LIST_ITEM_VALUE( ( pxTCB-xEventListItem ), ( TickType_t configMAX_PRIORITIES - ( TickType_t ) pxTCB-uxPriority );prvAddTaskToReadyList( pxTCB );互斥锁是如何保证持有锁的任务只能持有锁的任务释放的。uxMutexesHeld在持有锁的时候1如果xQueueSemaphoreTake里面xTicksToWait的参数是很大的值那么调用这个接口的对应的任务就会挂起。并且和持有锁的任务比较优先级如果设置了超时时候等超时的时间到了调度器会把互斥锁导致的挂起的任务中优先级最高给互斥锁持有者然后放到就绪列表中。保证优先执行。执行xSemaphoreGive时候uxMutexesHeld减1减到0的时候if( pxTCB-uxMutexesHeld ( UBaseType_t ) 0 ) 才会释放 pxQueue-u.xSemaphore.xMutexHolder NULL;
互斥锁 锁继承 反转的机制
发布时间:2026/6/27 20:24:33
uxBasePriority“基础优先级”原始值是任务的“出身”轻易不变。uxPriority“当前生效优先级”动态值是调度器实际用来调度的优先级。1.pxQueue-u.xSemaphore.xMutexHolder pvTaskIncrementMutexHeldCount(); 获取持有锁的任务tcb.TaskHandle_t pvTaskIncrementMutexHeldCount( void ){TCB_t * pxTCB;traceENTER_pvTaskIncrementMutexHeldCount();pxTCB pxCurrentTCB;/* If xSemaphoreCreateMutex() is called before any tasks have been created* then pxCurrentTCB will be NULL. */if( pxTCB ! NULL ){( pxTCB-uxMutexesHeld );}traceRETURN_pvTaskIncrementMutexHeldCount( pxTCB );return pxTCB;}( pxTCB-uxMutexesHeld ); 这个变量会累加2.如果设置没有超过超时时间则将任务挂起xInheritanceOccurred xTaskPriorityInherit( pxQueue-u.xSemaphore.xMutexHolder );if( pxMutexHolderTCB-uxPriority pxCurrentTCB-uxPriority ) 如果当前的任务活动线动态值比持有锁的任务的活动线动态值高pxMutexHolderTCB-uxPriority pxCurrentTCB-uxPriority;将当前任务活动线动态值的赋值给持有锁的活动线动态值。如果持有锁的任务不是在就绪列表则把他放到就绪列表里面。xReturn pdTRUE;if( pxMutexHolderTCB-uxBasePriority pxCurrentTCB-uxPriority )如果当前任务的活动线动态值比持有锁任务创建任务的的基础活动线原始值高。xReturn pdTRUE;3.如果设置的超时时间超时将挂起的任务的优先级设置到最高放到就绪列表里面调度。if( xInheritanceOccurred ! pdFALSE ){taskENTER_CRITICAL();{UBaseType_t uxHighestWaitingPriority;/* This task blocking on the mutex caused another* task to inherit this tasks priority. Now this task* has timed out the priority should be disinherited* again, but only as low as the next highest priority* task that is waiting for the same mutex. */uxHighestWaitingPriority prvGetDisinheritPriorityAfterTimeout( pxQueue );/* vTaskPriorityDisinheritAfterTimeout uses the uxHighestWaitingPriority* parameter to index pxReadyTasksLists when adding the task holding* mutex to the ready list for its new priority. Coverity thinks that* it can result in out-of-bounds access which is not true because* uxHighestWaitingPriority, as returned by prvGetDisinheritPriorityAfterTimeout,* is capped at ( configMAX_PRIORITIES - 1 ). *//* coverity[overrun] */vTaskPriorityDisinheritAfterTimeout( pxQueue-u.xSemaphore.xMutexHolder, uxHighestWaitingPriority );}taskEXIT_CRITICAL();}4.xReturn xTaskPriorityDisinherit( pxQueue-u.xSemaphore.xMutexHolder ); 将其加入到就绪列表。( pxTCB-uxMutexesHeld )--;if( pxTCB-uxPriority ! pxTCB-uxBasePriority )如果持有锁的任务的活动线动态值和基础活动线原始值不一致。则会将原始值赋值给当前动态值if( pxTCB-uxMutexesHeld ( UBaseType_t ) 0 ) 减到0 才会将原始值赋值给动态值pxTCB-uxPriority pxTCB-uxBasePriority;listSET_LIST_ITEM_VALUE( ( pxTCB-xEventListItem ), ( TickType_t configMAX_PRIORITIES - ( TickType_t ) pxTCB-uxPriority );prvAddTaskToReadyList( pxTCB );互斥锁是如何保证持有锁的任务只能持有锁的任务释放的。uxMutexesHeld在持有锁的时候1如果xQueueSemaphoreTake里面xTicksToWait的参数是很大的值那么调用这个接口的对应的任务就会挂起。并且和持有锁的任务比较优先级如果设置了超时时候等超时的时间到了调度器会把互斥锁导致的挂起的任务中优先级最高给互斥锁持有者然后放到就绪列表中。保证优先执行。执行xSemaphoreGive时候uxMutexesHeld减1减到0的时候if( pxTCB-uxMutexesHeld ( UBaseType_t ) 0 ) 才会释放 pxQueue-u.xSemaphore.xMutexHolder NULL;