【TriCore-OS】Os_MultiCoreServer 📅 发布时间:2026/8/28 18:16:49 👁 浏览次数: 文章目录1. Os_MultiCoreServer 的定位与作用1.1 为什么需要这个机制1.2 与 IOC 的区别2. 支持的服务列表3. 核心数据结构3.1 三层缓冲结构3.2 共享内存缓冲布局3.3 关键内存属性4. 跨核服务调用完整流程4.1 调用入口在 Task/Event/Alarm 等模块中4.2 Os_MultiCore_Trigger 主流程4.3 Os_MultiCoreServer_Write4.4 Os_MultiCoreServer_Read4.5 目标核中断处理4.6 完整时序图5. 硬件触发机制5.1 Os_Arch_Trigger_Core5.2 清中断的简化6. 多核启动同步6.1 四阶段同步6.2 Os_MultiCore_Sync 实现7. 调用方使用模式汇总1. Os_MultiCoreServer 的定位与作用Os_MultiCoreServer多核服务机制位于 Os_MultiCore.c是 AUTOSAR OS 多核 OS 的跨核服务调用机制。它允许一个核上的任务/ISR 调用目标核上才能执行的 OS 服务因为目标对象 Task/Alarm/Counter 等归属于目标核。1.1 为什么需要这个机制AUTOSAR OS 多核架构中OS 对象是核本地归属的每个 Task、Alarm、Counter、ScheduleTable、ISR 都归属于某个特定核任务调度、Alarm 管理、Counter 计数等操作必须在归属核上执行当 Core0 上的代码要 ActivateTask(TaskOfCore1) 时不能直接操作 Core1 的调度器解决方案通过 Os_MultiCoreServer 把请求转发到目标核执行1.2 与 IOC 的区别维度IOCOs_MultiCoreServer用途应用间数据传递OS 服务跨核转发同步方式异步非阻塞同步/异步双模式触发方式接收方轮询硬件软中断触发立即通知目标核返回值简单错误码携带完整返回值给调用方典型调用Ioc_SendActivateTask 跨核时自动走2. 支持的服务列表typedefenum{Os_MCServe_ActivateTask_ID0U,/* 激活任务 */Os_MCServe_AlarmActivateTask_ID,/* Alarm 激活任务 */Os_MCServe_ChainTask_ID,/* 链接任务 */Os_MCServe_GetTaskState_ID,/* 查询任务状态 */Os_MCServe_GetAlarm_ID,/* 查询 Alarm 剩余 tick */Os_MCServe_GetAlarmBase_ID,/* 查询 AlarmBase */Os_MCServe_SetRelAlarm_ID,/* 相对 Alarm */Os_MCServe_SetAbsAlarm_ID,/* 绝对 Alarm */Os_MCServe_CancelAlarm_ID,/* 取消 Alarm */Os_MCServe_TerminateApplication_ID,/* 终止应用 */Os_MCServe_GetApplicationState_ID,/* 查询应用状态 */Os_MCServe_ShutdownAllCores_ID,/* 关闭所有核 */Os_MCServe_SetEvent_ID,/* 设置事件 */Os_MCServe_AlarmSetEvent_ID,/* Alarm 设置事件 */Os_MCServe_StartSchdTbRel_ID,/* 启动调度表相对 */Os_MCServe_StartSchdTbAbs_ID,/* 启动调度表绝对 */Os_MCServe_StopSchdTb_ID,/* 停止调度表 */Os_MCServe_NextSchdTb_ID,/* 切换下一个调度表 */Os_MCServe_GetSchdTbStatus_ID,/* 查询调度表状态 */Os_MCServe_GetTaskStackUsage_ID,/* 查询任务栈使用 */Os_MCServe_GetIsrStackUsage_ID,/* 查询 ISR 栈使用 */Os_MCServe_GetCounterValue_ID,/* 查询 Counter 值 */Os_MCServe_Func_Counter}Os_MCServe_FuncId;这 22 个服务覆盖了几乎所有需要跨核操作的 OS API函数表是 ID 到具体处理函数的映射。3. 核心数据结构3.1 三层缓冲结构┌─────────────────────────────────────────────────────────────────────┐ │ Os_MultiCoreServe[OS_COREID_COUNT](每核一个发送缓冲)│ │ ┌─────────────────────────────────────────────────────────────────┐ │ │ │Os_MultiCoreServeType(srcCore 自己维护)│ │ │ │ ├─ uint8 writeId 已写入数量 │ │ │ │ └─ Os_CoreServeType Os_CoreServe[6]★6个槽位的环形数组 │ │ │ │ ├─[0]{isSync,active,funcId,param,retVal}│ │ │ │ ├─[1]...│ │ │ │ └─[5]...│ │ │ └─────────────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────────┘ ↓ 共享地址传递 ┌─────────────────────────────────────────────────────────────────────┐ │ Os_MCServe_ShareMemory[OS_MULTICORE_BUFFCNT](跨核共享内存)│ │ Os_MultiCoreCommType{active,addr}│ │ ★ addr 指向发送方 Os_CoreServeType │ └─────────────────────────────────────────────────────────────────────┘ ↓ 触发软中断 ┌─────────────────────────────────────────────────────────────────────┐ │ 目标核 ISR:Os_MultiCoreServer_Handler │ │ 通过 addr 读出发送方 Os_CoreServeType执行 func写回 retVal │ └─────────────────────────────────────────────────────────────────────┘3.2 共享内存缓冲布局#defineOS_MULTICORE_BUFFCNT(OS_COREID_COUNT*(OS_COREID_COUNT-1))#defineOS_MULTICORE_GETBUFF(coreId)(coreId*(OS_COREID_COUNT-1))每个目标核在 Os_MCServe_ShareMemory 中分配 OS_COREID_COUNT-1 个 Os_MultiCoreCommType 项每个对应一个可能的发送核。例如 3 核系统Core0 的发送槽给 Core1、Core2索引 0, 1Core1 的发送槽给 Core0、Core2索引 2, 3Core2 的发送槽给 Core0、Core1索引 4, 5Os_MultiCore_GetSendBuff 处理 srcCoredesCore 时的索引偏移避免双向通信冲突。3.3 关键内存属性#defineOS_START_SEC_GLOBAL_NOCACHE_VAR★ NOCACHE 关键多核可见#includeOs_MemMap.hstaticVAR(Os_MultiCoreServeType,OS_VAR_NO_INIT)Os_MultiCoreServe[OS_COREID_COUNT];staticVAR(Os_MultiCoreCommType,OS_VAR_NO_INIT)Os_MCServe_ShareMemory[OS_MULTICORE_BUFFCNT];volatileVAR(uint8,OS_VAR_NO_INIT)Os_MultiCoreSync[OS_COREID_COUNT];#defineOS_STOP_SEC_GLOBAL_NOCACHE_VARNOCACHE 是多核可见性的关键若使用 cacheCore0 写入 Core1 可能读到旧值。4. 跨核服务调用完整流程以 Core0 上的 TaskA 调用 ActivateTask(TaskB_OfCore1) 为例4.1 调用入口在 Task/Event/Alarm 等模块中parameter.Os_ActivateTask.taskIdtaskId;/* Execute multi-core calling function. */retOs_MultiCore_Trigger(TRUE,/* isSync同步等待 */coreId,/* srcCore0 */OS_TASK_GETCOREID(taskCfg),/* desCore1 */Os_MCServe_ActivateTask_ID,/* funcId */parameter);/* 参数 */4.2 Os_MultiCore_Trigger 主流程1.校验 srcCore/desCore 有效性2.计算 buffOffsetOs_MultiCore_GetSendBuff(srcCore,desCore)3.multicoreCommOs_MCServe_ShareMemory[buffOffsetOS_MULTICORE_GETBUFF(desCore)]★ 指向目标核 desCore 的发送槽中、对应 srcCore 的那一项4.multiCoreServeOs_MultiCoreServe[srcCore]★ 指向 srcCore 自己的发送缓冲5.retOs_MultiCoreServer_Write(isSync,funcId,param,multiCoreServe)6.if(OK)retOs_MultiCoreServer_Read(multiCoreServe,multicoreComm,desCore,param)4.3 Os_MultiCoreServer_WriteOs_Arch_IntDisable(intState);// 关本核中断防 ISR 干扰writeIdmultiCoreServe-writeId;if(Os_MULTICORE_MESSAGE_SIZEwriteId)// 6 个槽位满retE_OS_BUFFFULL;else{// 1. 拷贝参数到发送槽Os_MultiCore_ParamMemCyp(param,multiCoreServe-Os_CoreServe[writeId].Os_MultiCoreServeParam);// 2. 设置标志multiCoreServe-Os_CoreServe[writeId].isSyncisSync;multiCoreServe-Os_CoreServe[writeId].funcIdfuncId;multiCoreServe-Os_CoreServe[writeId].activeTRUE;// ★ 标记待处理multiCoreServe-writeId;}Os_Arch_IntEnable(intState);4.4 Os_MultiCoreServer_Read这是核心同步逻辑区分同步/异步while(TRUE){if(FALSEmultiCoreComm-active)// 槽位未被占用{Os_Arch_IntDisable(intState);if(FALSEmultiCoreServe-Os_CoreServe[writeId].active){// ★ Case A: 已被目标核处理完// 拷贝返回值到 param减少 writeId退出multiCoreServe-writeId--;Os_MultiCore_ParamMemCyp(...-Os_MultiCoreServeParam,param);retmultiCoreServe-Os_CoreServe[writeId].retVal;breakFlagTRUE;}else{// ★ Case B: 首次发送触发目标核处理multiCoreComm-activeTRUE;multiCoreComm-addrmultiCoreServe-Os_CoreServe[writeId];Os_Arch_Trigger_Core(desCore);// ★ 触发目标核软中断if(FALSEisSync)// 异步模式{multiCoreServe-writeId--;breakFlagTRUE;// 立即返回不等结果}// 同步模式不退出 while循环轮询 active 标志}Os_Arch_IntEnable(intState);}if(breakFlag)break;}同步模式发送方在 while(TRUE) 中忙等待目标核处理完成active 被清为 FALSE然后取出 retVal 返回。异步模式发送即返回不等结果适用于 Fire-and-Forget 场景如 Alarm 回调中的 SetEvent。4.5 目标核中断处理OS_ISR(Os_MultiCoreServer_Handler){Os_Arch_IntDisableAll();coreIdOs_Core_GetLogicId();Os_Arch_ClrMultiInt(coreId);// 清软中断标志multicoreCommOs_MCServe_ShareMemory[OS_MULTICORE_GETBUFF(coreId)];// 遍历所有可能的发送核OS_COREID_COUNT - 1 个for(index0;index(OS_COREID_COUNT-1);index){if(TRUEmulticoreComm[index].active)// 该发送核有请求{coreServemulticoreComm[index].addr;// 通过地址访问发送核的缓冲funcIdcoreServe-funcId;funcMultiCoreFuncList[funcId];// 查函数表statusfunc(coreServe-Os_MultiCoreServeParam);// ★ 执行目标核 OS 服务coreServe-retValstatus;// 写回返回值coreServe-activeFALSE;// ★ 通知发送方已完成multicoreComm[index].activeFALSE;// 释放共享槽}}}4.6 完整时序图Core0(发送方)Core1(目标核)───────────── ───────────── TaskA 调用ActivateTask(TaskB_Core1)│ ▼ Os_Task_ActivateTask ├─ 检测 TaskB 归属 Core1 └─Os_MultiCore_Trigger(isSyncTRUE,0,1,ActivateTask_ID,param)│ ▼ Os_MultiCoreServer_Write ├─ 写入 Os_MultiCoreServe[0].Os_CoreServe[idx]├─ activeTRUE,funcId,isSync,param └─ writeId│ ▼ Os_MultiCoreServer_Read ├─ multiCoreComm-activeFALSE?│ └─ YES进入首次发送分支 ├─ multiCoreComm-activeTRUE ├─ multiCoreComm-addrOs_CoreServe[idx]├─Os_Arch_Trigger_Core(1)──────────► SRC.SR1触发软中断 │ │ │(忙等待while(TRUE))▼ │ 轮询 multiCoreComm-active Os_MultiCoreServer_Handler ISR │ ├─Os_Arch_ClrMultiInt(1)│ ├─ 遍历 multicoreComm[]│ ├─ 找到 activeTRUE 的项 │ ├─ coreServemulticoreComm.addr │ ├─ funcIdcoreServe-funcId │ ├─ funcMultiCoreFuncList[funcId]│ │Os_MCServe_ActivateTask │ ├─ statusfunc(coreServe-param)│ │ └─Os_TargetActivateTask(TaskB)│ │ └─ Os_Task_ActivateTask 本地 │ ├─ coreServe-retValstatus │ ├─ coreServe-activeFALSE ★ │ └─ multicoreComm-activeFALSE ★ │ ◄───────────────────────────────────── ISR 返回 │ active 变 FALSE退出循环 ├─ 拷贝 retVal 到 param └─ 返回 ret │ ▼ TaskA 得到 ActivateTask 的返回值继续执行5. 硬件触发机制5.1 Os_Arch_Trigger_CoreFUNC(void,OS_CODE)Os_Arch_Trigger_Core(CoreIdType coreId){uint32 regValue;constOs_Arch_IsrSourceType*isrSource;isrSourceOS_CORE_GETMULTICOMMISRSOURCE(coreId);// 取目标核的中断源号regValue*(volatileuint32*)(OS_ARCH_INT_SRC_BASE(isrSource-number));*(volatileuint32*)(OS_ARCH_INT_SRC_BASE(isrSource-number))(regValue|OS_ARCH_INT_SRC_SETR_MASK);// ★ 设置 SRC.SETR 位触发软中断}原理TC3XX的 SRCSystem Interrupt Controller有 SETR 位软件写 1 可触发对应核的中断。每个核都有一个专用的多核通信中断源配置为 Cat2 ISR服务函数就是 Os_MultiCoreServer_Handler。5.2 清中断的简化Os_Arch_ClrMultiIntFUNC(void,OS_CODE)Os_Arch_ClrMultiInt(CoreIdType coreId){OS_DUMMY_STATEMENT(coreId);// 空实现}TC3XX 的 SRC 类型中断在 ISR 进入时硬件会自动清 SR因此软件清中断是空操作。这与 STM 的 ISCR 需要软件清不同。6. 多核启动同步6.1 四阶段同步Os_MultiCore_Sync(coreId, OS_MULTISYNCFIRST); // 阶段1所有核启动请求同步 Os_Hook_CallStartupHook(coreId); // 调用 StartupHook Os_MultiCore_Sync(coreId, OS_MULTISYNCSECOND); // 阶段2Hook 完成 /* Counter/Alarm/Task/ISR 等初始化 */ Os_MultiCore_Sync(coreId, OS_MULTISYNCTHIRD); // 阶段3OS 对象初始化完成 Os_Task_StartFirst(coreId); // 启动第一个任务ShutdownAllCores 时有 OS_MULTISYNCFOURTH。6.2 Os_MultiCore_Sync 实现void Os_MultiCore_Sync(CoreIdType coreId, uint8 syncCounter) { uint8 syncIdx; uint8 syncRet; do { // 1. 在自己的 sync 数组位上置位位图 Os_MultiCoreSync[coreId] Os_MultiCoreSync[coreId] | OS_MULTICOREMATCH(syncCounter); // 2. 计算期望值该阶段的位 syncRet OS_MULTICOREMATCH(syncCounter); // 3. 检查所有核是否都置了该位 for( syncIdx 0; syncIdx OS_COREID_COUNT; syncIdx ) { syncRet Os_MultiCoreSync[syncIdx]; } } while( FALSE syncRet ); // ★ 所有核到位才退出 }原理用 Os_MultiCoreSync[OS_COREID_COUNT] 数组每核一个字节做位图同步屏障Barrier。每个阶段对应一个 bit1, 2, 4, 8…所有核都置位后才放行。7. 调用方使用模式汇总Os_Task.c、Os_Event.c、Os_Alarm.c 等模块中的调用统一模式/* 1. 检测目标对象归属核 */ if( coreId ! OS_TASK_GETCOREID(taskCfg) ) { /* 2. 跨核填充参数联合体 */ Os_MultiCoreServeParamType parameter; parameter.Os_ActivateTask.taskId taskId; /* 3. 触发跨核调用 */ ret Os_MultiCore_Trigger(TRUE, /* 同步 */ coreId, /* srcCore */ OS_TASK_GETCOREID(taskCfg), /* desCore */ Os_MCServe_ActivateTask_ID, /* funcId */ parameter); } else { /* 本核直接调用 */ ret Os_Task_IntlActivateTask(taskId); }