在电子控制单元(ECU)的开发中,访问共享资源(如外设和全局变量)时可能需要进行中断或任务间的互斥处理(锁)。 AUTOSAR有一个名为“Exclusive Area”的机制,简称EA,它在软件组件(SWCs)和基础软件(BSW)开发期间抽象出互斥处理,并在集成期间确定具体的互斥处理。🤔🤔🤔
1.AUTOSAR开发中的互斥处理
在AUTOSAR中,SWC和BSW作为软件组件开发,在集成工作中使用所需的组件。因此,在开发SWC和BSW时无法确定哪些功能需要进行互斥处理。🙂🙂🙂
1.1 EA在WdgM中的应用
以监视SWC是否正确执行的BSW WdgM(*1)为例。
※1 Watchdog Manager: [AUTOSAR_SWS_WatchdogManager.pdf]
BSW周期性调用名为MainFunction的API来控制主要依赖于时间的处理。
在WdgM中,该API变为WdgM_MainFunction。通过定期调用WdgM_MainFunction,监视SWC是否按预期时间执行等情况。此外,通过调用名为WdgM_CheckpointReached的API,SWC通知WdgM已执行指定的监视对象处理。 WdgM_MainFunction确定是否正确执行了处理,根据SWC设置的监视条件和WdgM_CheckpointReached的调用状态。
由于在WdgM_MainFunction和WdgM_CheckpointReached内部处理中操作每个SWC的监视状态管理数据,因此在WdgM_MainFunction更新数据时,如果中断进入并执行WdgM_CheckpointReached,则可能会发生数据不一致的情况。为了防止这种情况发生,WdgM_MainFunction和WdgM_CheckpointReached需要执行互斥处理。
但是,如果调用WdgM_MainFunction的任务和调用WdgM_CheckpointReached的任务具有相同的优先级,会发生什么情况呢?由于同一优先级任务不会在任务执行期间被中断执行,因此不会发生WdgM_MainFunction在执行时执行WdgM_CheckpointReached的情况。在这种情况下,互斥处理是不必要的。也就是说,如果在WdgM_MainFunction和WdgM_CheckpointReached中固定实现互斥处理,它将成为ECU软件配置的无用EA处理。所以过度的使用EA,会导致资源浪费,影响响应的实时性。
为了解决这种情况,使用一种称为Exclusive Area的机制来抽象化互斥处理。它可以完全理解为我们在其他操作系统中的操作共享资源时使用的锁。
1.2 EA在运行时时间获取的应用
试想,如果由于中断的优先级问题,在两个同时需要获取时间的运行实体中(这里的运行实体指中断回调,task以及对应的runnable)。如果低优先级的先获取时间寄存器tick,而往往tick需要转换为可识别的时间单位,如纳秒,毫秒,秒等。但是如果在转换的过程中,高优先级的中断将其打断,而此时有又涉及到资源共享的问题的话,有可能时间获取会被打乱,高优先级可能获取了一个正常的时间,但是出栈后的低优先级中断,可能获取了一个异常事件。
此时,OS resource(下面将会提到)可能就不再适用此类场景,OS resource只负责只能够保证数据前后的一致性,即前后数据可能不会被修改,不能够保证中途是否会被打断。所以此场景中使用中断禁用更为适合。
2.关于EA的机制 Exclusive Mechanism
在解释互斥区域之前,我们先来解释一下实现AUTOSAR中的互斥处理所采用的机制(互斥机制)。在AUTOSAR中,主要使用操作系统(※2)提供的中断管理、资源和自旋锁等功能来实现互斥处理。😝😝😝
※2 Operating System: [AUTOSAR_SWS_OS.pdf]
2.1中断管理
OS管理的中断(ISR:Interrupt Service Routine)有两种类型:CAT1 ISR和CAT2 ISR。CAT1 ISR只能调用与禁止/允许中断相关的API,并且由于OS在中断发生后直到返回之前不会有任何干预,因此在需要快速中断响应性能的情况下使用。CAT2 ISR可使用许多OS的API。 OS提供用于执行用户定义中断处理的处理,如寄存器保存/恢复等。
针对这些中断,OS提供以下API:
- SuspendAllInterrupts:禁止所有中断
- ResumeAllInterrupts:允许所有中断
- SuspendOSInterrupts:禁止所有CAT2 ISR中断
- ResumeOSInterrupts:允许所有CAT2 ISR中断
只有可以调用控制任务的API的CAT2 ISR才能切换任务,因此,在需要在不同优先级的任务之间进行互斥控制的情况下,可以在SuspendOSInterrupts/ResumeOSInterrupts中的互斥区域内执行互斥处理。如果需要对CAT1 ISR进行互斥控制,则使用SuspendAllInterrupts/ResumeAllInterrupts。
2.2 资源(Resource)
在 AUTOSAR 中,资源是使用优先级上限协议实现的互斥控制功能。通过为每个在 OS 配置中定义的资源指定将使用该资源的任务,可以确定每个资源的优先级上限。在运行时,通过将获取资源的任务的优先级提高到目标资源的上限,可以使排他区域内的其他任务无法执行,从而实现互斥控制。以下 API 用于获取/释放资源:
- GetResource:获取资源
- ReleaseResource:释放资源
值得注意的是,资源的使用也可以扩展到与CAT2 ISR的互斥控制。
2.3 自旋锁(spinlock)
自旋锁是一种用于多核环境下进行核间互斥控制的功能。在多核环境下,由于任务在多个核心上并行执行,即使在某个核心中禁用中断,也无法停止其他核心上的任务处理。因此,需要定义自旋锁作为所有核心共同的互斥资源。当一个核心的任务获取了自旋锁时,其他核心的任务将无法获取该自旋锁,它们将自旋(循环)等待锁被释放。
以下是自旋锁的API:
- GetSpinlock:获取自旋锁(如果无法获取,就会自旋等待)
- TryToGetSpinlock:尝试获取自旋锁(如果无法获取,就会立即返回)
- ReleaseSpinlock:释放自旋锁
另外,在AUTOSAR中,可以指定与自旋锁相关的属性,例如在获取自旋锁时同时禁止中断等。
<NOTE>
AUTOSAR的操作系统被规定为是OSEK/VDX操作系统规范的上位兼容,并且AUTOSAR规范书中未记录OSEK/VDX操作系统规范的部分。此外,由于OSEK/VDX操作系统规范已在ISO上标准化,因此目前已不对外公开。在上述功能中,除自旋锁外,其余功能均为OSEK/VDX操作系统规范定义的功能。
3.实现互斥处理
接下来以WdgM为例,说明如何实现互斥处理。以下是WdgM_MainFunction和WdgM_CheckpointReached互斥处理部分的实现。
※AliveSupervision是WdgM的一项功能,用于监视SWC中的处理是否在正确的时间执行。(通俗的理解就是检查是否"还活着"😂😂😂)
SchM_Enter_WdgM_AliveSupervision();
/*与AliveSupervision相关的数据操作 */
SchM_Exit_WdgM_AliveSupervision();
实现很简单,只需在开始和结束互斥区域时调用由RTE(※3)提供的SchM_Enter和SchM_Exit API即可。
※3 Runtime Environment:[AUTOSAR_SWS_RTE.pdf]
在集成工作中,可以在考虑各个互斥区域所需的互斥机制之后,通过使用RTE生成各个API,实现适应ECU软件配置的最小必要EA处理。
SchM_Enter和SchM_Exit遵循以下命名规则,如上例中,为"WdgM"和"AliveSupervision"。
void SchM_Enter_<bsnp>[<vi><ai>]<name>()
void SchM_Exit<bsnp>[<vi><ai>]_<name>()
※有关详细信息,请参阅※3 RTE规范书
在实现WdgM时,我们只需确定“操作与AliveSupervision相关的数据所需的互斥区域”,并按照SchM_Enter、SchM_Exit的命名规则实现WdgM。当然,如果在除AliveSupervision之外的数据操作时也需要互斥,我们也可以使用相同的API来实现互斥处理。这样,使用SchM_Enter和SchM_Exit就实现互斥区域EA。
需要注意的是,上述是BSW的实现,因此前缀为“SchM(BSW Scheduler Module)”。在SWC中,EA的前缀为“Rte”。
4.EA提供的模板
为了使集成商能够选择适当的互斥机制,需要提供各个SWC和BSW都具有互斥区域的信息。
对于SWC,使用Software Component Template(※4);对于BSW,使用BSW Module Description Template(※5)中定义的元模型进行定义。 🤓🤓🤓
※4[AUTOSAR_TPS_SoftwareComponentTemplate.pdf]
※5[AUTOSAR_TPS_BSWModuleDescriptionTemplate.pdf]
以下是提供互斥区域的WdgM中AliveSupervision的定义摘要(这主要是对Autosar标准实现者而言的)。
<BSW-MODULE-DESCRIPTION>
<SHORT-NAME>WdgM</SHORT-NAME>
<INTERNAL-BEHAVIORS>
<BSW-INTERNAL-BEHAVIOR>
<SHORT-NAME>InternalBehavior</SHORT-NAME>
<EXCLUSIVE-AREAS>
<EXCLUSIVE-AREA>
<SHORT-NAME>AliveSupervision</SHORT-NAME>
<DESC>
<L-2>This exclusive area is ...</L-2>
</DESC>
</EXCLUSIVE-AREA>
</EXCLUSIVE-AREAS>
<ENTITYS>
<BSW-SCHEDULABLE-ENTITY>
<SHORT-NAME>WdgM_MainFunction</SHORT-NAME>
<CAN-ENTER-EXCLUSIVE-AREA-REFS>
<CAN-ENTER-EXCLUSIVE-AREA-REF DEST="EXCLUSIVE-AREA">/WdgM/InternalBehavior/AliveSupervision</CAN-ENTER-EXCLUSIVE-AREA-REF>
</CAN-ENTER-EXCLUSIVE-AREA-REFS>
</BSW-SCHEDULABLE-ENTITY>
<BSW-CALLED-ENTITY>
<SHORT-NAME>WdgM_CheckpointReached</SHORT-NAME>
<CAN-ENTER-EXCLUSIVE-AREA-REFS>
<CAN-ENTER-EXCLUSIVE-AREA-REF DEST="EXCLUSIVE-AREA">/WdgM/InternalBehavior/AliveSupervision</CAN-ENTER-EXCLUSIVE-AREA-REF>
</CAN-ENTER-EXCLUSIVE-AREA-REFS>
</BSW-CALLED-ENTITY>
</ENTITYS>
</BSW-INTERNAL-BEHAVIOR>
</INTERNAL-BEHAVIORS>
</BSW-MODULE-DESCRIPTION>
定义从第一行开始,针对“WdgM”。在第7-12行中定义了互斥区域“AliveSupervision”,并在第17-19行和第23-25行中定义了WdgM_MainFunction和WdgM_CheckpointReached使用互斥区域“AliveSupervision”。
此外,在9-11行中的DESC中,可以描述互斥区域的说明。如果同时调用WdgM_MainFunction和WdgM_CheckpointReached,则需要互斥区域的说明,以便将互斥区域的必要性传达给集成商。
当然,BSW附带的手册中也可能包含各个互斥区域的说明。
需要注意的是,各个BSW具有的互斥区域数量(粒度)和用途在很大程度上取决于BSW的设计/实现,因此并未在AUTOSAR中标准化。由于每个BSW供应商提供的互斥区域可能不同,请注意。
5.互斥区域的配置
基于从SWC和BSW提供的互斥区域信息,集成商选择在各个互斥区域中需要的互斥机制。互斥区域的设置方法由RTE的EcucDefs(※6)规定。
※6 富士软件技术专栏 “AUTOSAR开发 Basic Software配置规范的机制”
以下是设置排他区域的RteBswExclusiveAreaImpl部分摘录。请注意,本专栏基本上针对AUTOSAR的R4.0.3版本,但由于R4.3中添加了"NONE"到RteExclusiveAreaImplMechanism中,因此下面的EcucDefs是R4.3版本的。
<ECUC-PARAM-CONF-CONTAINER-DEF UUID="ECUC:ecd2f711-51be-4b48-83a2-219528eaaa17">
<SHORT-NAME>RteBswExclusiveAreaImpl</SHORT-NAME>
<PARAMETERS>
<ECUC-ENUMERATION-PARAM-DEF UUID="ECUC:99e2df6b-46ef-9a25-3991-e9af1b370716">
<SHORT-NAME>RteExclusiveAreaImplMechanism</SHORT-NAME>
<LITERALS>
<ECUC-ENUMERATION-LITERAL-DEF UUID="ECUC:51458958-eb49-db2b-f050-9c1d28db40ae">
<SHORT-NAME>ALL_INTERRUPT_BLOCKING</SHORT-NAME>
</ECUC-ENUMERATION-LITERAL-DEF>
<ECUC-ENUMERATION-LITERAL-DEF UUID="ECUC:e903fa41-18a4-e28b-c6cf-d7ed12ccbde9">
<SHORT-NAME>NONE</SHORT-NAME>
</ECUC-ENUMERATION-LITERAL-DEF>
<ECUC-ENUMERATION-LITERAL-DEF UUID="ECUC:d888ea7b-03f2-e0d4-c266-d780b657d096">
<SHORT-NAME>OS_INTERRUPT_BLOCKING</SHORT-NAME>
</ECUC-ENUMERATION-LITERAL-DEF>
<ECUC-ENUMERATION-LITERAL-DEF UUID="ECUC:763f0200-5758-dccb-e54e-48cef5eb9190">
<SHORT-NAME>OS_RESOURCE</SHORT-NAME>
</ECUC-ENUMERATION-LITERAL-DEF>
<ECUC-ENUMERATION-LITERAL-DEF UUID="ECUC:18e1be81-8f60-e4a8-f673-9a0c24a561a9">
<SHORT-NAME>OS_SPINLOCK</SHORT-NAME>
</ECUC-ENUMERATION-LITERAL-DEF>
</LITERALS>
</ECUC-ENUMERATION-PARAM-DEF>
</PARAMETERS>
<REFERENCES>
<ECUC-REFERENCE-DEF UUID="ECUC:bfaccb50-3017-44d5-9c2c-692cbd375d3d">
<SHORT-NAME>RteBswExclusiveAreaOsResourceRef</SHORT-NAME>
<DESTINATION-REF DEST="ECUC-PARAM-CONF-CONTAINER-DEF">/AUTOSAR/EcucDefs/Os/OsResource</DESTINATION-REF>
</ECUC-REFERENCE-DEF>
<ECUC-REFERENCE-DEF UUID="ECUC:17fad2ad-eeff-411a-9b4a-2f8bee7c44f1">
<SHORT-NAME>RteBswExclusiveAreaOsSpinlockRef</SHORT-NAME>
<DESTINATION-REF DEST="ECUC-PARAM-CONF-CONTAINER-DEF">/AUTOSAR/EcucDefs/Os/OsSpinlock</DESTINATION-REF>
</ECUC-REFERENCE-DEF>
<ECUC-FOREIGN-REFERENCE-DEF UUID="ECUC:9a3b4142-244d-40d2-a461-6a6b3f605891">
<SHORT-NAME>RteBswExclusiveAreaRef</SHORT-NAME>
<DESTINATION-TYPE>EXCLUSIVE-AREA</DESTINATION-TYPE>
</ECUC-FOREIGN-REFERENCE-DEF>
</REFERENCES>
</ECUC-PARAM-CONF-CONTAINER-DEF>
排他区域是通过名为RteBswExclusiveAreaImpl的容器进行设置的。使用RteBswExclusiveAreaRef指定要设置的SWC/BSW侧的排他区域(例如AliveSupervision)。然后,在RteExclusiveAreaImplMechanism中从以下排他机制中进行选择:
ALL_INTERRUPT_BLOCKING | 通过SuspendAllInterrupts/ResumeAllInterrupts禁止中断 |
NONE | (将SchM_Enter/SchM_Exit(Rte_Enter/Rte_Exit)设置为空的函数/宏等 |
OS_INTERRUPT_BLOCKING | 通过SuspendOSInterrupts/ResumeOSInterrupts禁止中断。 |
OS_RESOURCE | 通过RteBswExclusiveAreaOsResourceRef获取/释放指定的资源。 |
OS_SPINLOCK | 通过RteBswExclusiveAreaOsSpinlockRef获取/释放指定的自旋锁。 |
通过这种设置,Rte的生成器会生成使用指定排他机制的SchM_Enter和SchM_Exit,从而决定各SWC和BSW内的排他处理。
6.API无需调用的EA
实际上,AUTOSAR中有两种方法可以开始/结束EA。本文介绍的是通过明确调用SchM_Enter/SchM_Exit(Rte_Enter/Rte_Exit)来进行排他控制的CanEnterExclusiveArea方法。另一种方法是RunsInsideExclusiveArea,它是一种不需要调用API的方式。对于RunsInsideExclusiveArea,Rte将在执行排他对象函数之前和之后生成类似于SchM_Enter/SchM_Exit(Rte_Enter/Rte_Exit)的代码。也就是说,如果想要将整个函数作为排他区域,则使用RunsInsideExclusiveArea可以省去在函数内部调用排他用API的步骤。
7.排他区域设置需要注意的事项
根据SWC或BSW的实现,可能会在EA区域内调用其他组件提供的API。在这种情况下,根据所选择的EA机制,可能会发生问题。例如,在OS中存在许多在禁止中断时(如前述提到的CAT1 ISR)无法调用的API。在组件A的EA区域内调用组件B的API,而组件B的API在调用OS的API时,如果选择在组件A的排他机制中选择禁止中断,则可能会发生错误。
为避免此类问题,请注意排他区域的设置,例如查看目标组件的手册中的限制事项等。
8.实现
8.1 EB实现
1.All Interrupt Blocking:所有中断都被阻塞。
2.Os Resource:使用标准的Os资源来保护互斥区域。
3.Os Interrupt Blocking:Os中断被阻塞。
4.Cooperative Runnable Placement:对于执行协作运行的可执行实体,使用Os的内部资源进行映射。
5.EB Fast Lock:通过汇编指令锁定所有中断。
6.Disable Exclusive Area:没有中断被锁定。
7.Os Spinlock:使用Os自旋锁来保护互斥区域。
8.User Callout:使用用户定义的调用来保护互斥区域。
User callout enter: 用户定义函数的名称。如果实现机制设置为用户调用,则Rte调用此函数进入互斥区域。用户负责实现此函数。
User callout exit: 用户定义函数的名称。如果实现机制设置为用户调用,则Rte调用此函数退出互斥区域。用户负责实现此函数。
Rte生成包含用户定义进入调用和退出调用的外部声明的头文件: Rte_UserDefinedExclusiveArea.h。用户负责实现这些调用。
8.2 Vector实现
待更新
参考文献:
[EB tresos® AutoCore Generic 8 RTE documentation]