1. 引言
在实时操作系统(RTOS)中,优先级反转是一个经典问题,它会导致高优先级任务被低优先级任务阻塞,从而破坏系统的实时性。FreeRTOS 通过优先级继承(Priority Inheritance)机制有效缓解这一问题。该机制的核心实现隐藏在互斥量操作的背后:当任务调用 xSemaphoreTake 获取互斥量但因被其他任务占用而阻塞时,内核会自动调用 vTaskPriorityInherit() 提升当前持有者的优先级;而当任务调用 xSemaphoreGive 释放互斥量时,内核则会调用 xTaskPriorityDisinherit() 恢复持有者的原始优先级。这两个函数是优先级继承机制的'幕后工作者',共同协作解决优先级反转问题。
2. 优先级继承机制概述
当多个任务共享一个互斥量时,如果高优先级任务试图获取已被低优先级任务持有的互斥量,高优先级任务将进入阻塞状态。若此时有一个中等优先级的任务就绪,它会抢占 CPU,导致低优先级任务无法释放互斥量,从而间接阻塞高优先级任务,形成优先级反转。
优先级继承的解决思路是:临时提升互斥量持有者的优先级,使其尽快运行并释放资源,之后恢复其原始优先级。FreeRTOS 在任务控制块(TCB)中维护了相关字段:
uxPriority:任务当前优先级(可能因继承而提升)uxBasePriority:任务原始优先级(未继承时的值)uxMutexesHeld:任务当前持有的互斥量数量
3. vTaskPriorityInherit() 源码分析
vTaskPriorityInherit() 在任务试图获取互斥量失败时被调用,用于提升当前互斥量持有者的优先级。其原型如下:
void vTaskPriorityInherit( TaskHandle_t const pxMutexHolder );
参数 pxMutexHolder 为当前持有互斥量的任务句柄。下面逐段解析源码:
3.1 空指针检查与优先级比较
TCB_t * const pxTCB = ( TCB_t * ) pxMutexHolder;
if( pxMutexHolder != NULL ) {
if( pxTCB->uxPriority < pxCurrentTCB->uxPriority ) {
/* ... 继承逻辑 ... */
}
}
首先检查持有者是否为空(可能由于中断归还等情况导致)。然后比较持有者当前优先级与试图获取任务的优先级:仅当持有者优先级低于等待者时,才需要进行继承。
3.2 更新事件列表项
if( ( listGET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ) ) & taskEVENT_LIST_ITEM_VALUE_IN_USE ) == 0UL ) {
listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) pxCurrentTCB->uxPriority );
}
xEventListItem 用于任务在事件列表中的排序,其值通常为 configMAX_PRIORITIES - 任务优先级。此处若该列表项未被占用(高位标记未置位),则将其更新为等待任务优先级的倒序值,以确保在事件等待链中按新优先级正确排序。

