【TriCore-OS】SetRelAlarm
文章目录1. SetRelAlarm流程图2. SetRelAlarm整体调用链3. SetRelAlarm状态切换4. SetRelAlarm调用栈5. SetRelAlarm代码逻辑5.1 SetRelAlarm5.2 Os_Alarm_SetRelAlarm5.2.1 Os_Alarm_IntSetRelAlarm5.2.1.1 Os_Counter_InsertExpPoint5.2.1.1.1 Os_Counter_SetExpPoint5.3 Os_Arch_Mach_HrtTimerSetCompareValue6. CancelAlarm整体调用链7. CancelAlarm调用栈8. CancelAlarm代码逻辑8.1 CancelAlarm8.2 Os_Alarm_CancelAlarm8.2.1 Os_Alarm_IntCancel8.2.1.1 Os_Counter_ExpPointDel1. SetRelAlarm流程图2. SetRelAlarm整体调用链3. SetRelAlarm状态切换Alarm 状态机 4. SetRelAlarm调用栈5. SetRelAlarm代码逻辑5.1 SetRelAlarmStatusTypeSetRelAlarm(AlarmType AlarmID,TickType Increment,TickType Cycle){StatusType ret;#if(OS_MEMORY_PROTECTIONSTD_ON)Os_SysCallParamType sysCallParam;sysCallParam.Os_SetRelAlarm.alarmIdAlarmID;sysCallParam.Os_SetRelAlarm.incrementIncrement;sysCallParam.Os_SetRelAlarm.cycleCycle;Os_SysCall(Os_Syscall_SetRelAlarm_ID,sysCallParam);/* 走 SysCall trap. */retsysCallParam.Os_SetRelAlarm.retVal;#elseretOs_Alarm_SetRelAlarm(AlarmID,Increment,Cycle);/* 直接调用*/#endifreturnret;}5.2 Os_Alarm_SetRelAlarmOs_StatusTypeOs_Alarm_SetRelAlarm(alarmId,increment,cycle){/* 第 1 阶段参数和上下文检查 */coreIdOs_Core_GetLogicId();if(alarmIdOS_ALARMID_COUNT)returnE_OS_ID;// ① ID 范围if(OS_CORE_MASK_INTERRUPT(coreId))returnE_OS_DISABLEDINT;// ② 中断禁用if(OS_CORE_PROCESSTYPEMATCH(coreId,OS_SETRELALARM_ACCESS))returnE_OS_CALLEVEL;// ③ 调用上下文alarmCfgOS_ALARM_GETCFG(alarmId);if(OS_APPMATCH(alarmCfg-accessingApps,OS_CORE_GETAPPID(coreId)))returnE_OS_ACCESS;// ④ Permission/* 第 2 阶段多核路由 */#ifMULTI_COREif(coreId!OS_ALARM_GETCOREID(alarmCfg)){// 跨核消息转发到目标核Os_MultiCore_Trigger(TRUE,coreId,OS_ALARM_GETCOREID(alarmCfg),Os_MCServe_SetRelAlarm_ID,parameter);return;}#endif/* 第 3 阶段状态和参数检查 */if(OS_APP_STATEOFF(alarmCfg-ownerAppId))returnE_OS_ACCESS;// ⑤ Accessibilityif(OS_ALARM_SETalarmDyn-state)returnE_OS_STATE;// ⑥ 已设置if(OS_ZERO_VALUEincrement)returnE_OS_VALUE;// ⑦ increment0if(OS_COUNTER_CHECKINVALIDVALUE(alarmCfg-counter,increment,cycle))returnE_OS_VALUE;// ⑧ 范围检查/* 第 4 阶段禁中断临界区 */Os_Arch_IntDisable(intState);/* 第 5 阶段激活 Alarm核心 */retOs_Alarm_IntSetRelAlarm(alarmDyn,increment,cycle);/* 第 6 阶段开中断 */Os_Arch_IntEnable(intState);returnOs_Hook_CallErrorHook(OSServiceId_SetRelAlarm,ret);}5.2.1 Os_Alarm_IntSetRelAlarmOs_Alarm_IntSetRelAlarm(alarmDyn,increment,cycle){if(alarmDyn!NULL_PTR){alarmDyn-stateOS_ALARM_SET;// ① 状态机OFF → SETalarmDyn-cyclecycle;// ② 保存周期值供到期后重插入retOs_Counter_InsertExpPoint(alarmDyn-counter,alarmDyn-expNode,increment);// ③ 插入过期点到 Counter}}5.2.1.1 Os_Counter_InsertExpPointOs_Counter_InsertExpPoint(counterBase,expListNode,increment){if(counterBase!NULL_PTR){valueOs_Counter_GetCntValue(counterBase);// ① 读当前 Counter 值Os_Counter_SetExpPoint(counterBase,value,increment,expListNode);// ② 计算时间戳 入队}}与 SetAbsAlarm 的差异 SetRelAlarm diff increment 相对值SetAbsAlarm diff start - value 绝对值转相对值5.2.1.1.1 Os_Counter_SetExpPointOs_Counter_SetExpPoint(counterBase,start,offset,expListNode){cntExpListHeadcounterBase-Os_CntExpList;/* 双队列选择处理 Counter 回绕 */if((counterBase-maxAllowValue-start)offset){// 不回绕过期点在当前周期内cntExpListCntcntExpListHead-cntExplistMux;// 用当前队列setExpTimebase(startoffset);// 时间戳 当前值 偏移ifCheakTRUE;}else{// 回绕过期点在下一周期cntExpListCnt(cntExpListHead-cntExplistMux1)OS_COUNTER_EXPLISTMAX;setExpTimebaseoffset-(counterBase-maxAllowValue-start1);ifCheakFALSE;}/* 设置过期点时间戳 */expListNode-expTimestamp.timebasesetExpTimebase;/* 入优先队列 */Os_PriQueue_PUSH(cntExpListHead-cntExpList[cntExpListCnt],(Os_PriQueueNodeType*)expListNode);/* 若是 HRT更新 STM 比较值 */if(OS_COUNTER_HRTcounterBase-counterType){cntDynOS_COUNTER_GETDYN(counterBase);if(OS_COUNTER_INITcntDyn-value){// 情况 ACMP0 未设置第一次设置retOs_Counter_GetQueueData(cntExpListHead,expTimebase);if(ret!E_OS_BUFFEMPTY){cntDyn-valueexpTimebase;// 取队头时间戳setCmpTRUE;}}elseif(ifCheakcntDyn-valuesetExpTimebase){// 情况 B新过期点比当前 CMP0 更早cntDyn-valuesetExpTimebase;// 更新为更早的时间戳setCmpTRUE;}if(TRUEsetCmp){Os_Counter_HrtSetCompareValue(counterBase,cntDyn-value);// ← 写 STM CMP0 寄存器}}}双队列环绕机制当Counter maxAllowValue 100不回绕offset 在当前周期内当前 Counter 30, offset 50maxAllowValue(100) - 30 70 50cntExpListCnt mux (当前队列)setExpTimebase 30 50 80回绕offset 超出当前周期当前 Counter 80, offset 50maxAllowValue(100) - 80 20 50cntExpListCnt (mux 1) 0x1 (下一队列)setExpTimebase 50 - (100 - 80 1) 50 - 21 29(下一周期的 29)5.3 Os_Arch_Mach_HrtTimerSetCompareValueOs_Arch_Mach_HrtTimerSetCompareValue(hrtCfg,value){*(volatileuint32*)(hrtCfg-ModulelCmpRegAddr)value;// 写 STM CMP0 寄存器}6. CancelAlarm整体调用链7. CancelAlarm调用栈8. CancelAlarm代码逻辑8.1 CancelAlarmOs_StatusTypeCancelAlarm(AlarmType AlarmID){#if(OS_MEMORY_PROTECTIONSTD_ON)Os_SysCallParamType sysCallParam;sysCallParam.Os_CancelAlarm.alarmIdAlarmID;Os_SysCall(Os_Syscall_CancelAlarm_ID,sysCallParam);// 走 SysCall trapretsysCallParam.Os_CancelAlarm.retVal;#elseretOs_Alarm_CancelAlarm(AlarmID);// 直接调用#endif}8.2 Os_Alarm_CancelAlarmOs_StatusTypeOs_Alarm_CancelAlarm(AlarmType alarmId){OS_ORTI_API_MONITOR_ENTRY(OSServiceId_CancelAlarm);coreIdOs_Core_GetLogicId();/* 第 1 阶段参数和上下文检查 */if(alarmIdOS_ALARMID_COUNT)returnE_OS_ID;// ① ID 范围if(OS_CORE_MASK_INTERRUPT(coreId))returnE_OS_DISABLEDINT;// ② 中断禁用if(OS_CORE_PROCESSTYPEMATCH(coreId,OS_CANCELALARM_ACCESS))returnE_OS_CALLEVEL;// ③ 调用上下文alarmCfgOS_ALARM_GETCFG(alarmId);if(OS_APPMATCH(alarmCfg-accessingApps,OS_CORE_GETAPPID(coreId)))returnE_OS_ACCESS;// ④ Permission/* 第 2 阶段多核路由 */#ifMULTI_COREif(coreId!OS_ALARM_GETCOREID(alarmCfg)){// 跨核消息转发到目标核Os_MultiCore_Trigger(TRUE,coreId,OS_ALARM_GETCOREID(alarmCfg),Os_MCServe_CancelAlarm_ID,parameter);return;}#endif/* 第 3 阶段状态检查 */if(OS_APP_STATEOFF(alarmCfg-ownerAppId))returnE_OS_ACCESS;// ⑤ Accessibilityif(OS_ALARM_SET!alarmDyn-state)returnE_OS_NOFUNC;// ⑥ 必须是 SET 状态/* 第 4 阶段禁中断临界区 */Os_Arch_IntDisable(intState);/* 第 5 阶段取消 Alarm核心 */Os_Alarm_IntCancel(alarmDyn);/* 第 6 阶段开中断 */Os_Arch_IntEnable(intState);returnOs_Hook_CallErrorHook(OSServiceId_CancelAlarm,ret);}8.2.1 Os_Alarm_IntCancelOs_Alarm_IntCancel(alarmDyn){if(alarmDyn!NULL_PTR){alarmDyn-stateOS_ALARM_OFF;// ① 状态机SET → OFFalarmDyn-cycleOS_ALARM_INIT;// ② 清除周期值防止下次误重插入(void)Os_Counter_ExpPointDel(alarmDyn-counter,alarmDyn-expNode);// ③ 从优先队列删除过期点}}8.2.1.1 Os_Counter_ExpPointDelOs_Counter_ExpPointDel(counterBase,expListNode){cntExpListHeadcounterBase-Os_CntExpList;cntExpListCntcntExpListHead-cntExplistMux;// ① 先查当前队列retOs_PriQueue_Del(cntExpListHead-cntExpList[cntExpListCnt],(Os_PriQueueNodeType*)expListNode);// ② 尝试删除if((E_OS_NODATAret)||(E_OS_BUFFEMPTYret)){// ③ 当前队列没找到查另一队列回绕情况cntExpListCnt(cntExpListHead-cntExplistMux1)OS_COUNTER_EXPLISTMAX;if(E_OS_NODATAOs_PriQueue_Del(cntExpListHead-cntExpList[cntExpListCnt],(Os_PriQueueNodeType*)expListNode)){retE_OS_NODATA;// ④ 两个队列都没有}}returnret;}双队列删除逻辑Counter 双队列结构:cntExpList[0] 当前周期队列 (mux0)cntExpList[1] 下一周期队列 (mux1)删除过期点时:先在 cntExpList[mux] 查找并删除若没找到 (NODATA/EMPTY)在 cntExpList[(mux1)0x1] 查找若都没找到返回 E_OS_NODATACancelAlarm 不更新 CMP0 的原因取消的过期点不是队头CMP0 对应的过期点CMP0 仍指向队头过期点不需要更新Counter 到期时 OS_HRT ISR 正常触发取消的过期点恰好是队头CMP0 对应的过期点CMP0 已经过时指向已删除的节点但 Counter 继续计数当 TIM0 CMP0 时仍会触发中断OS_HRT ISR 中弹出过期点时发现队列空或节点已删除会调用 Os_Counter_SetNextPoint 重新设置下一个过期点双队列删除的潜在问题取消过期点时Alarm1 的过期点在队头CMP0 仍指向 Alarm1 的时间戳Counter 继续计数…Counter 到达 CMP0 触发 OS_HRT ISRISR 弹出过期点 发现是已删除的 Alarm1队列可能空了调用 Os_Counter_SetNextPoint 取下一个过期点若无过期点CMP0 保持可能等到下次 SetRelAlarm 时重设。

相关新闻

数学建模集训:Python数据科学四件套实战整合指南

数学建模集训:Python数据科学四件套实战整合指南

1. 项目概述:集训冲刺期的核心技能整合如果你正在经历数学建模集训,到了第九天这个节点,感觉知识庞杂、工具繁多,不知从何下手进行整合与实战,那么你来的正是时候。今天我们不谈高深的理论,只聚焦于如何将P…

2026/10/24 8:16:25 阅读更多 →
Ryzen Embedded V2000 与 COM Express Type 6 模块的工程实践指南

Ryzen Embedded V2000 与 COM Express Type 6 模块的工程实践指南

1. 为什么这块 Type 6 模块值得嵌入式开发者关注上周看到一条模块厂商的新品公告,Type 6 模块正式搭载 Ryzen Embedded V2000 系列 SoC。如果你平时主要做工业主板、边缘计算设备或者医疗影像终端,应该明白这条消息的分量:前几年大家都在等一…

2026/10/24 9:30:02 阅读更多 →
端侧物理AI落地:Android端侧模型部署与量化实践

端侧物理AI落地:Android端侧模型部署与量化实践

近期端侧AI赛道迎来了一笔值得关注的融资:前海母基金以数亿元级别资金押注Om AI联汇,把“端侧物理AI”这个词重新拉到开发者面前。不少人看到这种新闻的第一反应是“又是一轮资本热点”,但如果只看热度,很容易错过真正重要的部分。…

2026/10/24 9:07:45 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/10/26 12:00:21 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/10/27 4:06:49 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/10/26 4:52:12 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/10/26 12:00:21 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/10/26 5:00:37 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/10/27 4:06:50 阅读更多 →

日新闻

周新闻

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/26 12:00:19 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/25 13:21:54 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/26 8:34:37 阅读更多 →