【OS基础】符合AUTOSAR标准的RTAOS-Alarms详解

目录

前言

正文

7.报警Alarms

7.1配置Alarms

7.1.1激活一个任务

7.1.2 设置一个事件

7.1.3报警回调Alarm Callback

7.1.4 增加计数器值

7.2设置Alarms

7.2.1 绝对Alarms

7.2.2 相对Alarm

7.3自启动Alarms

7.4 删除Alarms

7.5确认何时会发生Alarm

7.6非周期Alarms

7.7 小结


前言

本系列文章将以RTA-OS为例详细介绍AUTOSAR OS标准及概念,并分享实际使用的一些案例,本文为符合AUTOSAR标准的RTA-OS--Alarm介绍。

OS相关文章

4.1 【OS基础】符合AUTOSAR标准的RTA-OS-功能简介

4.2 【OS基础】符合AUTOSAR标准的RTA-OS-Task详解

4.3 【OS基础】符合AUTOSAR标准的RTA-OS-Interrupts详解

4.4 【OS基础】符合AUTOSAR标准的RTA-OS-Resources详解

4.5 【OS基础】符合AUTOSAR标准的RTA-OS-Event详解

4.6 【OS基础】符合AUTOSAR标准的RTA-OS-Counters详解

2.1 【OS】AUTOSAR架构下的OS错误处理

2.2 【OS】AUTOSAR架构下QM Application如何访问ASIL Application

2.3 【OS】AUTOSAR架构下多核启动

2.4 【OS】AUTOSAR架构下多核Shutdown

2.5 【OS】AUTOSAR架构下多核通信

2.6 【OS】RH850U2A芯片平台Spinlock的底层实现

2.7 【OS】AUTOSAR架构下MCAL Modules软件分区问题分析

2.8 【OS】AUTOSAR架构下的中断和异常向量表

2.9 【OS】AUTOSAR Os是如何启动第一个Task的

2.10 【OS】AUTOSAR OS系统调用产生Trap的过程详解

2.11 【OS】AUTOSAR OS如何实现Task抢占

2.12 【OS】AUTOSAR OS调度器实现原理


注:本文章引用了一些第三方工具和文档,若有侵权,请联系作者删除!

正文

7.报警Alarms

可以使用ISR构建以不同速率激活任务的系统。然而,对于复杂的系统,这可能会变得低效和不切实际。警报器(Alarms)提供了一种更方便、更便携的调度系统方式。

该报警机构由以下两部分组成:

1.一个计数器counter.

2.一个或多个报警器连接到计数器上。

报警(Alarm)指定在达到特定计数器值时要执行的操作。系统中的每个计数器都可以附加任意数量的报警(Alarm)。

当计数器的值等于附加到计数器的警报的值时,就说警报已经过期。在到期时,RTA-OS将执行与告警相关联的操作。该操作可以是激活任务(OsAlarmActiveTask)、执行警报回调例程(OsAlarmCallback)、设置事件(OsAlarmSetEvent)或增加计数器值(OsAlarmIncrementCounter)。

报警到期值可以相对于实际计数器值或定义为绝对值。如果报警失效定义为相对于实际计数器,则称为相对报警(Relative alarm)。如果将其定义为绝对值,则称为绝对警报(Absolute Alarm)。

警报可以配置为过期一次。一旦过期的警报被称为单次警报(Single-shot Alarm)。

还可以将警报指定为定期过期。这种类型的警报被称为循环警报(cyclic alarm)。您可以在第7.2节中找到更多关于循环警报的信息。

7.1配置Alarms

一个Alarm需要配置三个配置项:

1.名字 - 系统中的每个报警都需要分配一个唯一的名称。对于其他操作系统对象,这是将代码中在运行时引用警报的名称。

2.关联的计数器counter - 报警在配置时静态绑定到计数器。警报的任何设置都是根据相关计数器的滴答(ticks)数来完成的。

3.报警到期后的动作。

创建的每个报警最多包含4个动作:

1.激活一个任务

Figure 7.1: Activating a Task with an Alarm

2.触发一个事件(event)。

3.执行一个callback函数。

4.增加一个计数器(counter)的值。

如果需要激活多个任务、设置多个事件、进行多个回调或在到期时增加多个计数器,则需要具有相同到期值的多个警报。(调度表提供了一种替代机制,允许同时激活多个任务和/或设置多个事件。后面将在在调度表章节中阅读关于调度表的内容)。

7.1.1激活一个任务

警报最常见的动作是激活一个任务。这是构建具有定期激活任务的系统的基础——可以为每个任务创建一个警报,然后通过软件代码将警报设置为在所需的时间段内发生。图7.1显示了如何配置告警以激活任务。

7.1.2 设置一个事件

报警可以为指定的任务设置一个事件。当事件设置为警报时,它具有与使用SetEvent() API调用设置时相同的属性。这意味着用户需要同时指定事件和要为其设置事件的任务。图7.2显示了如何为告警设置事件操作。

Figure 7.2: Setting an Event for a Task with an Alarm

7.1.3报警回调Alarm Callback

每个报警都可以有一个关联的回调函数。回调只是一个C函数,在告警到期时被调用。

集成指导:根据AUTOSAR操作系统标准,报警回调只允许在可伸缩性级别1(Scalability Class 1)中进行。这是因为这些回调在操作系统级别上运行,因此可能会干扰定时保护,并在内存保护方案中出现一个漏洞。

Portability Note: RTA-OS允许放松这个限制,允许在General➔Optimizations➔RTA-OS中使用配置选项在所有可伸缩性类中允许警报回调。

图7.3显示了如何为报警配置回调函数。

Figure 7.3: Configuring a Callback Routine for an Alarm

每个回调函数都必须使用ALARMCALLBACK() 宏来编写,如示例7.1所示。

ALARMCALLBACK(UserProvidedAlarmCallback) {
/* Callback code. */
}

集成指导:回调例程在操作系统级别运行,这意味着2类中断被禁用。因此,应该是尽可能保持回调例程的精简,以最小化任务和ISR在运行时遭受的阻塞量。

用户可以在回调中进行的唯一使用的RTA-OS API调用是SuspendAllInterrupts() and ResumeAllInterrupts().

7.1.4 增加计数器值

警报增加软件计数器允许您从单个ISR级联多个计数器。由Alarm驱动(Ticked)的计数器Counter继承了警报的周期。所以,如果你有一个每5毫秒发生一次的警报,你可以使用警报来驱动一个秒级的Counter, 这个Counter的一个tick是5ms. 图7.4显示了在RTA-OS中是如何配置的。

Figure 7.4: Cascading counter increments from an alarm

示例7.2显示了如何从中断中驱动1毫秒计数器。在1毫秒计数器上注册的每五次中断将导致告警过期,并增加级联计数器5秒:

#include <Os.h>
ISR(MillisecondInterrupt){CLEAR_PENDING_INTERRUPT();Os_IncrementCounter(Counter1ms);
/* Every 5th call internally performs Os_IncrementCounter(Counter5ms) */
}

Example 7.2: Cascading Counters

级联计数器的滴答率(tick rate)必须是驱动报警的计数器的整数倍。用户可以使用多级级别的级联来配置系统。但是,如果您试在级联中配置一个循环系统或尝试增加硬件计数器,RTA-OS将生成错误。

集成指导:级联计数器的定时特性是相对于级联中第一个计数器的定时特性来定义的。因此,级联中最早的计数器决定了定义所有其他计数器的基本滴答率。如果您更改了最早计数器的标记率,则应用程序的整个计时行为将相应地缩放。

7.2设置Alarms

OS提供两个API用来设置Alarms:

SetAbsAlarm(AlarmID, start, cycle);

将报警设置为在计数器值下次到达时开始时失效。如果底层计数器在调用SetAbsAlarm时已经开始,那么在本次计数器周期内不会发生警报。

SetRelAlarm(AlarmID, increment, cycle);

增量式Alarm,即设置该Alarm后计数满足就执行该Alarm.

在这两个API调用中,周期值设置为0表示警报是单次触发警报,这意味着它在被取消之前只会过期一次。循环值大于零定义循环报警。这意味着在第一次到期后,它将继续使每个周期过期。设置非零周期值可以轻松地配置具有周期变化周期的周期性警报。

参数选着

如果被激活的任务是BCC1或ECC1/2,则将不会有排队的激活。这意味着,如果开始值或增量值非常短,或者开始值非常接近当前的计数器值,那么这可能会导致不希望产生的副作用。当先前激活的实例仍在执行时,警报将尝试激活该任务。激活将会丢失,并将引发一个E_OS_LIMIT错误。必须确保有足够的时间完成任务,然后才能导致任务重新触发任务。

7.2.1 绝对Alarms

单次触发

绝对报警指定报警失效的底层计数器的绝对值。单次触发绝对警报用于监控预定义的阈值非常有用——警报可以配置为在超过阈值时过期。用户可能希望计算在运行时获取的数据采样中发生的错误数量,然后在错误数量达到危险级别时触发恢复操作。这一点如示例7.3所示。

/* Expire when counter value reaches 42. */
SetAbsAlarm(DangerLevelReached, 42, 0);

Example 7.3: Absolute single shot alarm

示例7.3如图7.5所示。

Figure 7.5: Illustration of an Absolute Single Shot Alarm

当我们需要设置一个超时,然后等待一个固定的超时时间,然后在超时发生时采取动作时,单次触发报警很有用。

循环触发

如果绝对告报警指定了一个非零周期值,则它将首先在指定的起始点终止,然后在此后的每个周期终止。这一点如示例7.4所示。

Figure 7.6: Illustration of the Absolute Cyclic Alarm

/* Expire when counter value reaches 10 and then every 20 ticks thereafter
*/
SetAbsAlarm(Alarm1, 10, 20);

Example 7.4: Absolute cyclic alarm

对于绝对告警,零刻度的绝对起始值与任何其他值相同——这意味着当计数器达到零值时告警失效。

例如,如果当前计数器值为零,则将不会看到警报过期,直到计数器值的最大值+1数量发生。另一方面,如果计数器的值已经处于最大等值,那么就会看到警报在计数器的下一个tick上过期。

设置Alarm为过去值

设置为过去式Alarm时,需要等待MAXALLOWEDVALUE+1个Tick后才能到期。

注意:一个常见的错误是设置绝对Alarm在OS 起动后Counter为0时发生,这样的Alarm不会发生,因为0已经是过去发生的。

Figure 7.7: Setting an alarm in the past

将绝对循环Alarm同步到计数器包装

将Alarm设置为在已知的同步点定期发生对于实时系统非常重要。但是,在AUTOSAR操作系统中,不可能将绝对Alarm设置为每次基线计数器环绕时定期发生。

如果需要此类功能,则必须提供每次Alarm过期时重置绝对单次Alarm的代码。例如,如果Task1连接到Alarm1,则Task1的主体将需要在激活任务时重置Alarm,如下示例所示。

TASK(Task1) {/* Single-shot alarm reset at top dead center = 0 = 360 degrees. */SetAbsAlarm(Alarm1, 0, 0);/* User code. */TerminateTask();
}

Example 7.5: Resetting an Alarm when a Task is Activated

7.2.2 相对Alarm

单次触发

相对报警指定报警失效的底层计数器的绝对值。当用户想在运行时超时某些活动时,单次触发相对报警很有用。例如,用户可能希望等待一个外部事件,然后在该事件未发生时激活该任务。

Figure 7.8: Illustration of a Relative Single Shot Alarm

示例7.6显示了如何设置绝对单枪报警。

/* Timeout 42 ticks from now */
SetRelAlarm(Timeout, 42, 0);

Example 7.6: Relative single shot alarm

当用户需要设置一个超时,等待一个固定的超时时间,然后在超时发生时采取行动时,单次触发报警我们很有用。

在AUTOSAR操作系统中,禁止在SetRelAlarm()中使用零作为增量。如果您使用零作为增量,则将返回一个E_OS_VALUE错误。

循环触发

示例7.7显示了一个相对警报,在10次响后响一次,然后每20次响一次。

/* Expire after 10 ticks, then every 20 ticks. */
SetRelAlarm(Alarm1, 10, 20);

Example 7.7: Relative cyclic alarm

在图7.9中,可以看到如何可视化此报警。

Figure 7.9: Illustration of a Relative Cyclic Alarm

7.3自启动Alarms

虽然可通过在主函数中调用SetRelAlarm() 或 SetAbsAlarm() API来起动Alarm,但最简单的调用周期Alarms方式是在STARTOS()后自启动Alarm。

自启动Alarm需声明其为绝对还是相对Alarm,counter及周期值。

Figure 7.10: Auto-starting Alarms

RTA-OS确保软件计数器在StartOS()期间初始化为零(硬件计数器将设置为您自己的应用程序初始化代码配置的值)。因此,如果对绝对Alarm使用零刻度开始时间,则必须小心,因为在Alarm启动时,零刻度已经发生。虽然Alarm将启动,但在相关计数器变为零之前,Alarm不会过期。在一个16位计数器上,每毫秒Tick增加一次,你需要等待超过65秒,然后在一个32位计数器上等待不到48天。指定Alarm在第一次(或以后)勾选时开始表示初始到期将在计数器的下一次勾选时发生。如果需要Alarm彼此同步(即Alarm之间的相对过期时间必须间隔预先设定的刻度数),则自动启动绝对Alarm非常有用。

7.4 删除Alarms

可以通过调用CancelAlarm() API来删除Alarm,例如,可能需要取消Alarm以停止正在执行的特定任务。可以使用SetAbsAlarm()或SetRelAlarm() API调用重新启动Alarm。

7.5确认何时会发生Alarm

当用户需要确认Alarm何时会发生,如对于绝对Alarm,为了避免已经达到的值被设置时可以通过调用Get Alarm() API获取。该调用返回指定Alarm到期前剩余的Tick数。如果未设置Alarm,则API调用将返回值E_OS_NOFUNC,到期的刻度数未定义。建议在使用结果之前检查调用的返回值。示例7.8显示了API调用的使用情况。

TickType TimeToExpiry;TickType SafetyMargin = 100;StatusType IsValid;IsValid = GetAlarm(Alarm1, &TimeToExpiry);if (IsValid != E_OS_NOFUNC) {    if (TimeToExpiry <= SafetyMargin) {      Log(InsideSafetyMargin);  }}

Example 7.8: Getting the time to expiry

在根据调用返回的Tick值出运行时决策时,尤其是在底层计数器具有高分辨率的情况下,应特别小心。与使用GetCounterValue() 读取计数器值一样,在获取该值和使用该值进行计算之间可能会发生抢占。这意味着可能会读取(很长)到期时间,但随后会被抢占,以便在Alarm到期前不久(甚至在Alarm到期后)恢复。

7.6非周期Alarms

周期报警只对循环行为有用。在许多系统中,例如那些需要定期执行任务来轮询数据源的系统中,这是非常理想的。但是,用户可能需要对在运行时需要更改的系统进行编程。例如,正在计算一个发动机轴转速,并使用它来编程火花或喷射定时的持续时间。

需要使用单次触发警报对具有警报的非周期行为进行编程,并由激活的任务设置为下一个到期值。

在示例7.9中,一个任务每毫秒运行一次,并轮询一个记录曲轴旋转度的计数器。该任务将计算曲柄的位置和速度。速度用于确定火花定时的持续时间。火花启动,警报设置为在SparkTiming ticks到期后。

TASK(MillisecondTask) {...GetElapsedCounterValue(ShaftEncoder,&Position,&DegreesRotation);RevsPerMinute = (DegreesRotation/360) * 1000 * 60;SparkTiming = Lookup(RevsPerMinute);if (Position == 90) {StartSpark();SetRelAlarm(TimeCounter, SparkTiming, 0); /* Activates SparkOff onexpiry */ }
}
...
TerminateTask()
}
​
TASK(SparkOff){StopSpark();TerminateTask();
}
Example 7.9: Aperiodic Alarm Example

7.7 

  • Alarms是基于counter设置的,同一个Counter可设置多个Alarms;

  • 每个Alarm执行的操作可能为:执行某个Task、设置个Event、执行某回调函数或增加一个计数器;

  • Alarm可设置绝对或相对counter值;

  • Alarm可配置为自启动模式。

  • 实际应用中一般采用调度表来调度,Alarms应用相对比较少。

参考文档:

[1] RTA-OS V6.1.3 User Guide

[2] Specification of Operating System AUTOSAR Release 4.2.2

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/30094.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

细致解析跨境电商多平台搭建利器-179海关接口源码应用方法

介绍 跨境电商已成为当前电商行业的热门发展方向之一。为满足跨境电商的需求&#xff0c;各大平台纷纷推出了多平台搭建利器。其中&#xff0c;179海关接口源码是一款非常实用的工具&#xff0c;本文将对其应用方法进行细致解析。 了解179海关接口源码 179海关接口源码可以帮…

2024最新版Vcpkg安装第三方库报错error: building XXXX failed with: BUILD_FAILED

很多朋友用Vcpkg安装第三方库的时候基本都会遇到报错的情况&#xff0c;而且大部分都会出现下面这个页面里面的红色报错信息&#xff0c;但是实际上真正错误应该是上面的Cmake Error提示&#xff0c;下面的红色警告只是Vcpkg官方提供给我们的一个最基础的解决方式&#xff0c;而…

【Docker系列】深入解析 Docker 容器部署脚本

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

【稳定检索/投稿优惠】2024年生物技术与食品科学国际会议(ICBFS 2024)

2024 International Conference on Biotechnology and Food Science 2024年生物技术与食品科学国际会议 【会议信息】 会议简称&#xff1a;ICBFS 2024 大会时间&#xff1a;点击查看 截稿时间&#xff1a;点击查看 大会地点&#xff1a;中国厦门 会议官网&#xff1a;www.icb…

汇聚荣优势是什么?

汇聚荣优势是什么?在探讨企业成功之道时&#xff0c;我们不得不提及“汇聚荣优势”这一概念。简而言之&#xff0c;它指的是企业通过整合内外部资源&#xff0c;形成独特的竞争优势&#xff0c;以实现持续发展与市场领先地位的战略行为。这种优势的构建不是一蹴而就的&#xf…

生信网络学院|06月21日《SolidWorks Costing助力制造企业建立成本核算体系》

课程主题&#xff1a;SolidWorks Costing助力制造企业建立成本核算体系 课程时间&#xff1a;2024年06月21日 14:00-14:30 主讲人&#xff1a;张丹清 生信科技 售前顾问 Costing成本分析简介钣金件成本分析加工件成本分析装配体成本分析总结&答疑 安装腾讯会议客户端或…

Windows上使用vscode配置C/C++编译环境

GCC和GDB 一句话概括&#xff1a;gcc用来编译C&#xff0c;gdb用来调试C。 GCC (GNU Compiler Collection) GCC&#xff08;GNU编译器套件&#xff09;是一个由GNU项目开发的编译器系统&#xff0c;支持多种编程语言&#xff0c;如C、C、Objective-C、Fortran、Ada和Go等。G…

ARM32开发-fat_fs文件系统

FAT_FS 文件系统 FAT (File Allocation Table) 文件系统是一种广泛使用的基于磁盘的文件系统,尤其适用于小型嵌入式系统和存储卡。FAT_FS 就是一个专门针对 FAT 文件系统的开源实现。 FAT_FS 的主要特点 轻量级和高度可移植: FAT_FS 是一个非常轻量级的文件系统实现,占用资源少…

人脸识别考勤机给企业带来了哪些好处

人脸识别考勤机给企业带来了哪些好处 随着考勤软件在国内各企业中逐渐使用&#xff0c;人们对于考勤的这种方式已不再生疏&#xff0c;传统的纸质签到、指纹打卡已因存在不灵敏、易作弊、难统计等诸多弊病&#xff0c;逐步被可以管理考勤的手机软件索取代&#xff1b; 近些…

【网络安全的神秘世界】渗透之信息收集流程

&#x1f31d;博客主页&#xff1a;泥菩萨 &#x1f496;专栏&#xff1a;Linux探索之旅 | 网络安全的神秘世界 | 专接本 | 每天学会一个渗透测试工具 渗透测试之信息收集 切记&#xff1a;搜索到敏感信息之后&#xff0c;不要随意下载和传播&#xff0c;属于违法行为&#xf…

如何基于ITIL构建有效的IT服务管理体系

在数字经济时代&#xff0c;IT服务管理已成为企业运作的核心支撑。随着信息技术的快速发展和应用&#xff0c;企业对IT服务的需求不断增加&#xff0c;而如何高效地管理这些服务成为一个重要挑战。基于ITIL&#xff08;信息技术基础架构库&#xff09;构建有效的IT服务管理体系…

Virtualbox7.0版本安装报错:Invalid installation directory

错误情况 我在安装virtualbox最新版7.0.18时候&#xff0c;因为默认安装在C盘&#xff0c;我改成了E盘&#xff0c;然后就报错 Invalid installation directory The chosen installation directory is invalid, as it does not meet the security requirements. Refer to th…

那些年我为了考PMP踩过的坑.....

说到考PMP我尊嘟很难过且伤心&#xff0c;众所周知&#xff0c;报考PMP都是要报机构的而且还是PMI认证的机构&#xff0c;所以在报考PMP过程中选的机构我可以说踩过了很多坑了...... Q&#xff1a;包过吗&#xff1f; 大家千万不要信某某机构说的包过噱头&#xff0c;真的很坑…

4000字读懂实时数仓的过去现在和未来(建议收藏)

1991年&#xff0c;比尔恩门&#xff08;Bill Inmon&#xff09;出版了他的第一本关于数据仓库的书《Building the Data Warehouse》&#xff0c;标志着数据仓库概念的确立。 我们所常说的企业数据仓库Enterprise Data Warehouse (EDW) &#xff0c;就是一个用于聚合不同来源的…

【嵌入式】嵌入式Linux开发实战指南:从交叉编译到触摸屏交互

文章目录 前言&#xff1a;1.简介1.1. 交叉编译工具1.2. 项目开发流程&#xff1a;1.3. ARM开发板的连接方法 2. 开发板连接3. 系统文件 IO4. 设置共享文件夹3.1. 读文件3.2. 写文件3.2. 设置文件偏移量 4. LCD显示屏显示4.1. LCD 显示颜色4.2. 将文件下载到开发板4.2.1. 在CRT…

002.Linux CentOS7 安装

我 的 个 人 主 页&#xff1a;&#x1f449;&#x1f449; 失心疯的个人主页 &#x1f448;&#x1f448; 入 门 教 程 推 荐 &#xff1a;&#x1f449;&#x1f449; Python零基础入门教程合集 &#x1f448;&#x1f448; 虚 拟 环 境 搭 建 &#xff1a;&#x1f449;&…

Git Extensions gui工具差异显示乱码

某些IDE例如KEIL等默认编码格式为GB2312&#xff0c;而git extensions默认utf-8&#xff0c;如果不想修改文件格式为utf-8的话就修改git extensions格式为GB2312。 默认是没有chines 这个选项的&#xff0c;我这里是已经添加好的。方法为上方工具栏->设置->Git->设置…

Linux C编译器从零开发三

AST语法树 BNF抽象 expr equality equality relational ("" relational | "!" relational)* relational add ("<" add | "<" add | ">" add | ">" add)* add mul ("" …

为什么很多Java程序员会下意识觉得Java的就是最好的?

在开始前刚好我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「Java的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&#xff01;做为一个真正热爱编程&#…

【并发程序设计】总篇集 Linux下 C语言 实现并发程序

11_Concurrent_Programing 文章目录 11_Concurrent_Programing1.进程概念进程内容进程类型进程状态 2.进程常用命令进程信息命令top 命令进程信息表 进程优先级命令nice 命令renice 命令 后台进程命令 3.子进程创建子进程fork 函数 结束进程exit 函数_exit 函数 回收子进程wait…