
一张图看懂 AUTOSAR Classic 完整软件架构很多人第一次打开 DaVinci Configurator看到 Com、PduR、CanIf、CanSM、CanNm、EcuM、NvM、Dem、Det……第一反应往往不是“AUTOSAR 真规范”而是这到底都是什么东西其实 AUTOSAR Classic 并没有想象中那么乱。你只需要先记住一张图。01 先看完整架构AUTOSAR Classic 的软件从上到下大体可以分成下面几层中间的 BSW 又可以继续拆成Services LayerECU Abstraction LayerMicrocontroller Abstraction LayerComplex Drivers如果把这些东西全部放在一起AUTOSAR Classic 的整体架构大致如下这张图其实就是整个 AUTOSAR Classic 学习路线的地图。以后不管看到什么模块第一件事情都不是去背 API而是先问它在这张图的什么位置只要位置知道了它大概负责什么基本也就能猜出来了。02 最上面Application Software先从最容易理解的地方开始。最上面是Application Software也就是应用软件。比如一台 VCU 里面可能有VehicleControl TorqueControl ThermalManagement ChargeControl DiagnosisManager EnergyManagement在 AUTOSAR 里面这些功能通常不会全部写在一个巨大的main.c里面而是拆成一个个Software Component简称SWC例如VCU ├── VehicleControl_SWC ├── TorqueControl_SWC ├── ChargeControl_SWC ├── ThermalManagement_SWC └── Diagnosis_SWCSWC 负责的是什么简单说负责汽车真正的业务逻辑。例如踩下加速踏板 ↓ 读取 Accelerator Pedal ↓ 计算 Driver Request Torque ↓ 进行扭矩限制 ↓ 计算最终 Motor Torque Request这些东西本质上都属于 Application。换句话说BSW 不关心你这辆车到底是纯电、混动还是燃油车。“我要多少扭矩”“什么时候允许上高压”“什么时候进入跛行模式”这些属于应用层。这也是为什么很多公司的组织结构里面会分成ASW Team BSW TeamASW 主要负责Software Component Control Logic Vehicle FunctionBSW 则负责下面整套基础设施。03 Application 为什么不直接访问硬件传统嵌入式开发里面我们很容易写出这样的代码Can_Write(...);Adc_ReadGroup(...);Dio_WriteChannel(...);甚至MODULE_P10.OUT.B.P01;应用程序直接操作寄存器。小项目这么做当然没问题。但是汽车 ECU 的软件规模一旦变大这种方式很快就会失控。比如你的应用代码里面到处都是CAN Driver ADC Driver GPIO Driver Flash Driver SPI Driver以后如果TC366 ↓ TC377甚至Infineon ↓ NXP大量应用代码都可能跟着修改。AUTOSAR 的设计思想恰恰相反。Application 尽量不要知道下面到底是什么芯片也不要知道 CAN 报文到底通过哪个 CAN Controller 发出去。于是中间出现了一层非常关键的东西RTE04 RTEAUTOSAR 最重要的“中间层”RTE 全称Runtime Environment很多刚接触 AUTOSAR 的人会把 RTE 理解成一个普通的中间件。实际上它的重要程度要高得多。你可以先简单理解成RTE 是 Application 和 AUTOSAR 基础软件之间的桥梁。例如一个 SWC 想读取车速。应用代码可能写Rte_Read_VehicleSpeed_Value(speed);应用层并不知道VehicleSpeed究竟来自CAN LIN FlexRay Ethernet ADC 另外一个 SWC它只知道Rte_Read()同样如果应用想发送目标扭矩Rte_Write_MotorTorqueRequest_Value(torque);应用层也不用关心后面经过多少模块。实际上背后可能是Application ↓ RTE ↓ COM ↓ PduR ↓ CanIf ↓ Can Driver ↓ CAN Controller最后才真正变成 CAN 总线上的一帧报文。所以在 AUTOSAR 项目里面有一个很重要的思想Application ≠ HardwareApplication 与 Hardware 之间存在大量抽象层。而 RTE 正好站在 Application 和 BSW 的边界上。05 再往下BSW接下来就是 AUTOSAR Classic 最庞大的一部分BSW Basic Software很多刚进入 AUTOSAR 的工程师真正感到头大的地方其实就在这里。因为一打开 DaVinci Configurator可能会看到几十甚至上百个模块。例如EcuM BswM ComM CanSM CanNm CanIf CanTp PduR Com Dcm Dem Det NvM MemIf Fee WdgM Os ...乍一看完全不知道从哪里开始。但这些模块并不是随便堆在一起的。BSW 内部其实仍然有明确分层。最经典的划分就是Services Layer ECU Abstraction Layer Microcontroller Abstraction Layer外加一个比较特殊的Complex Drivers理解这四块以后整个 AUTOSAR BSW 就会清晰很多。06 Services Layer整个 ECU 的公共服务中心BSW 最上面的一层通常称为Services Layer这一层已经基本不关心具体硬件。它提供的是整个 ECU 都会用到的公共能力。典型模块包括OS EcuM BswM ComM COM PduR Dcm Dem NvM WdgM可以把它理解成 ECU 的操作系统 通信管理 状态管理 诊断管理 存储管理都集中在这一层。OS首先是Operating System也就是 AUTOSAR OS。它负责Task ISR Alarm Counter Event Resource ScheduleTable简单理解整个 ECU 的软件什么时候运行由 OS 负责调度。比如Task_1ms Task_5ms Task_10ms Task_20ms Task_100ms你的 Runnable 最终往往就是在这些 Task 里面被调度运行。后面我们专门讲 AUTOSAR OS 的时候会把Task Runnable Event Alarm ScheduleTable之间的关系完全拆开讲。07 EcuMECU 的生命周期管理员另外一个非常重要的模块EcuM ECU State Manager顾名思义它管理 ECU 的状态。例如Power On ↓ Startup ↓ Run ↓ Post Run ↓ Shutdown ↓ SleepECU 上电之后MCU 初始化 Driver 初始化 OS 启动 BSW 初始化 进入正常运行这些过程都离不开 EcuM。以后你在代码里面经常会看到EcuM_Init()EcuM_StartupTwo()EcuM_MainFunction()或者Wakeup Source Validation Sleep Shutdown这些基本都属于 EcuM 的世界。08 BswMBSW 的“大管家”如果 EcuM 管的是 ECU 生命周期那么BswM BSW Mode Manager更像是整个 BSW 的模式协调中心。例如CAN 网络进入 Full Communication可能需要触发Com PduR CanIf CanSM不同模块切换状态。谁来协调很多情况下就是BswMBswM 会根据各种条件EcuM State ComM Mode CanSM State Application Request Network State执行不同的Action List如果以后你做网络唤醒 休眠 诊断模式 通信模式切换BswM 基本是绕不开的。09 COM信号世界和报文世界的分界线接下来进入 AUTOSAR 最经典的一条链路COM PduR CanIf Can很多项目里面你每天调试最多的可能就是这一条。先看COMCOM 主要处理Signal Signal Group I-PDU Timeout Update Bit Transmission Mode假设 DBC 里面有一个VCU_MotorTorqueRequestApplication 写入MotorTorqueRequest 200 NmCOM 会负责把这个 Signal 按照配置放到对应报文里面。例如CAN ID 0x123 Byte0 Byte1 Byte2 ...Application 并不需要自己写Data[2]...Data[3]...这些工作由 COM 完成。所以Application ↓ Signal ↓ COM ↓ I-PDU这是一个非常重要的转换。10 PduRAUTOSAR 里面的“快递分拣中心”再往下PduR PDU RouterPduR 最容易理解。它基本不处理业务数据。它负责这个 PDU 从哪里来 这个 PDU 应该送到哪里比如COM ↓ PduR ↓ CanIf或者CanTp ↓ PduR ↓ Dcm甚至CanIf ↓ PduR ↓ COM所以 PduR 很像一个物流分拣中心。包裹到了以后它不拆包只看来源 目的地 路由规则然后转发。以后看到 PduR 时不需要把它想得特别复杂。先记住一句PduR 负责 PDU 路由。就够了。11 ECU Abstraction Layer把具体 ECU 硬件继续抽象继续往下就是ECU Abstraction Layer这一层名字非常关键ECU Abstraction它不是抽象 MCU。它抽象的是整个 ECU 板级硬件。比如一块 ECU 板子上可能有CAN Transceiver EEPROM External Flash Watchdog Sensor IO Expander External ADC这些东西不一定在 MCU 内部。所以需要一个层把这些具体 ECU 硬件进一步封装。典型模块例如CanIf CanTrcv MemIf IoHwAb12 CanIfCAN Driver 上面的统一接口比如CanIf CAN Interface它位于PduR ↓ CanIf ↓ Can Driver为什么不能让 PduR 直接调用 Can Driver因为 AUTOSAR 希望继续降低耦合。CanIf 会向上提供统一的 CAN 接口。下面具体是CAN Controller 0 CAN Controller 1 CAN Controller 2甚至不同硬件上层都不用太关心。因此你经常会看到CanIf_Transmit()最后才继续调用Can_Write()13 CanSM 和 CanNm 又是什么这也是刚入门最容易混淆的地方。很多人看到Can CanIf CanSM CanNm ComM直接开始混乱。其实它们负责的事情完全不同。CanCAN Driver负责真正控制 MCU 的 CAN 外设。CanIfCAN Interface负责对上层屏蔽 CAN Driver 的具体实现。CanSMCAN State Manager负责管理 CAN 网络的状态。例如No Communication Silent Communication Full Communication以及Bus-Off RecoveryCanNmCAN Network Management负责CAN 网络管理。例如Repeat Message Normal Operation Ready Sleep Prepare Bus Sleep Bus SleepComMCommunication Manager则站得更高。它负责管理整个 ECU 的Communication Mode所以简单画出来Application │ ComM │ CanSM │ CanIf │ Can旁边还有CanNm负责网络管理。以后我们讲 CAN 通信栈、NM 和休眠唤醒的时候会专门把这几个模块串起来。这一块也是 AUTOSAR 项目里面非常核心的一部分。14 MCAL真正碰硬件的地方再往下就到了很多传统嵌入式工程师最熟悉的一层MCAL Microcontroller Abstraction Layer中文通常叫微控制器抽象层MCAL 基本就是AUTOSAR 标准化之后的 Driver。常见模块包括Mcu Port Dio Adc Pwm Gpt Icu Spi Can Lin Eth Wdg Fls如果你以前做过裸机或者普通 MCU 开发这些名字几乎都不陌生。例如Dio就是数字 IO。Adc就是 ADC。Pwm就是 PWM。Can就是 CAN Driver。Fls就是 Flash Driver。区别在于AUTOSAR 对这些 Driver 的接口 配置 初始化 错误处理 调用方式都进行了规范化。15 为什么 MCAL 很重要比如我们现在用Infineon AURIX TC377底层可能涉及EVADC GTM MCMCAN PORT STM QSPI这些全部是 Infineon 的具体硬件模块。但是到了 AUTOSAR 上层以后不希望大家天天面对MODULE_EVADC MODULE_GTM MODULE_CAN所以 MCAL 会把它们封装成标准接口Adc_ReadGroup() Pwm_SetDutyCycle() Dio_ReadChannel() Can_Write()上层软件看到的是 AUTOSAR API。而真正的TC377 Register被藏在 Driver 内部。所以AUTOSAR Application ↓ BSW ↓ MCAL ↓ TC377 Hardware Register这就是硬件抽象真正落地的地方。16 最下面MicrocontrollerMCAL 再往下已经没有什么软件抽象了。就是Microcontroller例如Infineon TC377 NXP S32K3 Renesas RH850 ST Stellar里面真正存在的硬件模块CPU Core CAN Controller ADC Timer PWM GPIO SPI Flash RAM Watchdog最终软件的所有动作都会落到这些硬件上。比如你写Dio_WriteChannel(KL15,STD_HIGH);经过 Driver 之后最终一定还是某个寄存器发生了变化。AUTOSAR 并没有消灭底层寄存器。只是把寄存器和 Application 隔开了。17 Complex Driver 为什么单独放一块完整架构图里面还有一个非常特殊的东西Complex Drivers简称CDD为什么它没有老老实实按照Application RTE Service ECU Abstraction MCAL一层一层走因为实际项目里面总会遇到一些 AUTOSAR 标准没有很好覆盖的功能。例如特殊 ASIC 特殊 FPGA 自定义通信协议 高性能控制算法 特殊传感器 Timing 要求极高的 Driver如果严格穿过所有标准层级可能效率不够 接口不合适 实现非常别扭所以 AUTOSAR 留了一个口子Complex DriverCDD 可以根据实际情况直接访问MCAL Hardware甚至和RTE交互。可以把它理解成AUTOSAR 很规范但没有把路完全封死。18 用一个 CAN 信号把整张架构串起来到这里如果还是感觉模块很多没有关系。我们用一个真实场景串一次。假设 VCU 要发送VCU_MotorTorqueRequest 200 Nm整个路径可能是TorqueControl SWC │ │ Rte_Write ↓ RTE │ ↓ COM │ │ Signal → I-PDU ↓ PduR │ │ Route ↓ CanIf │ ↓ Can │ ↓ CAN Controller │ ↓ CAN Bus这就是一条非常经典的 AUTOSAR Tx Path。接收则反过来CAN Bus ↓ CAN Controller ↓ Can ↓ CanIf ↓ PduR ↓ COM ↓ RTE ↓ Application SWC如果以后你调试 CAN 报文CANoe 上没有报文就可以顺着这条链一层一层查。例如Application 有没有写 ↓ RTE 有没有调用 ↓ COM Signal 有没有更新 ↓ COM I-PDU 有没有触发 ↓ PduR 有没有路由 ↓ CanIf 有没有收到 Tx Request ↓ Can_Write 有没有调用 ↓ CAN Controller 有没有真正发送这就是为什么先理解架构比背 API 有用得多。19 再看一个 ADC 信号CAN 是这样。ADC 其实也是同样的思想。假设12V Battery Voltage通过 ADC 采集。硬件路径12V ↓ 电阻分压 ↓ MCU ADC Pin软件路径可能是Application ↑ RTE ↑ IoHwAb ↑ Adc ↑ MCAL ↑ ADC HardwareApplication 并不需要知道ADC Group 几 Channel 几 Result Register 在哪里这些东西可以被下面的抽象层屏蔽掉。所以 AUTOSAR 的核心思想从来不只是模块很多。真正的核心是分层 解耦。20 AUTOSAR 为什么要分这么多层看到这里可能有人还是会问以前Can_Write()一下就发出去了。现在为什么非要Application RTE COM PduR CanIf Can绕这么多层原因其实很现实。汽车软件已经不是几万行代码的小项目了。一个量产 ECU 里面可能有几百个 SWC 几千个 Runnable 上万个 Signal 几十个 CAN / LIN / Ethernet Channel 大量诊断服务 大量 NVM 数据 多个 CPU Core如果没有这些分层所有模块全部互相调用项目很快就会变成A 调 B B 调 C C 又直接访问 Hardware D 又依赖 B E 又改了 C最后谁都不敢动。AUTOSAR 做的事情本质上就是规定谁可以和谁说话 通过什么接口说话 每一层负责什么 哪一层不能越界软件规模越大这种架构价值越明显。21 以后看到一个 AUTOSAR 模块先做这件事以后再看到NvM Dem Dcm CanSM CanNm EcuM BswM PduR ComM先不要急着打开几百页 Specification。第一件事情把它放回架构图。例如Can看到名字就应该想到MCAL Hardware Driver看到CanIf应该想到ECU Abstraction看到COM应该想到Communication Service看到RTE应该想到Application 和 BSW 的边界看到SWC应该想到Application当这种位置感建立起来以后AUTOSAR 就不会再是一堆缩写。它会慢慢变成一张地图。22 最后再把整张图压缩一次如果今天这篇文章只记住几句话记下面这些就够了。Application负责车辆功能。RTE负责连接 Application 和 BSW。Services Layer负责操作系统、通信、诊断、存储、模式管理等公共服务。ECU Abstraction负责屏蔽 ECU 板级硬件差异。MCAL负责直接控制 MCU 外设。Microcontroller就是真正的硬件。把它压缩成一条线业务逻辑 ↓ Application ↓ RTE ↓ BSW ↓ MCAL ↓ Hardware这就是 AUTOSAR Classic 最重要的软件架构。23 这张图后面会一直用从下一篇开始我们会开始真正拆 AUTOSAR Classic 的内部结构。你会发现后面不管讲SWC RTE OS EcuM BswM CAN Communication Stack Network Management Diagnostic NvM MCAL其实都只是在不断放大今天这张图里面的某一块。所以这篇不用急着把所有模块全部记住。先建立层级感。以后看到任何一个 AUTOSAR 模块能够大概知道它在哪一层 它上面是谁 它下面是谁 它负责什么做到这一点AUTOSAR 就算真正开始入门了。下一篇预告下一篇我们继续往下拆《MCAL、ECU Abstraction、Service Layer、RTE、ASW到底是什么关系》车控码农AUTOSAR 从 0 到 1 系列不堆概念不照着 Specification 念。从真正做 ECU 开发的视角把 AUTOSAR 一层一层拆开。