前言
本系列文章将以RTA-OS为例详细介绍AUTOSAR OS标准及概念,并分享实际使用的一些案例,本文为符合AUTOSAR标准的RTA-OS--Counters介绍。
符合AUTOSAR标准的RTA-OS --功能简介
(资料图片)
符合AUTOSAR标准的RTA-OS --Task详解
符合AUTOSAR标准的RTA-OS --Interrupts详解
符合AUTOSAR标准的RTA-OS --Resources详解
符合AUTOSAR标准的RTAOS--Event详解
正文
Example 6.1: Using a periodic interrupt to tick a software counter
软件计数器的另一个常见用途是作为容错系统的一部分,在超过错误阈值时需要采取某些操作。软件计数器可用于记录错误的数量,然后可以使用警报来触发恢复操作(例如,激活错误恢复任务)。
例6.2展示了名为Critical的任务如何在名为ErrorCounter的计数器上记录错误。
Example 6.2: Using a periodic Task to tick a software counter
静态计数器接口Static Counter Interface:
由于AUTOSAR API调用将计数器的名称作为参数,这意味着RTA-OS必须在更新OS数据结构之前在内部取消对参数的引用。这也意味着编译器需要在进入时将参数压入堆栈。
然而,通常情况下,在构建时就知道将从何处计时哪个计数器。可能需要从中断处理程序驱动计数器。
RTA-OS认识到这一点,并为配置文件中声明的每个计数器生成一个专用的API调用Os_IncrementCounter_
集成指南:API调用Os_IncrementCounter_
例如,考虑一个包含两个计数器的应用程序:一个名为TimeCounter,另一个名为AngularCounter。rtaosgen将生成例6.3中所示的两个API调用。
为定时器和角中断提供服务的中断处理程序必须调用这些API调用。
例6.4展示了这些中断处理程序。
Example 6.4: Interrupt Handlers for Example 6.3
Example 6.5: Making multiple calls to the static software counter interface
如果您有多个软件计数器,您需要以相同的速率tick,可以在处理程序中进行多个Os_IncrementCounter_
对于声明的每个计数器,都有一个Os_IncrementCounter_
6.2.2 硬件计数器驱动Hardware Counter Drivers
对于每个硬件计数器,User需要提供调用RTA-OS的硬件计数器驱动程序和RTA-OS使用的一组回调。与软件计数器一样,RTA-OS提供了一个定义良好的接口,用于将高级计数器驱动程序连接到操作系统。
集成指南:AUTOSAR OS标准没有指定处理硬件计数器的标准API调用。如果要将应用程序从另一个操作系统移植到RTA-OS,则可能需要更改硬件计数器驱动程序API调用。
对于每个硬件计数器,RTA-OS知道该计数器驱动的下一个动作是什么,是使警报过期,还是处理调度表上的过期点,或者两者兼而有之。RTA-OS还知道在发生这种情况之前需要经过多少滴答。这被称为匹配值。
图6.3 Advanced Counter Driver Model
当使用软件计数器时,驱动程序会在每次计时结束时告诉RTA-OS。RTA-OS在内部对刻度进行计数,当达到匹配值时,采取操作。然后RTA-OS计算下一个匹配值并重复该过程。
相比之下,当使用硬件计数器时,RTA-OS通过回调函数告诉驱动程序何时需要进行下一个操作。外设计算请求的滴答数,并在正确的滴答数耗尽时生成中断。在中断处理程序中,可以调用Os_AdvanceCounter_CounterID() API来告诉RTA-OS处理CounterID上的下一个操作。RTA-OS这样做,然后重复这个过程。
通常,User将使用中断来驱动软件和硬件计数器。对于软件计数器,无论RTA-OS是否有任何事情要做,每个计数器滴答都会发生中断。对于硬件计数器,只有当RTA-OS需要做某事时才会发生中断。这意味着硬件计数器将中断干扰减少到所需的绝对最小值。
Advancing Hardware Counters
User使用API调用Os_AdvanceCounter_
集成指南:User负责编写调用Os_AdvanceCounter_
Os_AdvanceCounter_
Callback Functions
对于软件计数器,RTA-OS在内部计算经过的滴答数。这意味着RTA-OS总是知道当前的计数器值,在下一次到期之前有多少个滴答等等。
对于硬件计数器,外设计算经过的滴答数。这意味着RTA-OS必须告诉硬件计数器它需要计数多少个节拍,并且必须询问外设当前的计数值,到下一个到期的节拍数等。
这种交互是使用回调函数在RTA-OS和您想用作计数器驱动程序的任何类型的硬件外设之间进行接口的。回调函数的确切功能性取决于用作硬件计数器驱动程序的外设。
然而,通过一个简短的概述,需要四个回调:
Os_Cbk_Set_
这个回调为下一个动作到期时发生的中断设置状态。回调函数被传递一个计数器的绝对值,在这个计数器上应该发生一个动作。对于计数器,这个回调在两种不同的情况下使用:
1. 开始Starting
当Schedule Table或Alarm在计数器上启动时,设置初始中断源。
2. 重置Resetting
缩短到下一个计数器到期的时间。这是必要的,例如,当下一个中断超过100个滴答时,做一个SetRelAlarm(WakeUp, 100)调用。
Example 6.6: Using GetAlarmBase() to read static counter attributes
Os_Cbk_State_
此回调返回计数器上的下一个操作是否挂起,以及(通常)在达到匹配值之前剩余的tick数。
Os_Cbk_Now_
此回调需要返回外部计数器的当前值。这用于GetCounterValue() API调用。
Os_Cbk_Cancel_
这个回调必须为计数器清除任何挂起的中断,并确保中断不能成为挂起,直到一个Os_Cbk_Set_
集成指南:硬件计数器可用于多核系统。RTA-OS将确保State, Set和Cancel回调只在拥有计数器的核心上被调用。这意味着User可以从拥有计数器的不同核心启动alarm和ScheduleTables, RTA-OS将向计数器的核心发送消息,告诉它调用适当的回调。
6.3运行时获取计数器属性Accessing Counter Attributes at Run time
RTA-OS API调用GetAlarmBase()总是返回配置的计数器值。GetAlarmBase()的结构如例6.6所示。
配置的值也可以以符号常量的形式访问,如下所示。
• OSMAXALLOWEDVALUE_
• OSTICKSPERBASE_
• OSMINCYCLE_
因此,上面的例6.6也可以写成例6.7:
Example 6.7: Using macros to read static counter attributes
6.3.1 特殊的计数器名Special Counter Names
如果创建了一个名为SystemCounter的计数器,那么在AUTOSAR OS中可以通过省略末尾的_CounterID来使用简短的宏形式访问相关的计数器属性:
OSMAXALLOWEDVALUE_SystemCounter ➔ OSMAXALLOWEDVALUE
OSTICKSPERBASE_SystemCounter ➔ OSTICKSPERBASE
OSMINCYCLE_SystemCounter ➔ OSMINCYCLE
RTA-OS为SystemCounter生成两种形式的宏,User可以使用任何一种版本。SystemCounter还提供了一个额外的宏来获取计数器滴答的持续时间(以纳秒为单位),称为OSTICKDURATION。
集成指导:生成一个有意义的OSTICKDURATION宏需要配置计数器属性“Seconds Per Tick”。
6.4 读取计数器值Reading Counter Values
应用程序需要能够在运行时读取计数器的当前值。例如,User可能想知道错误计数器记录了多少错误,按钮被按了多少次,或者经过了多少时间。
计数器的当前值可以在运行时通过调用GetCounterValue() API来读取,如例6.8所示。
Example 8.8: Using GetCounterValue()
当使用GetCounterValue()时,应该意识到:
•计数器从MAXALLOWEDVALUE到零,因此计算需要补偿。Counters wrap around from MAXALLOWEDVALUE to zero, so the calculation needs to compensate for the wrap
•抢占可以在调用返回时发生,这意味着当您恢复时," Now "的值将是旧的
•当使用硬件计数器时,当调用返回时,计数器驱动程序仍将递增。即使没有发生抢 占,立即执行的计算也将基于旧数据
如果需要执行一个简单的计算来计算自上次读取值以来计数器经过了多少次计时,那么可以通过使用GetElapsedCounterValue() API调用来避免这种潜在的竞争条件。该调用将先前读取的计数器值作为输入,并计算已经过的刻度,包括对计数器包装的补偿。计算发生在操作系统级别(即禁用中断),因此不会受到抢占效应的影响。
示例6.9显示了如何使用此特性来度量任务的端到端(响应)时间。
Example 6.9: Using GetElapsedCounterValue()
如果计数器正在计算时间刻度(如例6.9),那么这在AUTOSAR OS中被称为“自由运行计时器free running timer”。这种类型的计数器没有什么特别之处——它与任何其他类型的计数器相同——唯一的区别是计数器是由计时器滴答源驱动的。
自由运行计时器功能的预期用途是在运行时测量短、高准确度的持续时间。如果需要这样做,那么可能需要使用硬件计数器来获得所需的计数器分辨率。
6.5 Tick数转换为时间Tick to Time Conversions
通常将计数器用作操作系统的时基参考。对于编写的大多数应用程序,事件的相对定时将是由系统需求决定的实时值。很可能会根据实时值、纳秒、毫秒等来考虑系统配置,而不是使用更抽象的tick(滴答)概念。
如果计数器配置参数“秒每滴答”已经配置,那么RTA操作系统生成宏供使用,以在滴答和实时单位之间转换。
可移植性注意事项:AUTOSAR OS声明Tick到时间的转换仅适用于硬件计数器。但是,该特性通常对软件和硬件计数器都有用,并且AUTOSAR XML配置语言支持对这两种类型的计数器进行配置。
在RTA-OS中,这种异常通过为软件和硬件计数器提供刻度到时间的转换来解决。但是,应该注意,其他AUTOSAR OS实现不一定支持为软件计数器提供这些宏。
提供了以下Tick转换为时间的宏:
• OS_TICKS2NS_CounterID(ticks) converts ticks to nanoseconds
• OS_TICKS2US_CounterID(ticks) converts ticks to microseconds
• OS_TICKS2MS_CounterID(ticks) converts ticks to milliseconds
• OS_TICKS2SEC_CounterID(ticks) converts ticks to seconds
这些宏返回的值是PhysicalTimeType,而不是TickType,可能会使用这些宏的API调用使这些值,因此需要将它们转换为适当的类型。
例6.10展示了如何在应用程序代码中使用这些宏来使用静态定义的“timeout”值来模拟超时。
Example 6.10: Programming an alarm with time rather than ticks (1)
RTA-OS将尽可能使用整数乘法或除法生成这些宏。然而,对于某些滴答率,有必要在计算中使用浮点数,以保持准确性。当这些宏被传递给编译时已知的固定值时,编译器通常会自己执行计算并嵌入整型结果。如果传递的值是一个变量,那么编译器将不得不在运行时生成使用浮点计算的代码。如果这在应用程序中可能是一个问题,应该检查文件Os_Cfg.h以检查宏的代码。
除了这些宏之外,RTA-OS还生成一个名为otickduration_ 的宏,该宏以纳秒为单位返回计数器滴答的持续时间,因此,如果您希望编写固定时间的警报,即使更改底层计数器滴答率,它也非常有用。例6.11展示了如何使用otickduration_ 宏对例6.10进行修改。这个版本提供了稍好的性能,因为单个tick的持续时间不需要在运行时计算。
Example 6.11: Programming an alarm with time rather than ticks (2)
可移植性注意事项:OSTICKDURATION_
6.6 小结
•计数器用于注册一些tick源的计数。
•计数器可以是软件计数器也可以是硬件计数器。User需要为配置的计数器类型提供私有驱动程序。
参考文档:
[1] RTA-OS V6.1.3User Guide
[2]Specification of OperatingSystemAUTOSAR Release 4.2.2
关键词: