General Implementation Specification
- [7.1 General Implementation Specification](#7.1 General Implementation Specification)
-
- [7.1.1 遵循 MISRA C 和 C 标准](#7.1.1 遵循 MISRA C 和 C 标准)
- [7.1.2 遵循 AUTOSAR 基本软件需求](#7.1.2 遵循 AUTOSAR 基本软件需求)
- [7.1.3 遵循 AUTOSAR 方法论](#7.1.3 遵循 AUTOSAR 方法论)
- [7.1.4 平台独立性和编译器抽象](#7.1.4 平台独立性和编译器抽象)
- [7.1.5 可配置性](#7.1.5 可配置性)
- [7.1.6 各种命名约定](#7.1.6 各种命名约定)
- [7.1.7 配置参数](#7.1.7 配置参数)
- [7.1.8 共享代码](#7.1.8 共享代码)
- [7.1.9 全局数据](#7.1.9 全局数据)
- [7.1.10 宏和内联函数的使用](#7.1.10 宏和内联函数的使用)
- [7.1.11 调用调度函数(主处理函数)](#7.1.11 调用调度函数(主处理函数))
- [7.1.12 独占区(Exclusive Areas)](#7.1.12 独占区(Exclusive Areas))
- [7.1.13 回调函数(Callouts)](#7.1.13 回调函数(Callouts))
- [7.1.14 AUTOSAR 接口](#7.1.14 AUTOSAR 接口)
- [7.1.15 中断服务例程(Interrupt Service Routines)](#7.1.15 中断服务例程(Interrupt Service Routines))
- [7.1.16 限制对OS功能的访问](#7.1.16 限制对OS功能的访问)
- 7.1.17访问硬件寄存器
- 7.1.18数据类型
- 7.1.19在多分区系统上的分布式执行
7.1 General Implementation Specification
7.1.1 遵循 MISRA C 和 C 标准
本节强调BSW模块在代码编写时必须严格遵守 MISRA C 2012 标准以及C语言标准。MISRA C标准为安全关键的嵌入式系统提供了编码指导,尤其在汽车领域,减少系统中的指针错误、内存管理问题及其他潜在的安全隐患。这些编码标准能确保代码的安全性、可维护性和可移植性。
原文举例:
- 动态内存分配(如
malloc
和free
)在AUTOSAR BSW中是不允许的,因为在嵌入式系统中,动态内存分配可能会导致内存碎片,进而影响系统的实时性。
理解 :
MISRA C的严格限制防止了常见的C语言陷阱,如未初始化变量或未定义行为。这对汽车系统尤为重要,因为系统必须在长期运行过程中保持一致且安全的行为。
7.1.2 遵循 AUTOSAR 基本软件需求
这一部分规定了AUTOSAR BSW模块必须完全符合 AUTOSAR基本软件需求(SRS BSW General)。这些需求涵盖模块的功能性、接口设计、编码标准等,确保所有BSW模块在不同项目和平台上能够保持一致性。即使在一些简化的示例中未完全体现需求,实际开发中仍需严格遵守这些规定。
原文举例:
- 某些代码示例可能简化了对内存抽象的实现,但这并不意味着开发中可以忽略内存抽象。在实际应用中,必须按照规定来实现内存管理功能。
理解 :
遵守AUTOSAR的基本软件需求能确保模块在不同供应商的实现中都能够标准化,使得模块间的集成更加顺畅,提高系统的兼容性和可移植性。
7.1.3 遵循 AUTOSAR 方法论
AUTOSAR不仅提供了技术规范,还提供了一套开发流程和工具链,以确保模块开发和配置的标准化。AUTOSAR方法论包括开发工具的使用、代码生成和配置管理的流程规范,开发人员必须遵循这些标准化流程。
原文举例:
- AUTOSAR工具链支持根据配置文件自动生成部分代码,如接口的初始化和配置数据。这减少了手动编码的错误,并确保所有模块都符合标准。
理解 :
通过AUTOSAR的方法论,开发人员可以更加高效地管理复杂的配置和代码生成,减少手动操作和人为错误,同时保证整个开发生命周期的合规性和一致性。
7.1.4 平台独立性和编译器抽象
本节强调BSW模块的 平台独立性,即模块应能够在不同硬件平台和编译器之间移植,而不需要对代码进行大幅修改。这是通过使用编译器抽象来实现的,编译器抽象层能够屏蔽编译器和硬件平台的差异,确保代码可以无缝移植。
原文举例:
#define FAR(X) __far__ X
:这是一种编译器抽象的示例,FAR
宏定义屏蔽了编译器特性,使得特定平台的内存模型能够通过抽象统一起来。在不同的编译器上,__far__
关键字可能需要替换成其他表示法,开发者不必关心具体的编译器细节。- Compiler 1 requires:
void far function(); - Compiler 2 requires:
far void function();
通过定义统一的对外宏定义,FAR, 上述因不同编译器特性而造成的差异不应该对平台产生影响。
理解 :
使用编译器抽象层能够显著提高代码的可移植性。例如,在不同的编译器中,硬件寄存器的访问和特定的内存模型可能有所不同,通过统一的抽象,开发者可以编写更通用的代码,而不必针对每个编译器进行额外适配。
7.1.5 可配置性
AUTOSAR要求BSW模块在实现时必须具备高度的 可配置性,即模块的功能和行为能够通过配置文件或工具灵活调整,而不需要修改源代码。开发者可以通过配置参数来根据系统需求调整模块的功能和表现。
原文举例:
- 通信管理模块可以根据配置文件中的参数来定义消息缓冲区的大小、消息优先级以及通信通道的数量。这些参数可以在系统初始化之前由配置工具生成,而不需要手动更改代码。
- 开启/关闭部分代码的配置,不推荐使用单纯的宏定义,而应当使用STD_ON 和STD_OFF来明确是否开启或者关闭;
c
Example:
#if (EEP_21_LDEXT_DEV_ERROR_DETECT == STD_ON )
...
Example of a wrong implementation:
#ifdef EEP_21_LDEXT_DEV_ERROR_DETECT
理解 :
可配置性为BSW模块提供了极大的灵活性,开发人员可以根据不同硬件平台和应用场景,通过配置参数来调整模块的行为。这种灵活性使得BSW模块能够适应各种不同的系统环境,而不需要手动修改代码。
7.1.6 各种命名约定
文档规定了BSW模块中各种命名的标准。每个模块的接口、变量、函数、宏定义等都必须遵守AUTOSAR定义的命名规范。这一规范确保了模块之间接口的一致性和集成时的兼容性。
原文举例:
CanIf_Transmit()
:CAN接口模块的函数命名必须符合AUTOSAR规定的命名标准,以确保开发人员能够快速识别每个模块的功能和用途。这种命名约定有助于避免不同模块间的命名冲突。
c
Example: The Eeprom driver has the following status values:
EEP_21_LDEXT_UNINIT
EEP_21_LDEXT_IDLE
EEP_21_LDEXT_BUSY
Examples for pre-processor directives:
#define EEP_21_LDEXT_PARAM_CONFIG
#define EEP_21_LDEXT_SIZE
Example for enumeration literals:
typedef enum
{
EEP_21_LDEXT_DRA_CONFIG = 0,
EEP_21_LDEXT_ARE = 1,
EEP_21_LDEXT_EV = 2
} Eep_21_LDExt_NotificationType;
理解 :
命名规范不仅能提高代码的可读性,也能确保模块在集成时不会因命名冲突而出现问题。这对于跨团队开发或多个供应商提供的模块整合尤为重要。
7.1.7 配置参数
配置参数允许BSW模块根据实际需要进行灵活的配置,而不需要更改代码本身。配置参数可以在预编译、链接时配置或后期编译时进行设置,以便调整模块的行为。
原文举例:
- 在存储管理模块(NvM)中,开发者可以通过配置参数来定义存储区域的大小、数据保护策略和备份机制。这些配置参数允许存储管理模块适应不同的系统需求,而不需要修改模块的源代码。
理解 :
配置参数为BSW模块提供了灵活性和扩展性,开发者可以在不更改代码的情况下,通过简单的配置调整模块的功能。这种灵活性对于支持多个不同配置的产品尤为重要,因为它减少了代码修改的复杂性,提高了代码的复用性。
7.1.8 共享代码
BSW模块中的某些功能可能会被多个模块共享使用。在保证代码可维护性和复用性的前提下,AUTOSAR提供了关于共享代码的规范。共享代码应尽量避免直接依赖硬件或平台特性,确保它们在不同平台上均可复用。
原文举例:
- 多个模块可能需要访问相同的数学函数库(如正弦、余弦计算),这些函数可以通过共享代码库提供,而不是在每个模块中独立实现。这种共享机制能够减少重复代码的维护工作。
理解 :
共享代码能够减少系统中重复功能的实现,并提高代码的复用性和一致性。共享代码库应遵循AUTOSAR的抽象层规范,确保这些功能与硬件无关,能够在多个模块间无缝共享。
7.1.9 全局数据
AUTOSAR建议尽量减少全局数据的使用,防止模块之间出现不必要的耦合。过多使用全局数据可能会导致模块之间过度依赖,降低系统的模块化程度。
原文举例:
- 如果多个模块需要访问某个数据,建议通过接口函数进行数据传递,而不是直接使用全局变量。这样可以保持模块之间的独立性,并避免数据一致性问题。
- 如果全局变量为read-only,则需要添加const进行修饰
理解 :
全局数据的滥用可能会导致系统的模块化设计失效,因此,AUTOSAR建议开发者通过接口传递数据,这样既能减少模块之间的耦合,也能增强代码的可维护性和模块的独立性。
7.1.10 宏和内联函数的使用
AUTOSAR建议开发人员在使用宏函数或者内联函数,来增强运行时的效率;
- 宏通常被用在一些非常重要的场合
- 内联函数适合用在比较简单的场景
7.1.11 调用调度函数(主处理函数)
主处理函数是系统中定期调用的调度函数,用于处理周期性任务。AUTOSAR要求这些函数必须以固定的时间间隔执行,以确保满足系统的实时性需求。这些函数通常用于处理通信、状态监控和其他周期性任务。
理解 :
主处理函数的定期调用是实时系统的关键,确保了系统能够以规定的周期执行任务。实时系统中,任务的调度至关重要,开发人员必须确保这些调度函数能够按时执行。
7.1.12 独占区(Exclusive Areas)
独占区是指系统中需要通过互斥机制保护的代码或数据区域,以防止并发访问导致的数据不一致或系统崩溃。在多任务或多核环境中,某些资源或操作可能需要独占访问,确保多个任务不会同时访问同一个共享资源,包括但不限于accessing Scheduled functions (Main
processing functions), API services, Callback functions and ISR functions
原文举例:
- 在存储管理模块中,多个任务可能需要同时访问EEPROM存储。如果没有合适的互斥保护,数据可能会被多个任务同时修改,导致数据不一致。因此,必须确保这些资源访问时处于互斥状态。
理解 :
独占区的设置是为了防止竞争条件,确保多个任务或进程在访问共享资源时不会导致冲突或数据损坏。通过互斥机制,可以保证系统的稳定性和数据的完整性。
7.1.13 回调函数(Callouts)
回调函数 (Callouts)是指系统中的某些特定功能在发生特定事件时,通过调用预定义的函数来进行处理。AUTOSAR允许模块通过回调函数处理某些外部事件或特殊条件,以便能够灵活响应系统的变化。回调函数在处理某些硬件中断、错误检测和信号处理时非常有用。
原文举例:
- 在通信管理模块中,回调函数可以用于处理消息接收完成的通知。收到消息后,通信模块通过回调函数通知上层应用模块进行处理。
理解 :
回调函数提供了模块间灵活的交互机制,它可以在不改变系统主流程的情况下响应外部事件。它不仅提高了模块的灵活性,也简化了事件处理的流程。
7.1.14 AUTOSAR 接口
AUTOSAR接口定义了模块之间通信的标准。为了确保不同模块间的兼容性和互操作性,AUTOSAR要求所有模块通过定义明确的接口进行通信。接口的设计必须清晰、标准化,并符合AUTOSAR的规范,以便开发人员能够在集成多个供应商的模块时保证兼容性。
原文举例:
- CAN接口模块提供的
CanIf_Transmit()
函数是通过标准接口与其他模块交互的。无论CAN接口的底层实现如何变化,接口保持一致。
理解 :
标准化接口确保了模块之间的交互能够在不考虑实现细节的情况下进行。这种设计使得模块可以更好地重用,并且可以轻松替换不同的底层实现,而不影响上层逻辑。
7.1.15 中断服务例程(Interrupt Service Routines)
中断服务程序(ISR)的实现是高度微控制器化的相关的。参见7.1.4 -平台独立性和编译器抽象。
中断服务例程(ISR)是用来处理来自硬件或外部设备的中断信号的。AUTOSAR规定,ISR的实现应尽量简洁,避免复杂的逻辑操作。ISR应该只执行必要的处理,尽快恢复系统的正常运行状态,避免长时间占用CPU资源。复杂的处理应交给后台任务,而不是直接在ISR中进行。
- 中断服务是高度依赖平台的,如果使用了中断服务,那么必须提供对应的目录
- AUTOSAR不支持在应用中使用中断,防止中断嵌套
- 谨慎执行从中断中切换到task的动作,如果确实需要,需要将优先级放到最低
原文举例:
- 在CAN接口模块中,ISR只负责接收CAN总线上的数据帧,而帧的解析和处理则在主任务中完成。这样可以避免中断处理占用过多的系统资源。
理解 :
实时系统中的中断服务例程是关键部分。过长的中断处理时间会导致系统响应速度下降,因此应尽量保持ISR简短,确保系统能够快速响应外部事件,保持系统的实时性。
7.1.16 限制对OS功能的访问
AUTOSAR建议在BSW模块中应尽量限制对操作系统(OS)功能的直接访问,尤其是非必要的OS功能。过多依赖操作系统的模块可能会降低系统的可移植性,增加对特定操作系统的依赖性。这将会在系统移植到不同平台或OS版本时引发问题。
原文举例:
- 某些模块可能直接调用操作系统的调度功能或内存管理功能,这会导致模块与操作系统的耦合度过高,从而影响模块的独立性和可移植性。
理解 :
通过限制对OS功能的访问,可以提高模块的独立性和移植性,使得模块能够在不同的操作系统平台之间更加灵活地进行移植和集成,避免了与操作系统的深度耦合问题。
7.1.17访问硬件寄存器
BSW模块在访问寄存器时,需要处理并发访问带来的影响
BSW模块应该允许使用防御功能并发访问HW寄存器行为和技巧,比如:
- 保护读-修改-写访问不被中断
- 使用原子(不可中断)指令进行读-修改-写访问
7.1.18数据类型
- 组织所有AUTOSAR标准类型和常量
AUTOSAR标准类型头(Std_Types.h)。这头:包括平台特定类型头(Platform_Types.h)包括编译器特定语言扩展头(Compiler.h)
定义类型Std_ReturnType定义E_OK和E_NOT_OK符号及其值定义STD_ON和STD_OFF符号及其值。 - 平台特定类型
一些依赖硬件平台和编译器的变量应当放在Platform_Types.h中 - AUTOSAR中不允许使用自定义的C整数类型,而应当使用AUTOSAR定义的C整数类型
7.1.19在多分区系统上的分布式执行
AUTOSAR架构支持BSW模块功能的执行
多个分区,可能运行在不同的核心上。如果一个模块提供服务
在多个分区上,或者
- RTE将服务调用传输到BSW模块所在的分区应执行调用的实体已定位,或
- BSW模块实体在它所在的分区上接收调用调用并自主处理其执行(4.1版新功能)。那意味着,它可以在同一分区上执行调用,将其转发到另一个分区或两者的组合-取决于实现BSW供应商的策略。
总结
7.1节为AUTOSAR BSW模块的实现提供了详细的指导,涵盖了编码标准、平台独立性、可配置性、共享代码和全局数据管理等方面。通过遵循这些规范,开发人员能够确保BSW模块在不同硬件和软件环境下保持一致性、可移植性和安全性。