【TriCore-OS】Resource
发布时间:2026/8/28 6:46:09 作者:尧图编辑部 阅读量:1,286

文章目录1. Resource 是什么1.1 核心特征1.2 为什么需要Resource1.3 优先级反转问题Resource 解决的核心问题1.4 Priority Ceiling ProtocolPCP本 OS 采用1.5 Resource 的关键数据结构1.6 Resource vs Event vs Spinlock对比1.7 Resource的2个API2. GetResource2.1 GetResource流程图2.2 GetResource调用层级2.3 GetResource状态切换2.4 GetResource调用栈2.5 GetResource2.5.1 Os_Resource_GetResource2.5.1.1 Os_Resource_IncreaseTaskPrio2.5.2 嵌套获取资源的优先级变化3. ReleaseResource3.1 ReleaseResource流程图3.2 ReleaseResource调用层级3.3 ReleaseResource3.4 ReleaseResource3.5 ReleaseResource3.5.1 Os_Resource_ReleaseResource3.5.2 Os_Resource_CheckReleaseOrder3.5.3 Os_Resource_RestoreTaskPrio4. 完整优先级继承时序图1. Resource 是什么Resource资源是 AUTOSAR OS 提供的互斥机制用于保护共享数据结构或临界区避免多个任务/ISR 同时访问造成数据竞争。1.1 核心特征特征说明本质二值信号量0 或 1锁/未锁作用域单核内不能跨核归属属于一个 OS-ApplicationownerAppId类型任务资源isIsrFALSE/ ISR 资源isIsrTRUE阻塞方式不阻塞直接返回错误码获取顺序LIFO栈式必须逆序释放优先级影响提升持锁者优先级优先级继承1.2 为什么需要Resource共享数据竞争问题任务A(低优先级)任务B(高优先级)│ │ │ counter;│ │(读 counter5)│ │ │ │(中断被 B 抢占)│ │ │ counter;│ │(读 counter5,写6)│ │ 返回 │(恢复,写6)│ │ │ ▼ ▼ 最终 counter6(应该是7!)用Resource解决任务A(低优先级)任务B(高优先级)│ │ │GetResource(R_counter)│ │ counter;│ │(读5,写6)│ │ │ │(中断被 B 抢占)│ │ │GetResource(R_counter)│ │(返回 E_OS_ACCESS,锁已被占用)│ │ → 重试或处理错误 │ │ 返回 │ReleaseResource(R)│ │ │ ▼ ▼ 最终 counter7✓1.3 优先级反转问题Resource 解决的核心问题任务A(prio1,高)任务B(prio2,中)任务C(prio3,低)│ │ │ │ │GetResource(R1)│ │(C 持有 R1)│ │ │ │GetResource(R1)|│ │(A 等待 R1)|│ │ │ │ │ │(B 抢占 C)│ │ │ B 长时间运行 │ │ │ │ │(A 被间接阻塞)│ │ │(实际等待时间R1 临界区时间)│问题低优先级 C 持锁高优先级 A 等待但中优先级 B 抢占了 C导致 A 被间接延长等待时间。优先级继承协议PIP核心思想持锁任务临时继承等待锁的最高优先级任务的优先级。任务A(prio1,高)任务C(prio3,低)│ │ │GetResource(R1)│ │ │GetResource(R1)│ │(A 等待 R1)│ │ │ │ ┌────────────┘ │ ▼ │ C 优先级被提升到1(继承 A 的优先级)│ C 继续执行以 prio1运行 │B(prio2)无法抢占 C │ │ │ReleaseResource(R1)│ C 优先级恢复到3│ │ │ A 获得 R1,被调度 │ ▼1.4 Priority Ceiling ProtocolPCP本 OS 采用Ceiling 优先级设定每个 Resource 有一个 ceiling 优先级设定为所有可能请求该资源的任务/ISR 中最高的优先级。可能请求 R1 的任务:TaskA(prio1)TaskB(prio2)TaskC(prio5)R1.ceiling1(最高优先级)为什么用 PCP 而非 PIP协议特点优缺点PIP优先级继承持锁任务继承等待者的优先级需要遍历等待队列复杂PCP优先级天花板持锁任务直接提升到 ceilingO(1)简单但可能有过度提升本 OS 采用 PCP因为ceiling 优先级在配置时静态确定GetResource 时直接提升到 ceiling无需查找等待者实现简单开销低1.5 Resource 的关键数据结构structOs_ResourceCfgType{ResourceType rsrcId;// 资源 IDCoreIdType coreId;// 所属核uint32 accessingApps;// 允许访问的 App 位掩码ApplicationType ownerAppId;// 所有者 Appboolean isIsr;// 是否为 ISR 资源union{Os_TaskPrioType taskPrio;// Ceiling 优先级任务Os_IntLevelType isrLevel;// Ceiling 中断等级ISR}rsrcParam;Os_ResourceDynType*resouceDyn;// 运行时状态};structOs_ResourceDynType{Os_ResourceStateType state;// LOCKED/RELEASEDunion{...}rsrcParam;// 当前 ceilingunion{...}preRsrcParam;// 提升/恢复前的原始优先级Os_ListNodeType rsrcListNode;// 链表节点记录获取顺序};1.6 Resource vs Event vs Spinlock对比维度ResourceEventSpinlock作用域单核内任务/ISR 互斥任务间同步多核间互斥阻塞方式不阻塞返回错误阻塞WaitEvent忙等待自旋优先级影响提升持锁者优先级不影响不影响获取顺序LIFO栈式无限制FIFO/优先级核心机制优先级继承 ceiling位掩码匹配原子操作 自旋适用场景共享数据保护短临界区事件通知多核共享数据跨核不支持支持SetEvent 跨核支持多核专用1.7 Resource的2个APIAPI作用调用者GetResource(ResID)获取资源加锁任意 Task/Cat2 ISRReleaseResource(ResID)释放资源解锁任意 Task/Cat2 ISR2. GetResource2.1 GetResource流程图2.2 GetResource调用层级┌─────────────────────────────────────────────────────────────────┐ │ 用户代码 │ │GetResource(ResID)← AUTOSAR 标准 API │ └──────────────────────────────┬──────────────────────────────────┘ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ Resource 层Os_Resource.c │ │ Os_Resource_GetResource ← API 入口检查加锁优先级提升 │ │ └─ Os_Resource_GetResourceSimp ← 置锁IncreaseTaskPrio │ │ └─ Os_Schedler_IncreasePriority ← 队列头部插入位图置位 │ └─────────────────────────────────────────────────────────────────┘2.3 GetResource状态切换NA.2.4 GetResource调用栈NA.2.5 GetResource2.5.1 Os_Resource_GetResourceOs_Resource_GetResource(ResourceType resId){/* 第 1 阶段参数和上下文检查 */if(resIdOS_RESOURCEID_COUNT)returnE_OS_ID;// ① ID 范围if(OS_CORE_MASK_INTERRUPT(coreId))returnE_OS_DISABLEDINT;// ② 中断禁用if(OS_CORE_PROCESSTYPEMATCH(...))returnE_OS_CALLEVEL;// ③ 调用上下文if(coreId!resourceCfg-coreId)returnE_OS_CORE;// ④ 同核if(OS_RESOURCE_ALREADYLOCKED(...))returnE_OS_ACCESS;// ⑤ 未被锁if(OS_APPMATCH(...))returnE_OS_ACCESS;// ⑥ Permissionif(isCat2!isIsrResource)returnE_OS_ACCESS;// ⑦ ISR/Task 匹配if(!isCat2isIsrResource)returnE_OS_ACCESS;// ⑦ ISR/Task 匹配if(!Os_Resource_CheckPrioIsHigher(...))returnE_OS_ACCESS;// ⑧ 优先级 ceiling/* 第 2 阶段禁中断临界区 */Os_Arch_IntDisableAll();/* 第 3 阶段时序保护 */Os_Tp_StartResBudget(...);/* 第 4 阶段获取资源置锁 优先级提升 */Os_Resource_GetResourceSimp(resourceCfg);/* 第 5 阶段压入资源链表LIFO 记录 */Os_List_Push(rsrcListHead,resourceCfg-resouceDyn-rsrcListNode);Os_Arch_IntEnableAll();}2.5.1.1 Os_Resource_IncreaseTaskPrioOs_Resource_IncreaseTaskPrio(resourceCfg){rsrcTaskprioresourceCfg-resouceDyn-rsrcParam.taskPrio;// ceilingcurrentTaskprioOS_TASK_GETRUNPRIO(currentTask);// 当前运行优先级if(rsrcTaskpriocurrentTaskprio)// ceiling 更高数值更小{// 保存原始优先级用于恢复resourceCfg-resouceDyn-preRsrcParam.taskPriocurrentTaskprio;// 提升优先级Os_Schedler_IncreasePriority(scheduler,rsrcTaskprio);}}Scheduler 的 IncreasePriority 用 PushF头部插入保证当前任务在新优先级队列中排最前面。2.5.2 嵌套获取资源的优先级变化任务A(cfgPrio5)│ │GetResource(R1,ceiling3)│ preRsrcParam[R1]5← 保存原始 │ runPrio:5→3← 提升到3│ │GetResource(R2,ceiling2)│ preRsrcParam[R2]3← 保存当前已提升的 │ runPrio:3→2← 提升到2│ │(临界区执行)│ │ReleaseResource(R2)(必须先释放 R2,LIFO)│ 读取 preRsrcParam[R2]3│ runPrio:2→3← 恢复到 R1 的 ceiling │ │ReleaseResource(R1)│ 读取 preRsrcParam[R1]5│ runPrio:3→5← 恢复到原始5▼3. ReleaseResource3.1 ReleaseResource流程图3.2 ReleaseResource调用层级┌─────────────────────────────────────────────────────────────────┐ │ 用户代码 │ │ReleaseResource(ResID)← AUTOSAR 标准 API │ └──────────────────────────────┬──────────────────────────────────┘ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ Resource 层Os_Resource.c │ │ Os_Resource_ReleaseResource ← API 入口检查解锁优先级恢复 │ │ └─ Os_Resource_ReleaseResourceSimp ← 解锁RestoreTaskPrio │ │ └─ Os_Schedler_DecreasePriority ← 队列弹出可能清位图 │ │ └─ Os_Schedler_NeedSchedle ← 判断是否需要切换 │ │ └─ Os_Schedler_Schedle ← 选 nextTask │ │ └─ Os_Task_TaskSwitch ← CSA 切换 │ └─────────────────────────────────────────────────────────────────┘3.3 ReleaseResource3.4 ReleaseResource3.5 ReleaseResource3.5.1 Os_Resource_ReleaseResourceOs_Resource_ReleaseResource(ResourceType resId){/* 第 1 阶段参数和上下文检查同 GetResource */if(resIdOS_RESOURCEID_COUNT)returnE_OS_ID;if(OS_CORE_MASK_INTERRUPT(coreId))returnE_OS_DISABLEDINT;if(OS_CORE_PROCESSTYPEMATCH(...))returnE_OS_CALLEVEL;if(coreId!resourceCfg-coreId)returnE_OS_CORE;if(OS_APPMATCH(...))returnE_OS_ACCESS;if(isCat2!isIsrResource)returnE_OS_ACCESS;if(!isCat2isIsrResource)returnE_OS_ACCESS;if(OS_RESOURCE_ISUNLOCKED(...))returnE_OS_NOFUNC;// ⑧ 必须已锁if(!Os_Resource_CheckReleaseOrder(...))returnE_OS_NOFUNC;// ⑨ LIFO 顺序/* 第 2 阶段禁中断临界区 */Os_Arch_IntDisableAll();/* 第 3 阶段释放资源解锁 优先级恢复 */Os_Resource_ReleaseResourceSimp(resourceCfg);/* 第 4 阶段从资源链表弹出 */Os_List_Pop(rsrcListHead);/* 第 5 阶段可能触发调度 */if(OS_CORE_CHECKCURRENTINTASK(coreId)){if(Os_Schedler_NeedSchedle(scheduler)){nextDynOs_Schedler_Schedle(scheduler);Os_Task_TaskSwitch(currentTaskCfg,nextTaskCfg);}}Os_Arch_IntEnableAll();/* 第 6 阶段时序保护 */Os_Tp_StopResBudget(...);}3.5.2 Os_Resource_CheckReleaseOrderOs_Resource_CheckReleaseOrder(resourceCfg,rsrcListHead){// 必须释放最后获取的资源栈式 LIFOif(Os_List_GetTop(rsrcListHead)!resourceCfg-resouceDyn-rsrcListNode)retFALSE;}为什么必须 LIFO资源获取顺序R1 → R2 → R3释放必须R3 → R2 → R1嵌套临界区必须正确配对否则 preRsrcParam 恢复的优先级会错乱3.5.3 Os_Resource_RestoreTaskPrioOs_Resource_RestoreTaskPrio(resourceCfg){currentTaskprioOS_TASK_GETRUNPRIO(currentTask);preRsrcTaskprioresourceCfg-resouceDyn-preRsrcParam.taskPrio;// 保存的原始优先级if(currentTaskpriopreRsrcTaskprio)// 当前优先级 原始{Os_Schedler_DecreasePriority(scheduler,preRsrcTaskprio);}else{Os_FatalError();// 异常优先级被破坏}}Scheduler 的 DecreasePriority 会从当前提升后的优先级队列弹出恢复到原始优先级重新选下一个任务可能更高优先级任务在等待4. 完整优先级继承时序图任务A(prio1,高)任务B(prio2,中)任务C(prio5,低)│ │ │ │ │GetResource(R1)│ │ ceiling1│ │ preRsrcParam5│ │IncreasePriority(1)│ │ runPrio:5→1│ │(C 以 prio1运行)│ │ │ │GetResource(R1)│ │ │(A 等待 R1,但 R1 已锁)│ │ │ │ │ │ │(B 想抢占 C)│ │ │ B.prio(2)C.runPrio(1)?│ │ No!(数值21,C 更高)│ │ B 无法抢占 C │ │ │ │ │ │ReleaseResource(R1)│ │RestoreTaskPrio(R1)│ │ preRsrcParam5│ │DecreasePriority(5)│ │ runPrio:1→5│ │ NeedSchedle?A 就绪 │ │TaskSwitch(C,A)│ A 获得锁,恢复运行 │ ▼