RTA OS系列介绍04-Alarm
本文框架
- 1.概述
- 1.1Alarm的大概流程
- 1.2单发与周期Alarm
- 2.Alarms 配置与功能
- 2.1Alarms配置
- 2.2 Alarms的功能
- 2.2.1 激活任务
- 2.2.2 设置Event
- 2.2.3 Alarm回调函数
- 2.2.4 增加一个计数器
- 3 Alarms应用
- 3.1 Alarm设置
- 3.1.1 绝对Alarms设置
- 3.1.2 相对Alarm
- 3.2自启动Alarms
- 3.3 取消Alarms
- 3.4确认何时会发生Alarm
- 4 本文总结
- 5. RTA-OS系列文章汇总
1.概述
在项目开发中,除利用调度表对Task进行调度外,还可以通过Alarm调用任务。使用Alarm机制主要包括两个部分:
- 一个计数器;即对任务的执行时机计时,设定所需的Counter;
2.一个或多个关联到该计数器的Alarm,系统中的每个计数器可以连接任意数量的Alarm。
Alarm部分规定了达到特定计数器值时要执行的操作。
1.1Alarm的大概流程
选定计数器→关联Task或其他动作→设定Counter→是当计数器的值等于该Alarm预先设定的值时,Alarm到期后RTA-OS会执行一些动作。可以是激活某个task,执行alarm回调函数或设置一个event等
1.2单发与周期Alarm
按Alarm配置使能后作用的次数,可以分为单发与周期两种Alarm:
单发Alarm:Alarm可以配置为到期使能一次;
周期Alarm:Alarm也可以配置为周期性到期,这种被称为周期Alarm
2.Alarms 配置与功能
2.1Alarms配置
Alarm有三处需要配置:名称、计数器与对应操作。
名称:不同Alarm不同;
计数器:与某counter关联,Alarm的任何设置都是根据相关计数器的Tick来完成的;
对应操作,每个alarm可以关联的四种操作:
1) 激活Task;
2) 设置个Event;
3) 执行个回调函数;
4) 增加一个软件计数器。
如果需要激活多个任务,设置多个events,执行多个回调函数或增加多个软件计数器就需要多个Alarms,这点是与调度表的区别点。
2.2 Alarms的功能
2.2.1 激活任务
Alarm最常用的功能为激活某个任务,为每个任务创建一个alarm,再按需要的周期触发Alarm。
在AUTOSAR-OS中,每个alarm只允许激活一个task,如需要一个alarm到期激活多个task,则需要创建多个Task或使用Task链激活。
2.2.2 设置Event
Alarm可以作为一个特殊的任务设置Event,通过Alarm设置Event与通过调用SetEvent() API达到的效果相同。这意味着需要同时指定事件和要为其设置事件的任务。
2.2.3 Alarm回调函数
每个Alarm都可以有相关联的回调函数,每个回调函数都需通过ALARMCALLBACK()宏来编写,如下:
ALARMCALLBACK(UserProvidedAlarmCallback) {/* Callback code. */
}
Alarm触发的回调函数是在OS Level运行,这意味着二类中断是禁止的,应该力求使回调函数尽可能短,以尽量减少任务和ISR在运行时遭受的阻塞量。
可以在回调中进行的唯一RTA-OS API调用是SuspendAllInterrupts()和ResumeAllInterrupts()调用。
2.2.4 增加一个计数器
通过增加Alarm中的软件计数器,可以级联单个ISR中的多个计数器。从Alarm中勾选的计数器将继承原Alarm的周期。
级联计数器的频率必须是驱动Alarm的计数器的整数倍。但是,如果在级联中配置具有循环的系统,或者尝试增加硬件计数器,RTA-OS将产生错误。级联计数器的定时特性与级联中第一个计数器的定时特性相关。因此,级联中最早的计数器决定了确定所有其他计数器的基准频率。如果更改最早计数器的计时速率,则应用程序的整个计时行为将相应地缩放。
如下示例描述了一个级联计数器,显示了如何从中断驱动1ms计数器。1ms计数器上记录的每五次中断都会导致Alarm过期,并增加级联计数器5ms:
#include <Os.h>
ISR(MillisecondInterrupt){CLEAR_PENDING_INTERRUPT();Os_IncrementCounter(Counter1ms);/* Every 5th call internally performs Os_IncrementCounter(Counter5ms) */
}
3 Alarms应用
3.1 Alarm设置
可通过两个API设置Alarms:
SetAbsAlarm(AlarmID, start, cycle);
绝对式Alarms,会在下次Counter达到后到期,开始执行。如在Set Alarm前,时钟已开始计数则在当次周期不会执行。
SetRelAlarm(AlarmID, increment, cycle);
增量式Alarm,即设置该Alarm后计数满足就执行该Alarm。
在这两个API调用中,周期值为零表示该Alarm为单次触发Alarm,这意味着该Alarm在取消之前只会过期一次。循环值大于零表示循环Alarm。这意味着它将在第一次到期后的每个周期内继续到期。通过设置非零周期值,可以方便地配置周期性Alarm,这些Alarm以周期性Tick的周期性出现。
选取参数
如果激活的任务是BCC1或ECC1/2,则不会有排队激活。这意味着,如果起始值或增量值非常短,或者起始值非常接近当前计数器值,则这可能会导致不期望的副作用。当先前激活的实例仍在执行时,Alarm将尝试激活任务。激活将丢失,并引发E_OS_LIMIT错误,必须确保在下一个导致任务重新触发的Alarm发生之前,有足够的时间完成任务。
3.1.1 绝对Alarms设置
单发Alarm
绝对Alarm指定Alarm过期的基础计数器的绝对值。单触发绝对Alarm可用于根据预先定义的阈值监控事件-当超过阈值时,Alarm可配置为过期。您可能希望统计运行时采集的数据样本中发生的错误次数,然后在错误数达到危险级别时触发恢复操作。示例代码如下:
/* Expire when counter value reaches 42. */
SetAbsAlarm(DangerLevelReached, 42, 0);
当需要设置等待固定时间量的超时,然后在超时发生时采取措施时,单次触发Alarm非常有用。
周期Alarm
如果绝对Alarm指定了一个非零周期值,则它将首先在指定的起始点终止,然后在此后的每个周期终止。如下所示。
/* Expire when counter value reaches 10 and then every 20 ticks thereafter */
SetAbsAlarm(Alarm1, 10, 20);
设置Alarm为过去值
设置为过去式Alarm时,需要等待MAXALLOWEDVALUE+1个Tick后才能到期。
注意:一个常见的错误是设置绝对Alarm在OS 起动后Counter为0时发生,这样的Alarm不会发生,因为0已经是过去发生的。
将绝对循环Alarm同步到计数器包装
将Alarm设置为在已知的同步点定期发生对于实时系统非常重要。但是,在AUTOSAR操作系统中,不可能将绝对Alarm设置为每次基线计数器环绕时定期发生。
如果需要此类功能,则必须提供每次Alarm过期时重置绝对单次Alarm的代码。例如,如果Task1连接到Alarm1,则Task1的主体将需要在激活任务时重置Alarm,如下示例所示。
TASK(Task1) {/* Single-shot alarm reset at top dead center = 0 = 360degrees. */SetAbsAlarm(Alarm1, 0, 0);/* User code. */TerminateTask();
}
3.1.2 相对Alarm
单发模式,能达到与绝对模式相同的目标,示例代码如下:
/* Timeout 42 ticks from now */
SetRelAlarm(Timeout, 42, 0);
同样,在AUTOSAR OS中不允许使用Counter 0来计时,如出现则会报错。
周期触发模式示例如下:
/* Expire after 10 ticks, then every 20 ticks. */
SetRelAlarm(Alarm1, 10, 20);
3.2自启动Alarms
虽然可通过在主函数中调用SetRelAlarm() 或 SetAbsAlarm() API来起动Alarm,但最简单的调用周期Alarms方式是在STARTOS()后自启动Alarm。
自启动Alarm需声明其为绝对还是相对Alarm,counter及周期值。
RTA-OS确保软件计数器在StartOS()期间初始化为零(硬件计数器将设置为您自己的应用程序初始化代码配置的值)。因此,如果对绝对Alarm使用零刻度开始时间,则必须小心,因为在Alarm启动时,零刻度已经发生。虽然Alarm将启动,但在相关计数器变为零之前,Alarm不会过期。在一个16位计数器上,每毫秒Tick增加一次,你需要等待超过65秒,然后在一个32位计数器上等待不到48天。指定Alarm在第一次(或以后)勾选时开始表示初始到期将在计数器的下一次勾选时发生。如果需要Alarm彼此同步(即Alarm之间的相对过期时间必须间隔预先设定的刻度数),则自动启动绝对Alarm非常有用。
3.3 取消Alarms
可以通过调用CancelAlarm() API来取消Alarm,例如,可能需要取消Alarm以停止正在执行的特定任务。可以使用SetAbsAlarm()或SetRelAlarm()API调用重新启动Alarm。
3.4确认何时会发生Alarm
当用户需要确认Alarm何时会发生,如对于绝对Alarm,为了避免已经达到的值被设置时可以通过调用Get Alarm() API获取。该调用返回指定Alarm到期前剩余的Tick数。如果未设置Alarm,则API调用将返回值E_OS_NOFUNC,到期的刻度数未定义。建议在使用结果之前检查调用的返回值。
在根据调用返回的Tick值出运行时决策时,尤其是在底层计数器具有高分辨率的情况下,应特别小心。与使用GetCounterValue()读取计数器值一样,在获取该值和使用该值进行计算之间可能会发生抢占。这意味着可能会读取(很长)到期时间,但随后会被抢占,以便在Alarm到期前不久(甚至在Alarm到期后)恢复。
4 本文总结
Alarms是基于counter设置的,同一个Counter可设置多个Alarms;
每个Alarm执行的操作可能为:执行某个Task、设置个Event、执行某回调函数或增加一个计数器;
Alarm可设置绝对或相对counter值;
Alarm可配置为自启动模式。
实际应用中一般采用调度表来调度,Alarms应用相对比较少。
5. RTA-OS系列文章汇总
1)RTA-OS系列介绍-Task
2)RTA-OS系列介绍-中断
3)RTA-OS系列介绍-资源
4)RTA-OS系列介绍-Event
RTA OS系列介绍04-Alarm相关推荐
- RTA OS系列介绍05-调度表
本文框架 1.概述 1.1 调度表常用术语 1.2 调度表操作模式 2.调度表配置 2.1 调度表配置 2.1.1 同步 2.2 到期点的配置 3.调度表的使用 3.1 启动调度表 3.3.1 绝对值 ...
- UDS诊断系列介绍08-19服务
本文框架 1. 系列介绍 1.1 19服务概述 1.2 DTC故障码定义 1.3 DTC状态位 2. 19服务常用子服务 2.1 19 01服务 2.2 19 02服务 2.3 19 04服务 2.4 ...
- UDS诊断系列介绍05-27服务
本文框架 1. 系列介绍 27服务概述 2. 27服务请求与应答 2.1 27服务请求 2.2 27服务肯定应答 2.3 27服务否定应答 1. 系列介绍 UDS(Unified Diagnostic ...
- 【SHQi——单片机系列(一)】| STC89C52单片机 | 入门向 | 单片机系列介绍
单片机系列介绍 1.什么是单片机 单片机,全称:单片微型计算机(Single Chip Microcomputer) 英文:Micro Controller unit,简称为 MCU 是一种集成电路芯 ...
- Autosar模式管理系列介绍01-BswM
本文框架 1.概述 2. BswM属性介绍 2.1 模式仲裁 2.1.1 Rules 2.1.2 LogicalExpression 2.2 模式控制 2.3 基本控制过程 3. BswM功能介绍 3 ...
- 【ENVI入门系列】04.图像几何校正
[ENVI入门系列]04.图像几何校正 (2014-09-23 10:15:13) 转载▼ 标签: 杂谈 分类: ENVI 版权声明:本教程涉及到的数据仅供练习使用,禁止用于商业用途. 目录 图像几何 ...
- Python语言学习:创建/删除文件/文件夹、获取当前文件/文件夹路径(系统环境路径/目录)、获取当前文件夹下的所有子文件路径等代码(os系列用法)实现之详细攻略
Python语言学习:创建/删除文件/文件夹.获取当前文件/文件夹路径(系统环境路径/目录).获取当前文件夹下的所有子文件路径等代码(os系列用法)实现之详细攻略 目录 系统环境路径的设置 1.sys ...
- Maven精选系列--介绍与安装
转载自 Maven精选系列--介绍与安装 Maven介绍 Maven是一个项目管理工具,用来管理项目的生命周期,如项目中各个项目之间的依赖管理,项目中使用到的jar包依赖管理,还有许多项目构建的插件等 ...
- UDS诊断系列介绍13-31服务
本文框架 1. 系列介绍 1.1 31服务概述 2. 31服务请求与应答 2.1 31服务请求 2.2 31服务正响应 2.3 31服务否定响应 3. Autosar系列文章快速链接 1. 系列介绍 ...
最新文章
- python加减法视频教程免费_一起学opencv-python三十八(视频分析:背景减法)
- 网络命令大全(9)--runas
- dos2unix命令找不到_Linux系统中的dos2unix命令
- 如何用一行 CSS 实现 10 种现代布局?
- 自适应采样次数的Ransac算法
- 前端开发面试题-JavaScript(二)
- phpexcel 导入导出
- App云测试服务对比
- HTML5+CSS大作业——学生个人博客(5页) 大学生个人博客网页作品 网页设计作业模板 学生网页制作源代码下载
- c 获取本地计算机ip,C++获取本机IP地址
- 密码学0930大作业
- IntelliJ IDEA 中如何配置JDK
- v12.2.8 released版本介绍--2019_7
- js: 获取最近3天、1周、1个月、3个月、半年、1年的时间
- Windows 平台下AMD 显卡加速pytorch训练
- php如何将图片gif,jpg或mysql longblob或blob字段值转换成16进制字符串!
- spark java mysql 连接数据库_Spark入门:通过JDBC连接数据库(DataFrame)
- 学习设计模式之原型模式
- 发票盖章不清晰,盖了两个章怎么办?官方说法来了
- DirectX Jun2010 安装error S1023