在AUTOSAR经典平台中,**Resource(资源)**指多个任务或中断共享的临界资源(如全局变量、外设寄存器等),通过资源管理器实现互斥访问,防止竞态条件。其核心作用包括:
typedef struct {
uint16 saveCount; // 当前资源占用计数(嵌套获取次数)
Os_PriorityType savePrio; // 占用前的任务优先级
Os_LevelType saveLevel; // 占用时的OS级别(任务/中断)
// 时间保护相关字段
Os_TaskType osWhichTaskOccupy;
Os_IsrType osWhichIsrOccupy;
Os_TickType* osTmProtResBgtTask;
Os_TickType* osTmProtResBgtIsr;
TmProtResData osResTpData;
} Os_RCBType;
Os_RCB
数组管理所有资源,索引为ResID
。typedef struct {
uint16 taskResCount; // 已获取资源计数
ResourceType taskResourceStack[CFG_RESOURCE_MAX]; // 资源栈(LIFO顺序)
// 临界区相关字段(与资源释放顺序同步)
uint16 taskCriticalZoneCount;
ObjectType taskCriticalZoneType[CFG_SPINLOCK_MAX];
uint16 taskCriticalZoneStack[CFG_SPINLOCK_MAX];
} Os_TCBType;
typedef struct {
uint16 IsrC2ResCount; // Cat2中断已获取资源计数
ResourceType IsrC2ResourceStack[CFG_RESOURCE_MAX]; // 资源栈
// 临界区相关字段
uint16 isr2CriticalZoneCount;
ObjectType isr2CriticalZoneType[CFG_SPINLOCK_MAX];
uint16 isr2CriticalZoneStack[CFG_SPINLOCK_MAX];
} Os_ICBType;
Os_ResourceCfg
存储每个资源的类型(resourceOccupyType
)和天花板优先级(ceiling
)。P2CONST(uint16*, OS_VAR, OS_CONST) Os_TaskResourceAccessMask; // 任务资源访问掩码
P2CONST(uint16*, OS_VAR, OS_CONST) Os_IsrResourceAccessMask; // 中断资源访问掩码
ResID & 0x0Fu
)验证是否有权限访问资源。Os_InitResource()
FUNC(void, OS_CODE) Os_InitResource(void) {
// 初始化RCB数组
for (resId = 0; resId < Os_CfgStdResourceMax; resId++) {
Os_RCB[resId].saveCount = 0U;
Os_RCB[resId].savePrio = OS_PRIORITY_INVALID;
// 时间保护初始化
#if (TRUE == CFG_TIMING_PROTECTION_ENABLE)
Os_RCB[resId].osWhichTaskOccupy = OS_TASK_INVALID;
for (i = 0U; i < Os_SCB.sysTaskMax; i++) {
Os_RCB[resId].osTmProtResBgtTask[i] = OS_TICK_INVALID;
}
#endif
}
// 多核场景下初始化核心相关配置
vCoreId = Os_SCB.sysCore;
Os_ResourceCfg = Os_ResourceCfg_Inf[vCoreId];
Os_RCB = Os_RCB_Inf[vCoreId];
}
GetResource(ResourceType ResID)
FUNC(StatusType, OS_CODE) GetResource(ResourceType ResID) {
OS_ENTER_KERNEL();
// 核心ID验证、资源ID有效性检查
if (Os_SCB.sysCore != Os_GetObjCoreId(ResID)) return E_OS_CORE;
ResID = Os_GetObjLocalId(ResID); // 转换为本地索引
// 扩展状态下的访问权限检查
#if (OS_STATUS_EXTENDED == CFG_STATUS)
if (Os_RCB[ResID].saveCount > 0U) return E_OS_ACCESS; // 资源已被占用
if (任务/中断无访问权限) return E_OS_ACCESS;
#endif
// 根据资源类型调用具体获取逻辑
return Os_GetResource(ResID);
}
static FUNC(void, OS_CODE) Os_GetResourceByTask(Os_TCBType* pTCB, ResourceType ResID) {
Os_PriorityType prio = Os_ResourceCfg[ResID].ceiling;
// 保存当前优先级并提升至天花板优先级
pTCB->taskRunPrio = (prio > pTCB->taskRunPrio) ? prio : pTCB->taskRunPrio;
// 更新系统最高优先级
if (prio > Os_SCB.sysHighPrio) {
Os_SCB.sysHighPrio = prio;
Os_SCB.sysHighTaskID = Os_SCB.sysRunningTaskID;
}
// 记录资源获取顺序
Os_SaveResourceByTaskOrder(pTCB, ResID);
// 时间保护启动
#if (TRUE == CFG_TIMING_PROTECTION_ENABLE)
Os_TmProtResStart(ResID, TP_RES_OCCUPY_TASK);
#endif
}
OCCUPIED_BY_TASK
等)提升任务优先级至天花板优先级,避免优先级反转。OCCUPIED_BY_TASK_OR_INTERRUPT
类型,通过Os_ArchSetIpl()
屏蔽中断至对应优先级。ReleaseResource(ResourceType ResID)
FUNC(StatusType, OS_CODE) ReleaseResource(ResourceType ResID) {
OS_ENTER_KERNEL();
// 有效性检查(如核心ID、资源ID、调用上下文)
// 转换为本地索引并调用具体释放逻辑
return Os_ReleaseResource(ResID);
}
static FUNC(StatusType, OS_CODE) Os_ReleaseResourceByTask(Os_TCBType* pTCB, ResourceType ResID) {
// 验证释放顺序(栈顶匹配)
#if (CFG_SPINLOCK_MAX > 0U)
if (资源栈顶 != ResID) return E_OS_NOFUNC;
#endif
// 恢复任务优先级
Os_PriorityType savePrio = Os_RCB[ResID].savePrio;
pTCB->taskRunPrio = savePrio;
// 从就绪队列移除当前任务的天花板优先级
Os_ReadyQueueRemove(OS_LEVEL_STANDARD_RESOURCE, prio);
// 弹出资源栈
Os_ResumeResourceByTaskOrder(pTCB, ResID);
// 时间保护结束
#if (TRUE == CFG_TIMING_PROTECTION_ENABLE)
Os_TmProtResEnd(ResID);
#endif
// 重新计算系统最高优先级并触发调度
Os_SCB.sysHighPrio = Os_GetHighPrio();
if (需要调度) Os_Dispatch();
return E_OK;
}
OCCUPIED_BY_TASK_OR_INTERRUPT
类型,恢复中断屏蔽级别。// 启动资源占用计时
#if (TRUE == CFG_TIMING_PROTECTION_ENABLE)
if (任务/中断配置了时间保护) {
Os_TmProtResStart(ResID, TP_RES_OCCUPY_TASK);
}
// 结束计时并检查超时
Os_TmProtResEnd(ResID);
#endif
Os_TmProtResStart
和Os_TmProtResEnd
监控资源占用时间,若超过配置的预算(osTmProtResBgtTask
),触发时间保护错误处理。假设存在两个任务TaskA
和TaskB
,共享资源ResID=0
(类型为OCCUPIED_BY_TASK
,天花板优先级为5)。
// Os_ResourceCfg[0] 配置
{
.resourceOccupyType = OCCUPIED_BY_TASK,
.ceiling = 5, // 天花板优先级
// 其他配置...
}
// 任务访问掩码:允许TaskA和TaskB访问
Os_TaskResourceAccessMask[TaskA_ID][0 >> 4] |= (1u << (0 & 0x0F));
Os_TaskResourceAccessMask[TaskB_ID][0 >> 4] |= (1u << (0 & 0x0F));
TASK(TaskA) {
StatusType err;
// 获取资源
err = GetResource(ResID);
if (err == E_OK) {
// 临界区代码
SharedData = 42;
// 释放资源
ReleaseResource(ResID);
}
TerminateTask();
}
TASK(TaskB) {
StatusType err;
err = GetResource(ResID);
if (err == E_OK) {
// 临界区代码
uint32 temp = SharedData;
ReleaseResource(ResID);
}
TerminateTask();
}
TaskA
调用GetResource
,优先级提升至5,获取资源成功。TaskB
(优先级4)就绪,因TaskA
优先级更高,继续运行。TaskA
释放资源后,优先级恢复为原优先级,系统重新调度,TaskB
获取资源并执行。该资源管理器实现遵循AUTOSAR标准,通过天花板优先级机制解决优先级反转,利用栈结构保证资源获取/释放顺序正确性,并集成时间保护功能满足功能安全需求。核心设计要点包括:
CFG_RESOURCE_MAX
、OS_STATUS_EXTENDED
)支持不同硬件和安全等级配置。Os_RCB_Inf[vCoreId]
),避免跨核心资源冲突。E_OS_ACCESS
、E_OS_NOFUNC
等错误码及Os_TraceErrorHook
提供调试和故障诊断能力。实际应用中,需根据系统需求配置资源类型、天花板优先级及访问掩码,确保临界资源的安全互斥访问。