ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

AUTOSAR入门:从分层架构到CAN通信Demo的实践指南

AUTOSAR入门:从分层架构到CAN通信Demo的实践指南 1. 先搞清楚AUTOSAR到底是什么很多刚转行做汽车电子软件的朋友打开招聘网站看到满屏的“熟悉AUTOSAR优先”第一反应是去搜“AUTOSAR入门”然后就被一堆术语砸懵了CP、AP、BSW、RTE、SWC、EcuC、NvM、Dem……说实话我当年刚接触AUTOSAR的时候也是一样花了很久才把这些概念串起来。所以这篇文章我不打算做成一份“从入门到放弃”的字典式教程而是站在一个过来人的角度带你把AUTOSAR从头到尾捋一遍让你搞清楚它到底是什么、为什么会出现、平时开发到底碰它哪些东西以及怎么一步步上手。先回答最基础的那个问题AUTOSAR是什么全称是AUTomotive Open System ARchitecture汽车开放系统架构。它不是一套我们能下载安装的软件也不是某个具体的操作系统而是一套软件架构的标准化规范。你可以把它理解成汽车电子行业的“乐高说明书”——每一块积木做成什么形状、接口留在哪里、互相之间怎么拼都有统一规定不同厂商只要按同一份说明来造积木拼出来就能严丝合缝。这套标准解决的是一个非常真实的行业痛点。早年间的ECU电子控制单元软件开发芯片厂商、Tier1、OEM各有各的封闭体系底层驱动跟应用逻辑死死绑在一起换一颗芯片就意味着底层代码全部重写不同供应商的软件模块互相不兼容集成一次要烧高香。AUTOSAR出现以后把ECU软件从下到上做了分层每一层之间有标准接口应用层的人不用关心底层是哪家的芯片底层的人也不用被迫理解整车的业务逻辑。开发模式从“针对单个ECU的垂直开发”变成了“平台化、模块化的横向复用”这才是AUTOSAR真正的价值。AUTOSAR发展到现在有两条技术路线。一个是Classic Platform经典平台行话叫CP面向传统MCU微控制器上对实时性、确定性要求极高的控制功能用的是C语言。另一个是Adaptive Platform自适应平台行话叫AP面向高算力SoC和自动驾驶这类需要动态部署、大规模运算的场景用的是C。大多数刚入门的人特别是做MCU底层、做嵌入式BSP、做CAN通信诊断相关工作的接触最多的是CP。这篇文章也以CP为主线来讲AP我后面会单独再开一篇聊。提示如果面试被问到“AUTOSAR是什么”千万别答“AUTOSAR是一个操作系统”。这是最容易被纠正的错误标准答案应该是“一套开放、标准化的汽车软件架构方法论”。2. 从架构图看AUTOSAR怎么“分层治理”研究AUTOSAR第一步一定是看懂那张经典的三层架构图。网上搜“autosar架构详细介绍”能搜出一堆但大多数人都没把这图画在脑子里。我建议你也自己在纸上画一遍画完你对整个体系的认知会清楚很多。2.1 应用层、RTE、基础软件层各管什么整个CP架构分三层最上面是应用层Application Layer中间是RTERuntime Environment运行时环境最下面是基础软件层BSWBasic Software。应用层里跑的是一个一个独立的软件组件叫SWCSoftware Component。每个SWC只负责一段具体的业务逻辑比如“车窗防夹功能”“自动大灯控制”它们彼此之间不直接通信而是通过端口Port和接口Interface来交换信息。这样设计的好处是什么模块之间彻底解耦一个SWC内部怎么实现不影响别人你甚至可以把它整体替换掉只要对外接口不变系统照常运行。RTE是整个架构的心脏它既是“通信总线”也是“调度中枢”。SWC之间所有的数据交互不管是在一个ECU内部还是跨ECU走CAN总线在应用层的代码里看来都只是调用了一个简单的函数接口。RTE把这些调用翻译成一次进程间通信、一次内存拷贝或者一路CAN报文发送对上层完全透明。另外RTE还负责按照配置去周期性地调度各个SWC里的Runnable可运行实体保证每个任务按照要求的周期执行。最底下是基础软件层它又细分成四个子层服务层Services Layer、ECU抽象层ECU Abstraction Layer、微控制器抽象层MCALMicrocontroller Abstraction Layer以及复杂驱动Complex Drivers。这四个子层一层包一层目的就是把硬件藏起来。MCAL直接跟寄存器打交道提供诸如GPIO、ADC、PWM、SPI这类最底层的驱动接口ECU抽象层把MCAL的差异进一步抹平让上层看到的是统一的外部设备比如“某个外部Flash”而不是“SPI3上的那个芯片”服务层则提供操作系统、通信管理、存储管理、诊断管理这些系统级服务也就是后面要展开讲的OS、Com、NvM、Dem这些模块。2.2 配置与生成AUTOSAR开发的核心工作方式AUTOSAR架构里有个非常容易被新手忽视的点它不只是“运行时”的架构更是“开发期”的架构。什么意思呢在传统嵌入式开发里你写代码、编译、烧写一个main函数从头用到尾。在AUTOSAR里代码不是你手动写出来的而是由工具根据一套配置文件生成的。这套配置文件就是AUTOSAR XMLARXML里面描述了整个ECU的所有配置参数有哪些SWC、它们的端口和接口怎么定义、CAN通信的波特率和报文矩阵、NvM要存几块数据、诊断协议支持哪些UDS服务……工具链读取ARXML配置自动生成对应的代码骨架。每个AUTOSAR模块EcuC、Can、NvM、Os等都有一堆配置参数这些参数被组织在工具生成的配置界面上代码则由工具“一键生成”。这套工作方式对开发者的最大冲击就是你要做好心理准备你的工作重心从“写代码”变成了**“配参数”**。而且AUTOSAR这种“用参数描述一切”的设计对参数语义的理解要求很高——你不但要懂这个模块是干嘛的还要知道每个配置项在运行时会怎样影响行为。举个例子NvM模块里有个参数叫“写校验”Write Verification你把它开了每次写Flash之后NvM会主动读回数据做比对数据可靠性大幅提高代价是写操作的时间变长。这个参数开不开直接取决于你的应用对存储时间和可靠性的取舍——这些判断才是AUTOSAR工程师真正的价值。3. 核心模块逐个拆解热词背后都是日常开发的主角网上搜索热度最高的几个词基本上是autosar can、autosar cantp协议、autosar os、autosar nvm、autosar dem、autosar ecuc模块、autosar网络管理。这些全部属于BSW层也是日常开发打交道最多的模块。我按通信、存储、诊断、系统这四类逐个给你拆。3.1 通信家族Can、CanTp、PduR、Com是怎么协作的CAN通信是AUTOSAR里最核心也最容易绕晕的一块。很多初学者一上来就被一堆缩写劝退CanIf、CanTp、CanSM、PduR、Com、CanNm……它们之间到底什么关系简单说一条报文从应用发到总线要经过这层链路应用通过RTE调用Com模块的接口比如Com_SendSignal()把信号值交给Com。Com把多个信号打包成一个PDUProtocol Data Unit协议数据单元通过PduRPDU RouterPDU路由器做转发。PduR把这个PDU路由到对应的通信接口模块——如果是普通CAN报文就是CanIfCAN InterfaceCAN接口模块如果是长于8字节的报文要走CAN FD或传输层分包那就由CanTpCAN Transport ProtocolCAN传输层协议来处理。CanTp把大PDU拆成多帧逐帧交给CanIf再由CanDriverCAN驱动最终送到底层控制器发送出去。CanTp就是热词里那个“autosar cantp协议”它专门解决“CAN单帧只能发8个字节但我一条诊断消息可能几百个字节”的问题。注意看CanTp的四个帧类型单帧SF、首帧FF、连续帧CF、流控帧FC。发送方先发一个首帧告诉接收方“我要发一个长度多大的消息”接收方回一个流控帧说“你一次可以发多少帧、隔多久发一帧”然后发送方按这个节奏把剩余数据用连续帧发完。听起来有点绕打个比方你给朋友寄快递一箱书太重装不进一个包裹你就先发一条微信说“我要寄200本书”首帧朋友回“好的你分5次寄每次间隔10分钟”流控帧然后你就按约定一批一批地寄连续帧。CanTp干的就是这件事。PduR是通信链路里那个“看不见但离不开”的中间人。不管是Com上来的报文、诊断Dcm下发的UDS消息还是网络管理Nm的报文统统先汇总到PduR再由它决定路由给CanTp还是CanIf。印象里我刚学的时候总把PduR和Com搞混找准他们的定位就好了Com做的是信号到PDU的打包/解包PduR做的是PDU的路由分发。3.2 系统服务三件套Os、EcuC、网络管理AUTOSAR OS不是我们熟悉的Linux或者FreeRTOS它遵循OSEK/VDX标准是一个静态配置的实时操作系统。所谓“静态配置”是指任务、中断、计数器、调度表这些统统在配置阶段就定死了编译后不许动态创建。它的核心能力是调度——支持基于优先级的抢占式调度、时间表驱动的周期任务还有一系列针对汽车控制场景的机制比如“保护钩子ProtectionHook”可以在任务出错时执行特定处理。在AUTOSAR架构里我们不会在代码里指定任务的启动顺序而是通过调度表来精确排布这对那些需要严格按相位执行的控制算法特别重要。EcuCECU Configuration模块不干具体活它像是一个“总目录”存了整个ECU的配置信息哪些PDU参与了收发、每个PDU的CAN ID是多少、用的是哪个通信通道、DETDefault Error Tracer默认错误跟踪器要不要开、开发错误报告打到哪个级别……几乎所有其他模块的配置都要引用EcuC里的定义。你在工具里配CAN报文矩阵时填的那些地址、长度、端到端校验信息最终都会汇总到EcuC。它是配置ETL里那张“主表”。**AUTOSAR网络管理CanNm**解决的是ECU在整车网络里的“休眠/唤醒”协同问题。传统做法是靠硬线电平控制睡眠AUTOSAR网络管理则完全基于报文节点上车后先发“NM报文”告诉网络“我醒了”然后一边正常通信一边周期性地“心跳”想睡觉的节点在完成自己的任务后不再发NM消息但如果还收到别人的NM消息就继续保持清醒等到网络里所有节点都不再发NM消息各节点在约定的超时时间后自动进入低功耗模式。很多人一开始不理解为什么要搞这套网络管理其实核心目的是省电、同时让整车在熄火后还能保持一致性。3.3 存储与诊断NvM、Dem、Dcm的三角关系**NvMNon-Volatile Memory Manager非易失存储管理模块**负责管理ECU里需要掉电保存的数据比如故障码、保养里程、配置参数。它本身不直接操作Flash芯片而是把不同存储块Block映射到底层EEPROM或Flash驱动上。为什么要有NvM这样一层因为直接操作Flash要面对擦写次数限制、掉电写一半、数据校验这些烦人的问题。NvM替你把这些事都兜住了管理块状态机、数据校验和冗余备份、掉电时的恢复逻辑。配置NvM时主要关注Block的类型原生块、冗余块、数据集块、校验机制、写入条件、重试次数这些参数。**DemDiagnostic Event Manager诊断事件管理模块**负责管理故障状态。整车诊断里我们常说“故障码”但在AUTOSAR里更准确的概念是“诊断事件”——不只是“坏了”这一种状态还包括“测试通过”“失败”“待处理”这些中间状态。应用层检测到异常时调用Dem_SetEventStatus()报告给DemDem内部记录事件的发生次数、老化状态、DTC状态字节并触发NvM把数据存到掉电不丢失的区域。等Tester通过诊断仪读故障码时Dcm把Dem维护的DTC信息通过UDS 0x19服务返回给诊断仪。**DcmDiagnostic Communication Manager诊断通信管理模块**是诊断协议栈的“前台”负责接收和解析Tester发来的UDS请求。发请求到ECU后Dcm根据服务ID分发给内部不同的处理器是读/写数据标识符0x22/0x2EDcm就直接从配置的数据字典里读写是请求例程0x31Dcm就调上层注册的回调函数是读故障码0x19Dcm则委托给Dem去取数。Dcm和CanTp的关系也很密切诊断请求过来时CanTp负责把多帧数据重组完通过PduR交给DcmDcm回响应也是先发给CanTpCanTp分包后再从CAN发出去。注意NvM、Dem、Dcm这三个模块之间的依赖关系很典型。Dem要把故障码存NvM、读故障码要动NvM、Dcm要拿Dem的数据三者的配置顺序要一起理单独配一个往往会在集成阶段报一堆连不上接口的错。3.4 MCAL与复杂驱动最后两公里MCAL是BSW最底层的一层直接跟寄存器打交道。它由芯片厂商提供但接口遵循AUTOSAR规范所以上层ECU抽象层不用关心你用的是NXP、Infineon还是瑞萨。MCAL里有Can驱动、Lin驱动、Spi驱动、Adc驱动、Gpt驱动、Pwm驱动等这些驱动一方面要实现标准的AUTOSAR接口另一方面还要针对具体芯片做大量的厂商扩展。复杂驱动Complex Drivers是架构留给“例外”的窗口。有些功能对时序要求极其苛刻、或者需要直接操作特殊硬件外设不适合按常规AUTOSAR模块的方式套进去比如某些特殊的高精度PWM生成、某些私有总线协议就可以做成复杂驱动在配置工具里留一个SWSrc代码槽把自定义实现挂进去。简单说MCAL是AUTOSAR平台在具体芯片上落地的“桥头堡”复杂驱动则是“后门”。做底层驱动的人这两个都要会因为芯片厂商给的MCAL往往要根据项目做裁剪复杂驱动就更是百分百的苦力活。4. 实操从零到一跑通一个CAN报文收发Demo架构说得再多不如亲手跑通一个小Demo。这里我给一条自己带过很多新人走通的路线你照着做思路会清晰很多。4.1 工具选型到底选哪家的AUTOSAR工具链做AUTOSAR CP开发几乎离不开商业工具链。目前市面上主流是Vector的DaVinci Developer DaVinci Configurator Pro、EB的tresos也叫EB tresos Studio、ETAS的ISOLAR还有Elektrobit、Mentor等。个人学习的话EB的tresos在授权和上手友好度上相对亲民一些而且很多芯片原厂如NXP、Infineon的SDK里会预集成部分EB生成的驱动官方demo也很多。Vector家的工具集成度高、资料多但价格和启动时间都让人肉疼。我个人的建议是学习阶段选一个芯片原厂的评估板 一套有免费评估版的AUTOSAR工具EB这套是很多人的首选把驱动配置和通信栈跑通比什么都重要。提示工具链没有绝对的好坏重要的是你愿不愿意花时间把它磨熟。一个工具用了三年效率肯定比你频繁换工具的人高。4.2 配置一个基础功能CAN报文周期发送假设现在有个最朴素的需求ECU上电后以100ms周期在CAN总线上发送一条长度为8字节的报文内容固定为0x11 0x22 0x33 0x44 0x55 0x66 0x77 0x88。这个需求放在AUTOSAR里怎么做第一步在EcuC里定义这条PDU指定它的CAN ID比如0x123、数据长度8字节、发送周期100ms并把它分配给某个CAN通道。第二步配置CanDriverMCAL层和CanIf。CanDriver要做的是初始化CAN控制器的波特率500kbps配置收发邮箱Mailbox的映射CanIf负责把EcuC定义的PDU关联到具体的硬件邮箱上让它知道“0x123这条报文用哪个邮箱发出去最合适”。第三步配置PduR和Com。PduR里把EcuC里Pdu的路由信息加进去Com里要为这8字节的每个字节定义“信号”——如果只是发固定数据可以直接用Com的固定值功能某些工具还支持直接用信号组把0x11~0x88封装成一个信号组合。第四步配置OS。AUTOSAR的COM报文发送通常由一个周期任务触发。我们要创建一个Task让它每100ms被调度一次Task里调用Com_MainFunctionTx()Com模块就会根据配置把PDU组织好交给PduR、CanIf、CanDrv最终发到总线上。整个过程做完用工具生成代码然后把你写的启动代码调EcuM_Init()、Can_Init()等模块初始化集成好编译烧录用PCAN或者周立功CAN卡接上总线就能看到0x123这条报文周期性地出现了。4.3 一个典型的集成顺序建议很多新人在集成AUTOSAR代码的时候喜欢“一股脑全生成然后编译”结果报错几百条看到就崩溃。我建议按这个顺序来先把MCAL跑通。只生成Can、Gpt、Port、Mcu这些底层的模块不加通信栈——先用一个裸机测试函数往里塞一个报文测试硬件收发确认驱动本身没问题。加入CanIf和CanTp接上PduR。这阶段用工具自带的“回环测试”(Cannel)功能看硬件发出去的报文能否被自己收到确认通信链路通的。加上Com配几个信号测试应用发信号给Com是否能正确地打包成PDU并发送。最后接RTE和SWC。创建两个SWC一个周期发送、一个周期接收确认RTE的端口连接和调度没有问题。每走一步都编译、下载、测试出了问题能马上定位是这一层的配置错了还是上一层的接口没接上。这个习惯我后来在带人的时候反复强调效果非常好。5. 入门学习路线与避坑实录5.1 三个月学习路径参考AUTOSAR的学习曲线确实是“开头最难”。我的建议是前三个月分三段走第一个月打基础。先把C语言、嵌入式基础巩固一下然后看AUTOSAR的官方规范文档可以从AUTOSAR官网下载Classic Platform各模块的SWS文档英文不好没关系先看图、看状态机、看接口函数列表。配合一本书比如《AUTOSAR规范与车用控制器软件开发》把架构框架建立起来。第二个月动手实践。买一块带CAN的MCU开发板STM32 CAN收发器或者直接用带CAN的英飞凌TC2xx评估板按上面那个Demo的路径把最简单通信用栈跑通。不一定要完整的商业工具链网上有开源的AUTOSAR实现比如开源社区有一些简化版BSW用它们来理解模块间的关系也很有帮助。第三个月专项深挖。选定一个你最感兴趣的模块通信栈、诊断栈、存储管理把它的规范文档从头到尾精读一遍然后把开发板上的对应功能调试通关。这之后你再看招聘JD上那些AUTOSAR要求基本就不会发怵了。5.2 常见问题和排错思路速查表现象可能原因排查方向生成代码后编译报错模块间接口对不上配置里PDU/信号/端口的命名或ID不一致检查EcuC的PDU定义、PduR的路由表、Com的IPdu映射是否对齐ECU上电后CAN报文一直不发任务没有调用Com_MainFunctionTx()或者周期任务的调度使能没开在OS配置里确认Task附着到了正确的调度表用调试器看任务有没有被正常执行短报文正常、长诊断报文收发超时CanTp的参数没配好检查CanTp的STmin、BlockSize这些流控参数结合对端ECU能力做匹配掉电后NvM存储数据丢失写条件、校验方式或Block属性没配对查看NvM的写校验、冗余、CRC配置确认应用层的写调用时机在掉电准备之前完成诊断仪读到“No response”Dcm没启动或PduR没有把诊断PDU路由给Dcm检查Dcm的配置、CanTp的PDU ID过滤条件以及Dcm任务是否周期调用代码生成后一个模块的参数“被覆盖”工具合并配置时不同人改动了同一处共用配置用好工具的Diff/Merge功能规范导出和导入流程避免多人直接改同一个ARXML额外避坑心得不要手改生成的代码。AUTOSAR工具生成的代码经过复杂处理你改了再次生成就会被覆盖。正确做法是回到配置项里改参数或者使用工具支持的“代码插槽”SWSrc/SWCnt来增加自定义代码。我见过太多人图一时方便直接在生成的Can.c里改了寄存器操作结果下一次生成后用不起来白折腾半天。用版本管理工具管ARXML。配置文件是AUTOSAR项目的核心资产一定要用好Git这类工具。两个人同时改一个ARXML产生的Merge冲突是很多新手团队踩的第一个大坑。建议配置变更先沟通再动手尽量用分散的模块配置文件减少冲突面。日志是救命稻草。AUTOSAR模块普遍有“开发错误报告”机制打开DET后程序出错会打印出一个8位错误码很多问题靠这个错误码“直指病灶”。如果调试时发现代码跑飞死机第一反应应该是去翻DET日志而不是对着寄存器猜。5.3 关于“autosar core1无法正常运行”这类问题的看法最后聊聊搜索热词里那个“autosar core1无法正常运行”。如果你用的是多核MCU比如TC3xx、S32K3遇到过核1或某个核的AUTOSAR任务起不来通常绕不开这几个原因第一OS的核间配置问题。AUTOSAR OS是支持多核的MC-OS每个核有自己独立的任务和中断但系统时钟、IOC核间通信和共享资源的访问必须配置同步否则核1起来就卡在等待某个核间信号上。第二MCU启动代码没有把对应CORE的初始化代码带进来。很多多核MCU存在一个“主核负责启动、从核需要被主核唤醒”的过程如果启动流程只初始化了Core0忘记给Core1建好启动向量表并解除复位Core1自然跑不起来。第三数据一致性和内存保护。多核在共享内存上访问同一个全局变量时如果没有缓存一致性管理或者内存保护配置不对典型表现就是“偶尔正常跑一段时间后某一个核死掉”。碰到这种问题我的建议是先用芯片原厂的裸机demo确认硬件和启动流程本身没问题再逐个核去初始化AUTOSAR OS组件不要把多核的问题一上来就归因到AUTOSAR头上——很多时候问题出在自己对芯片启动流程的理解上。写在最后的一点体会我在这个行业里摸爬滚打好几年一个特别深的感受是AUTOSAR入门这件事最大的障碍不是技术本身而是“不知道从哪里开始”。它不像学Linux驱动那样你装个虚拟机、开个终端就能动手敲代码AUTOSAR的工程化门槛很高商业工具链贵、文档厚得像本砖头、术语又多新手经常困在“看不懂规范—不会用工具—无法实践”的死循环里。我的建议是别试图一次把所有模块都搞懂。先抓住通信栈这一条主线从Can收发到Com到RTE把它跑通你就有了一张“通关地图”其他模块比如NvM、Dem、Dcm本质上都是类似的结构——配参数、生成代码、做集成、调试。而且在实际项目中往往是有经验的老人带着做一两个完整功能比自己看三个月文档都管用。如果你身边有懂AUTOSAR的同事一定要厚着脸皮多问无论是配置上的细节还是排查问题的思路比你看十篇教程都值。最后再分享一个我在实践中特别受益的小技巧每个AUTOSAR模块的参数除了官方SWS文档里的“配置参数表”工具界面里的帮助文档往往更通俗、更贴近实际工程里面会告诉你这个参数在什么场景下改、跟哪些参数联动。每配一个陌生的模块先花半小时把工具里那些参数说明过一遍比直接拿着PDF硬啃高效得多。这个习惯帮我少走了很多弯路也希望正在读这篇文章的你能早一点跨过“AUTOSAR入门”这道坎。
返回列表