一、写在前面
工作的第一份工作就是从事autosar cp组件的开发,依然还很清晰的记得,我在恒润时的导师在介绍autosar时,说:所谓的autosar cp其实就是:
- 软件架构
- 接口
- 方法论
由于自己是软件工程师,所以在很长时间,我都认为AUTOSAR_EXP_LayeredSoftwareArchitecture.pdf的内容就是autosar的全部,直到后面了解的越来越多才发现,好像软件架构并不是全部,甚至在整个autosar工作流中不是最重要的一部分。在从恒润出来之后,接触到了linux开发,又受到了真正软件大拿的影响,才发现原来自己曾经奉为圭臬的autosar文档是如此的晦涩难懂,各个组件内部居然如此没有可读性;所以在后面依然决定投入到linux下的软件开发,甚至导致我很长时间都不喜欢autosar的软件架构和设计,甚至由于autosar,我都不喜欢mcu的开发。直到最近又不得不脱离软件角度的来重新审视cp。
我对cp的看法,从初入职场的惊为天人:原来写代码可以如此轻松--->开始接触linux的开发:原来还有这么多设计,还能这么灵活,这才是真正的软件工程;--->跳开软件角度:原来autosar真的可以把各个水平、不同组织的人完成一个能够稳定、正常运行的大型软件工程项目。
在职业生涯也遇到了、听到了很多人对于autosar批判、赞美甚至铁粉和黑粉。这像极了当前社会非黑即白的造神运动,当然我自己也是从这个过程中逐渐改变认知, 不过发展至今,我依然觉得对于很多组织尤其是OEM来说,autosar依然有很多改进、裁剪的空间。
所有人都知道的autosar优点:
- 软件分层、模块化、封装
- 接口标准化
- AUTOSAR是一个符合ISO26262标准的软件架构
就像曾经的我一样,我也是以为这是autosar cp最大的优点,但是我现在觉得cp最核心也是最重要的反而是方法论,如果要再加一个限定,我认为最最核心的是:工具。不管是方法论也好还是软件架构也好,脱离了工具,autosar也就失去了很多意义(先别着急,看后面的分析)。
二、autosar方法论
autosar方法论是一个超级大的话题,以及包含超级多的内容,别的不说,单说:TPS的template文档,以及TR的方法论文档就是大几千页。接下来想才能够开发流程、信息载体(arxml)以及标准组件和接口简单阐述一下自己的理解。
1. 开发流程
AUTOSAR设计和开发流程分为三个阶段:系统配置、ECU设计与配置阶段、代码生成阶段。官方下图:
三个阶段具体来说就是:(下述会以一个具体功能展开描述这三步包含哪些内容以及在开发过程中,如何体现)
第一阶段:定义系统配置文件,这是系统设计者或架构师的任务。包括选择硬件和软件组件,定义整个系统的约束条件。AUTOSAR通过使用信息交换格式和模板描述文件来减少初始系统设计时的工作量。系统配置的输入是XML类型的文件,输出是系统配置描述文件,系统配置的主要作用是把软件组件的需求映射到ECU上。
第二阶段:根据系统配置描述文件提取单个ECU资源相关的信息,提取出来的信息生成ECU提取文件。根据这个提取文件对ECU进行配置,例如操作系统任务调度,必要的BSW模块及其配置,运行实体到任务的分配等,从而生成ECU配置描述文件。该描述文件包含了特定ECU的所有信息。
第三阶段:生成代码,是基于ECU配置描述文件指定的配置来产生代码、编译代码,并把相关代码链接起来形成可执行文件。
具体的开发流程大致分为5步:
- 编写系统配置输入描述文件
在AUTOSAR中,所有的描述文件都是XML类型(ARXML)的文件。系统配置输入文件包含三部分内容:
- 软件组件描述,定义了每个涉及的软件组件的接口内容,如数据类型,端口,接口等。
- ECU资源描述,定义了每个ECU的资源需求,如处理器、存储器、外围设备、传感器和执行器等。
系统约束描述,定义了总线信号,软件组件间的拓扑结构和映射关系。
- 系统配置
系统配置的功能主要是在资源和时序关系的前提下,把软件组件映射到各个ECU上,然后借助系统配置生成器生成系统配置描述文件。这个描述文件包括总线映射之类的所有系统信息以及软件组件与某个ECU的映射关系。
- 提取特定的ecu的描述
从系统配置描述文件中提取出与各个ECU相关的系统配置描述信息,提取的信息包括ECU通信矩阵、拓扑结构、映射到该ECU上的所有软件组件,并将这些信息放在各个ECU的提取文件中。
- ECU配置
ECU配置主要是为该ECU添加必要的信息和数据,如任务调度、必要的基础软件模块及其配置、运行实体及任务分配等,并将结果保存在ECU配置描述文件中,该文件包含了属于特定ECU的所有信息,换言之,ECU上运行的软件可根据这些信息构造出来。
- 生成可执行文件
根据ECU配置描述文件中的配置信息,生成RTE和基础软件配置代码,完成基础软件和软件组件的集成,最终生成ECU的可执行代码
做过基于AUTOSAR CP开发的小伙伴都会知道上述是一个很理想的状态,理论上所有的配置或者信息都可以承载在ARXML中,但是实际上很多ECU资源相关都是在excel等文档中描述的,配置还是手动配置上去的,最后由工具厂商提供的工具储存在BSW相关配置中。
软件工程师经常说需要定义软件边界,所谓的软件边界其实就是不同功能集之间交互的接口,具体来说,对于某个模块来说,就是需要什么输入,输出什么东西,因此如所谓的软件组件描述,其实就是定义软件组件的接口内容,如数据类型、接口。对于在不同的方法论体系下这些都是相同的,对于SOA来说,关注的服务+接口,对于传统autosar来说,关注的是swc、数据类型、端口和接口,所以本质上来说,不管是吹的很火的SOA还是被“誉为落后”的CP,在想要达到:功能灵活设计、快速迭代,在顶层设计来看是没有区别的。只不过在实现过程中不一样而已。后续我也会写SOA和autosar cp的本质区别。
以下面三个图为例,首先我们需要梳理出,我们有哪些功能,最后将功能映射到具体的软件组件(swc)去,但是功能和swc并不是一一对应的,因为逻辑上的和真实实现上还是可以有差别,主要是从实现角度是做一个取舍,但是这并不会改变不同功能之间的输入、输出关系。在确定好软件组件以及输入、输出关系后,我们就可以通过虚拟功能总线,将不同的swc连接起来。此时,是将整车所有的ecu当成一个整体来看的,而所谓的虚拟总线需要有不同的实体来对应,在autosar cp世界里就是RTE了,而在SOA中就是service framework + communication了。
在顶层设计中,是将所有的ecu(整车)当做一个整体来看的,实际上不同的swc会根据功能、资源需求等因素分配在不同的ECU中,这个时候就要区分SWC的输入是来自同一ECU的全局变量,还是来自通信总线的数据,因此结合整车EE就会有如下图示。这个时候就进入了ECU开发阶段了。
system template定义纯软件视角和真实ecu系统架构下的网络联系:(Topology, Software, Communication, Mapping and Mapping Constraints )
- 系统拓扑:描述系统逻辑,ecu连接到哪个集群或者通道
- 通信特性:帧交换
- mapping:软件组件到ecu的分布,软件组件间交互所用到的数据元素,以及到信号和帧的映射
对于进入到ECU开发阶段,我们其实就不过多赘述了,无非就是APP开发(基于MBD、手搓代码等),底层软件开发以及软件集成。
2. 信息承载(文件交换)
众所周知,ARXML是所有autosar不同工具、不同组织和不同过程中信息交换的载体,而对于autosar来说,它是基于UML 2.0框架下开发的(题外话:UML曾被誉为能够解决软件开发的“银弹”)。对于大部分开发者来说,几乎是不会打开ARXML来看的,但是对于AUTOSAR CP平台的开发者来说,却是跟原始ARXML打交道比较多的,尤其是架构者角色。
AUTOSAR 使用xsd文件描述了scheme,列出了所有公开的、标准的配置项(体现在arxml就是lable),约束相关数量,换句话说,前面提到的所有过程都可以承载在这scheme所列出的内容中。正是由于有了scheme,可以使用工具很好的生成arxml解析库,而无需要手动解析。如下图所示:
很多人都使用过了不同的AUTOSAR CP ecu开发工具,都会发现不同的工具UI/UE千差万别,但是内容却高度一致,是因为这里面还有一个基于AUTOSAR scheme具化出来的规范文件,那就是bsw describtion definition文件,其不仅定义了不同组件的配置,不同组件间的依赖关系,还定义了相关配置的属性和约束。正是因为如此,在你使用davinci等工具时,会发现有些输入只能是字符串、数字或者只能下来选择,甚至还有范围约束。对于一个资深或者说优秀的cp ecu开发者来说,不管是谁家的平台,在掌握了其背后的原理后,使用工具就不是问题了。ps:针对不同的厂家,其bswdef.arxml是会有定制化更改的,但是这些都是明文的,都是直接打开阅读的。如下所示:
3. 标准组件和接口
这一节,无需多言,autosar cp定义了严格的分层和很多标准组件。对接口来说,标准接口和AUTOSAR标准接口,大家都能很好的理解;而AUTOSAR接口,则是其粘合各种非标模块的关键之一。
4. 总结
所谓的AUTOSAR的方法论,其实无非就是3点:
- 定义了标准的开发流程,这样就让不同的OEM、Tirex,不同团队之间有了一套统一的开发流程
- 定义了软件分层、标准模块和接口
- 定义了统一格式的交换文件,在不同流程、不同团队中能够很好的协同开发。
为了让大家能够更好的遵从上述三点,所以autosar体系下都是强工具、弱代码!!只有这样才能保证大家在各个环节去创新,最后导致大家细节上流程各异,这就是为什么大家说AUTSOAR CP抹杀了很多软件开发能力,但并不是说AUTOSAR CP本身就是很low,事实上是因为在CP的世界里,它是希望能够将所有的设计上移至工具,而不是在手搓代码的过程中。因此,如果工具足够牛逼的话,在工具完成一系列配置(点点点)之后,编译运行完全是可以做到没问题,这就是不同厂家工具的最大差异性,都知道vector的davinci好,为啥好,无非就是使用它的工具需要再操心的事情最少了,其有各种联动、校验以及快速修复。
说到这个,为啥我曾经会觉得cp很傻,因为从源代码角度,发现其代码可读性、可维护性实在太差了,事实人家就没想让使用者从代码角度来理解,需要结合工具来理解,而不是单单从源码角度。
理想很丰满,现实很骨感,对于具体的团队来说,在CP体系下的开发,依然需要探索出来一条属于自己团队的流程。因为对于CP来说,它是严格遵从V模型的,其理想状态是保证前一个环节没有问题再流转到一个环节,所以在整个开发流程中,很多是串行的,这会导致开发周期变长,在这里就需要结合团队的差异性,看能否优化开发流程。
三、为什么说AUTOSAR CP是面向信号?
相信在所谓的“软件定义汽车”大背景下,都听说过一句话,传统autosar开发是基于信号,严重影响迭代速度,需要上SOA。整句话包含两个信息,先不论后面的结论是对的,至少传统autosar真是基于信号开发的。那所谓的信号指的又是啥?
绝大部分软件工程来说,都是包含两部分:信息传递和调度。而信息传递可以有多重实例,比如函数调用,网络通信,但是不管如何,最终对于信息交互的双方,都需要明确知道相互交流的含义,所以就有了各种协议以及序列化,而AUTOSAR CP来源传统的CAN/LIN通信,基于信号体系下的,所以在CP的世界里,所有的信息被称为了信号。其实所谓的信号,和互联网领域提到的序列化和反序列化之后的数据没有任何区别,无非由于CAN/LIN总线带宽有限,导致其一个ID就能代表其数据序列化规则,而互联网下从MAC->IP->PORT->高层协议,最终到具体的应用层才有序列化规则。从这里看出,所谓的面向信号,其实都是不得已而为之,带宽下,协议层数少,没法进一步高度分层、抽象,导致在实际开发过程中灵活性降低。从踏入职业生涯就开始接触所谓的SOA,一直都在思考什么是SOA,通信基石又是什么?是以太网?是someip?是dds?亦或者其他协议?那我的答案:都不是,是大带宽和IP。文章《SOA通信基石》描述了如何从传统的RTE理解SOA,为什么是IP,以及SOA是银弹么?描述了自己对SOA理解。
言归正传,CP是面向信号,是因为其一开始本身就是面向信号而生,所以其很多内容都是站在信号的角度来阐述,所以所CP是面向信号的,本事是没有任何问题的。在AUTOSAR 4.2引入以太网之后,按照我们前面的分析只需要在应用层具体数据下与信号等价,就可以将以太网完美的嵌入到CP世界。而实际上,AUTOSAR CP就是这么做的,通过SoAd模块,将其信号等价做好转换前提(PDU),然后按照既有框架逐层传递就好了。这也是跟很多人都吐槽过的一点,这让本身极其灵活的基于IP的通信变成了超级静态,是我超级不喜欢的一点,所以在我们公司开发SOA时,我就不是这样做的。
前面提到了信息传递是软件工程中必不可少的,结合前面提到的方法论,那CP中在信息传递的实例化又是怎么样的呢?以一个经典灯控制系统为例:
首先按照系统分析,将具体的功能组件的交互划分出来,定义好输入输出。
将其实例化到具体的ECU中去,确定好输入的数据从哪里来,输出的数据到哪里去。站在应用者的角度来说,所有的数据都是来源system signal,所有数据都是输出到system signal,具体的区别就是system signal是隐射到哪里去了,无非有些就是内部的全局变量,有些是来自通信总线或者某些IO。如下述图所示:
通过S-R接口与内外部通信。
通过C-S接口与IO完成信息交换。
在CP的世界里,自顶向下,就是SWC->PORT->interface->data element->system signal,道理system signal之后就是取决于其mapping到哪里去了,可以mapping到通信-Com(data mapping),也可以mapping另一个组件的接口(service mapping)。如果是到Com的话,就是通过组包最后通过通信层(CAN/LIN/tcpip stack)发送出去;接收时则是反之!
对齐的到方法论层面:对于非ecu嵌入式软件开发者来说,他们会输出通信矩阵、SWC的描述以及对应的mapping关系;这样app开发者可以拿着swc的描述进行模型的开发,而底软开发者则可以拿到上面所有信息之后进行底层软件的开发,而集成方则会将两方代码拿过一起集成编译、生成可执行文件。
在我们看到的各种mapping关系中,在arxml时使用标准A/B配对的方式,对于过程来说,其实就是字符串拼接和匹配,保证在生成源代码时,接口和变量名是一样就mapping上啦~剩下就交给编译器了!Orz!!!
除了信息传递,还有一部分就是调度,在CP中,调度需要基于AUTOSAR OS提供的能力,而调度的最小单元就是runnable,所谓的runnable就是外部能够调用的接口了。
四、软件架构
对于AUTOSAR CP来说,通信是其最核心的功能,而RTE又是其软件架构中最核心的组件,所谓的RTE不能认为就是一个组件,其算做一个为了实现AUTOSAR CP方法论的一个具体实现方案,所以本质上还是一种小方法论。方法论定义了如何描述接口,如何调用接口,如何保证数据的一致性,做到了这些则可以使上层开发者和底层软件开发者是互相不感知的。从这里可以看出来,RTE则一定是全“动态”的,动态的意思是,指的在生成代码层面的,对于应用开发者来说的!在这里是不是又想到了所谓SOA需要达到的目标了:可插、可拔、可拓展!只不过不是运行时而已!
对于软件架构来说,其实并不想说的过多,无非就是软件分层、接口标准化,两个维度来阐述,这对于大部分优秀的软件工程师来说,都是家常便饭了。本文本身就是想跳出软件角度来审视AUTOSAR CP。想要谈的反而是其软件中的配置性!!!
很多人都吐槽过,AUTOSAR过于静态了,但是其真的静态么?如果你要在源代码的角度来去看,的确很静态,几乎没有接口可以让你动态设置,如果要改,不得不手动更改cfg/lcfg/pbcfg相关源代码。我们需要从不同的维度来看这个问题。相信吐槽的人,很大一部分都是有过mpu开发经验的人,所谓的静态,无非就是无法通过运行时来更改东西而已嘛,在linux喜欢通过接口、通过配置文件来完成动态配置。如果我拿出davinci可视化配置,是否可以有一战?因此CP的动态配置,必须要将工具视为其中的一个环,会发现CP容易动态配置。当然本身cp有很多约束,让你无法任意的配置,但本身就是autosar的理解,御错于前,也算是防御式编程了。
五、写在最后
虽然我依然很不喜欢AUTOSAR CP,不喜欢其在以太网中的设计;也不喜欢我明明只需要一把刀,我又不得不从180般武器中挑选的感觉,当然这种不喜欢,可能更多的是不喜欢MCU的开发环境以及动不动大把大把的文档!
质疑AUTOSAR,理解AUTOSAR,从客观角度去思考整个AUTOSAR体系,它将各路形形色色的人能够很好的在一个超大型分布式系统中良好的工作,本身就是必须牺牲灵活性的,所以使用AUTOSAR CP至少能够保证下限。我也曾经思考过,当前OEM自研力度逐渐加大,在AUTOSAR的基础其实能够做很多减法和优化,也在写《“OEM”视角下的AUTOSAR开发设想》。AUTOSAR AP就不提了,门槛降低N多。
作者:jinbao.tang
来源:汽车电子与软件
推荐阅读:
更多汽车电子干货请关注汽车电子与软件专栏。欢迎添加极术小姐姐微信(id:aijishu20)加入技术交流群,请备注研究方向。