【TriCore-OS】Trap 文章目录1. Trap概念与分类1.1 TriCore Trap分类表1.2 三种Trap的区别2. Trap 向量入口的硬件机制2.1 Trap 向量表2.2 入口汇编模板以 MemFault 为例2.3 SysCall Trap 的特殊处理3. OS 如何介入三类 Trap3.1 Trap 6: SysCall主动调用OS 完全介入3.2 Trap 1/2: Fault异常OS 通过 ProtectionHook 介入3.3 其他 TrapUnvalid未注册异常OS 致命错误介入4. SysCall 的应用场景4.1 哪些 API 会走 SysCall4.2 信任函数CallTrustedFunction4.3 与多核服务的对比5. Trap 与中断/ISR 的关系5.1 三种异步/同步事件的对比5.2 嵌套关系5.3 Trap 与 Cat2 ISR 的 OS 介入对比6. OS 对 Trap 的三层介入模型1. Trap概念与分类Trap 是 TriCore 架构的同步异常synchronous exception由 CPU 在执行指令时检测到的异常情况触发与中断异步不同Trap 总是在触发它的那条指令处发生且不可屏蔽。1.1 TriCore Trap分类表Trap#名称代码宏处理函数TIN子类型来源1Memory FaultOs_Arch_MemFaultEntryOs_Arch_MemFaultHandlerd15 寄存器2Instruction FaultOs_Arch_InsFaultEntryOs_Arch_InsFaultHandlerd15 寄存器6System CallOs_Arch_SysCallEntryOs_SysCallHandlera4 寄存器参数指针其他Unvalid ExceptionOs_Arch_UnvalidExceptionOs_Arch_Exce_UnhandledTrap # 本身注意TC3XX 实际还有 Trap 0Virtualization Fill、3Context Management、4Bus Error、5Assertion、7Non-Maskable Interrupt等但 OS 代码中只显式注册了 1、2、6 三类其他由 Os_Arch_UnvalidException 兜底。1.2 三种Trap的区别维度Trap 1 (MemFault)Trap 2 (InsFault)Trap 6 (SysCall)触发方式自动硬件检测自动硬件检测主动syscall 0 指令触发原因访问非法地址、MPU 违例非法指令、未对齐访问用户态请求 OS 服务错误性质异常意外异常意外正常流程预期参数传递d15TIN, a11异常地址d15TIN, a11异常地址a4SysCall 参数指针OS 介入方式ProtectionHookProtectionHookSysCallHandler 派发是否返回通常不返回关闭核通常不返回关闭核必定返回继续执行2. Trap 向量入口的硬件机制2.1 Trap 向量表TriCore 的 Trap 向量表位于 BIV 寄存器指定的地址每个 Trap 号占用 32 字节__trap(x) __vector_table(core) 编译属性自动生成。OS 通过宏在每个核上注册独立的 Trap 处理函数。2.2 入口汇编模板以 MemFault 为例.align5;32字节对齐.global OS_MEMFAULT_CODE_START_0;全局符号 OS_MEMFAULT_CODE_START_0:svlcx;保存 Lower Context 到 CSA movh.a a4,%hi:cfg;加载 contextCfg 地址高位 lea a4,[a4]%lo:cfg;加载 contextCfg 地址低位 mov d4,d15;读取 TINTrap Identification Number mov.aa a5,a11;读取异常访问地址 call Os_Arch_MemFaultHandler;调用 C 处理函数 rslcx;恢复 Lower Context rfe;从异常返回svlcx 保存 Lower Context通用寄存器 D0-D7, A0-A7到 CSAContext Save Aread15 寄存器在 Trap 发生时硬件自动写入 TINTrap 子类型号a11 寄存器存放触发异常的访问地址rfe 指令恢复 PCXI 并返回到被中断的指令2.3 SysCall Trap 的特殊处理void__trap(6)__vector_table(core)osTrap_6_Core##core(void*a4){volatileuint32 pcxiOS_ZERO_VALUE;volatileuint32 interruptStateOS_ZERO_VALUE;// 1. 从 PCXI 读取被中断代码的中断使能状态PIE 位pcxiOS_ARCH_MFCR(OS_ARCH_PCXI_OFFSET);pcxi(pcxiOS_ARCH_PCXI_PIE_MASK)OS_ARCH_PCXI_PIE_BIT;// 2. 将 PIE 状态合并到 ICR中断控制寄存器interruptStateOS_ARCH_MFCR(OS_ARCH_ICR_OFFSET);interruptStateinterruptState|(pcxiOS_ARCH_ICR_INT_BIT);OS_ARCH_MTCR(OS_ARCH_ICR_OFFSET,interruptState);// 3. 调用 SysCall 派发器Os_SysCallHandler(a4);// 4. 恢复 ICR 的中断级别到 PCXI 的 PCPN 字段interruptStateOS_ARCH_MFCR(OS_ARCH_ICR_OFFSET)(OS_ARCH_ICR_INT_LEVEL_MASK|OS_ARCH_ICR_INT_MASK);pcxiOS_ARCH_MFCR(OS_ARCH_PCXI_OFFSET);pcxi~(OS_ARCH_PCXI_PCPN_MASK);pcxi|(interruptStateOS_ARCH_ICR_INT_LEVEL_MASK)OS_ARCH_PCXI_PCPN_BIT;OS_ARCH_MTCR(OS_ARCH_PCXI_OFFSET,pcxi);}为什么 SysCall 要恢复中断级别TriCore 的 CSA 上下文中保存了被中断代码的 ICR.IE 和 ICR.CCPN中断屏蔽级别。syscall 指令触发 Trap 后硬件将当前 ICR 状态保存到 PCXITrap 处理函数运行在新的上下文返回前需要把 SysCall 期间可能修改的中断级别写回 PCXI确保 rfe 恢复正确的中断状态这与中断/异常的关键区别SysCall 是正常调用可能在中断禁用/启用不同状态下进入和退出需要保持中断状态的连续性。3. OS 如何介入三类 Trap3.1 Trap 6: SysCall主动调用OS 完全介入触发方式非信任 App 调用 OS API 时API 内部执行 syscall 0 指令。用户态任务(非信任 App)│ ├─ 调用ActivateTask()│ └─ Os_Task_ActivateTask 检测 sysCallTRUE │ └─Os_Arch_SysCall()执行 syscall 指令 │ │ │ ▼ ★ 触发 Trap6│ osTrap_6_Core0 │ ├─svlcx(保存上下文)│ ├─ 恢复中断状态到 ICR │ ├─ call Os_SysCallHandler │ │ │ │ │ ▼ ★ OS 介入核心 │ │Os_SysCallHandler(sysCallData)│ │ ├─ funcIdsysCallData-funcId(如 ActivateTask_ID)│ │ ├─ funcOs_SysCallFunc_List[funcId]│ │ └─func(sysCallData-Os_SysCallParam)│ │ │ │ │ ▼ 切换到特权模式执行 │ │Os_SysCall_ActivateTask(parameter)│ │ └─ 调用真正的 Os_Task_IntlActivateTask │ │ │ ├─ 恢复中断级别到 PCXI │ ├─rslcx(恢复上下文)│ └─rfe(返回到 syscall 下一条指令)│ └─ 用户态任务继续执行得到返回值OS 介入要点特权切换syscall 指令将 CPU 从 User-0 模式切换到 Supervisor 模式OS 内核代码可访问全部内存服务派发Os_SysCallFunc_List 函数指针表约 50 个服务按 funcId 派发参数传递通过 a4 寄存器传递 Os_SysCallType* 指针内含 funcId、中断级别、参数联合体返回值通过参数结构体的 retVal 字段回传支持的 SysCall 服务typedefenum{Os_Syscall_ActivateTask_ID0U,// 任务管理类Os_Syscall_TerminateTask_ID,Os_Syscall_ChainTask_ID,Os_Syscall_GetTaskId_ID,Os_Syscall_GetTaskState_ID,// ... Alarm、Event、Resource、Spinlock、Counter、ScheduleTable ...Os_Syscall_CallTrustedFunction_ID,// 信任函数调用Os_Syscall_ControlIdle_ID,// 空闲控制Os_Syscall_Monitor_ID,// 监控服务Os_Syscall_Func_Counter}Os_Syscall_FuncId;3.2 Trap 1/2: Fault异常OS 通过 ProtectionHook 介入触发方式硬件自动检测无法预测。任意代码执行中触发异常 │(如访问非法地址/执行非法指令)▼ ★ 硬件触发 Trap1或 Trap2osTrap_1_Core0/osTrap_2_Core0 ├─svlcx(保存上下文)├─ mov d4,d15(读取 TIN)├─ mov.aa a5,a11(读取异常地址)├─ call Os_Arch_MemFaultHandler/Os_Arch_InsFaultHandler │ │ │ ▼ ★ OS 介入核心 │Os_Arch_MemFaultHandler(cfg,source,addr)│ ├─OS_ARCH_SETSP(cfg-stackStartAddr)│ │ ★ 切换到内核栈关键 │ │ 原因异常发生时栈可能已损坏必须用安全的内核栈 │ ├─Os_Arch_StoreFaultInfo(source,addr)│ │ 保存故障信息到局部变量便于调试 │ └─Os_Hook_CallProtectionHook(E_OS_PROTECTION_MEMORY)│ │ │ ▼ ★ 用户 Hook 决策 │ Os_Hook_CallProtectionHook │ ├─ 关中断 │ ├─ 记录错误状态和调用者 │ ├─ 设置 ProcTypePROTECTHOOK │ ├─ 调用用户配置的ProtectionHook(error)│ │ │ │ │ ▼ 返回 ProtectionReturnType │ │ ├─PRO_IGNORE(忽略)│ │ ├─PRO_TERMINATETASKISR(终止任务/ISR)│ │ ├─PRO_TERMINATEAPPL(终止应用)│ │ └─PRO_SHUTDOWN(关闭 OS)│ │ │ ├─Os_HookProtectionLogical(逻辑处理)│ └─Os_HookProtectionProcess(执行决策)│ ├─ 忽略 → 返回原现场 │ ├─ 终止任务 → Os_Task_TerminateTask │ ├─ 终止应用 → Os_App_TerminateApplication │ └─ 关闭 → Os_Core_Shutdown │ ├─rslcx(恢复上下文)└─rfe(返回)★ 若 ProtectionHook 返回 IGNORE回到原代码继续 ★ 否则不返回已切换到新任务或关机OS 介入要点栈切换异常时栈可能已损坏Os_Arch_Exception.c:148 强制切到内核栈 cfg-stackStartAddrProcType 标记进入 ProtectionHook 前设置 OS_PROTECTHOOK_TYPE_MASKOS API 会据此检查是否允许调用用户决策OS 不直接决定如何处理而是交给用户配置的 ProtectionHook 回调决策错误码区分E_OS_PROTECTION_MEMORY内存错vs E_OS_PROTECTION_EXCEPTION指令错3.3 其他 TrapUnvalid未注册异常OS 致命错误介入void__trap(x)__vector_table(core)osTrap_##x##_Core##core(void){Os_Arch_Exce_Unhandled();// ★ 调用 Os_FatalError()}FUNC(void,OS_CODE)Os_Arch_Irq_Unhandled(void){Os_FatalError();// 未注册中断 → 致命错误}FUNC(void,OS_CODE)Os_Arch_Exce_Unhandled(void){Os_FatalError();// 未注册异常 → 致命错误}OS 介入要点未注册的 Trap如 Trap 3/4/5/7直接调用 Os_FatalError这是不可恢复的错误通常进入死循环或重启用于捕获 OS 未预期的硬件异常作为最后的兜底4. SysCall 的应用场景4.1 哪些 API 会走 SysCall通过 grep Os_SysCall( )统计所有需要特权访问的 OS API 都会在非信任 App 中走 SysCall模块SysCall 服务数典型 APITask5ActivateTask、TerminateTask、ChainTask、GetTaskID、GetTaskStateAlarm5GetAlarm、GetAlarmBase、SetRelAlarm、SetAbsAlarm、CancelAlarmEvent1SetEventResource3GetResource、ReleaseResource、GetResourceIDSpinlock4GetSpinlock、ReleaseSpinlock、TryToGetSpinlock、GetSpinlockIdCounter3IncrementCounter、GetCounterValue、GetElapsedValueScheduleTable5Start/Stop/Next/GetStatusApplication5TerminateApplication、GetApplicationState、GetApplicationID 等IOC4IocWrite、IocRead、IocSend、IocReceiveTrustFun1CallTrustedFunctionMonitor1Monitor其他若干ShutdownOS、ShutdownAllCores、ControlIdle4.2 信任函数CallTrustedFunction信任函数是特殊的 SysCall 应用非信任 App 需要执行特权操作如直接访问硬件寄存器通过调用预配置的信任函数实现。非信任 App │ ├─CallTrustedFunction(funcIndex,params)│ └─Os_Arch_SysCall()→ Trap6│ └─ Os_SysCallHandler │ └─ Os_SysCall_CallTrustedFunction │ └─ Os_CallTrustedFunctionSimp │ ├─ 切换到信任函数的 MPU 区 │ ├─ 执行用户配置的信任函数特权模式 │ └─ 切换回原 MPU 区 │ └─ 返回信任函数执行完毕4.3 与多核服务的对比维度SysCall (Trap 6)Os_MultiCoreServer触发场景同核内特权切换跨核服务请求通信方式寄存器 a4 传参共享内存 SRC 软中断是否阻塞同步等返回可同步可异步目标本核 OS 内核其他核 OS5. Trap 与中断/ISR 的关系5.1 三种异步/同步事件的对比事件类型触发方式入口指令可屏蔽上下文保存中断 (ISR)硬件异步__interrupt(level)可屏蔽Cat2/ 不可屏蔽Cat1svlcx Os_Arch_SaveContextSysCall (Trap 6)软件主动syscall 0不可屏蔽Trap 优先级最高svlcxFault (Trap 1/2)硬件自动__trap(1/2)不可屏蔽svlcx5.2 嵌套关系Task(User Mode)│ ├─ syscall0──► Trap6(Supervisor Mode)│ │ │ ├─ 可被中断抢占 │ │ └─ISR(Cat2)嵌套 │ │ └─ ISR 中也可 syscall嵌套 Trap │ │ │ └─ 可被 Fault 抢占 │ └─ Trap1/2嵌套 │ └─ ProtectionHook 中可再触发 syscall │ └─Fault(Trap1/2)也可在 Task 执行中发生关键设计Trap 可以嵌套OS 通过 CSA 链表管理嵌套上下文。5.3 Trap 与 Cat2 ISR 的 OS 介入对比维度Cat2 ISRTrap 6 (SysCall)Trap 1/2 (Fault)入口汇编svlcx Os_Arch_SaveContext Os_Isr_Entrysvlcx 恢复 ICR Os_SysCallHandlersvlcx 传参 Os_Arch_*FaultHandlerOS 介入函数Os_Isr_EntryOs_SysCallHandlerOs_Hook_CallProtectionHook上下文切换切到 ISR 栈不切栈用 Trap 栈切到内核栈MPU 切换切到 ISR 的 MPU自动进特权区自动进特权区调度触发退出时可能调度不调度由 ProtectionHook 决定资源清理强制释放 Resource/Spinlock不需要强制释放6. OS 对 Trap 的三层介入模型┌─────────────────────────────────────────────────────────────────┐ │ 第0层硬件自动响应 │ │-保存 PCXI、PC 到 CSA │ │-加载 Trap 向量表入口地址 │ │-写入 TIN 到 d15、异常地址到 a11 │ └─────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ 第1层Trap 向量入口汇编 │ │-svlcx 保存 Lower Context │ │-准备参数d4TIN,a5地址/a4SysCallData │ │-call C 处理函数 │ │-rslcxrfe 返回 │ └─────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ 第2层OS C 处理函数OS 介入 │ │ │ │ ├─ Trap6(SysCall):│ │ │ Os_SysCallHandler │ │ │ ├─ 查 Os_SysCallFunc_List 函数表 │ │ │ └─ 派发到具体服务ActivateTask、SetEvent 等 │ │ │ ★ OS 完全介入作为特权代理执行 │ │ │ │ │ ├─ Trap1/2(Fault):│ │ │ Os_Arch_MemFaultHandler/Os_Arch_InsFaultHandler │ │ │ ├─ 切换到内核栈 │ │ │ ├─ 保存故障信息 │ │ │ └─ Os_Hook_CallProtectionHook │ │ │ ├─ 记录错误状态 │ │ │ ├─ 设置 ProcTypePROTECTHOOK │ │ │ ├─ 调用用户 ProtectionHook │ │ │ └─ 执行决策忽略/终止任务/终止应用/关机 │ │ │ ★ OS 介入作为错误处理框架 │ │ │ │ │ └─ 其他Trap(Unvalid):│ │ Os_Arch_Exce_Unhandled → Os_FatalError │ │ ★ OS 介入作为致命错误兜底 │ └─────────────────────────────────────────────────────────────────┘