今天遇到个问题,解决完之后觉得挺有意思,记录一下。
先聊聊背景
汽车软件开发有个特点:稳。
代码写完了不能随便改,改了要验证,验证完要评审,评审完要发版,发版前要测试,测试完才能上车。
这种节奏下,整个行业都在追求"标准化"。
AUTOSAR就是这么来的——一个汽车软件架构标准,让不同厂家的代码能互相兼容。
最早的时候,车里都是MCU(单片机),算力有限但足够用。AUTOSAR为MCU定了一套标准,叫AUTOSAR Classic Platform(CP)。
后来自动驾驶来了,MCU算不动了,需要SOC(那种手机芯片级别的大算力芯片)。于是域控制器就诞生了——MCU+SOC的组合,MCU负责安全控制,SOC负责感知和决策。
有了SOC,标准也得跟上。AUTOSAR又搞了一套Adaptive Platform(AP),专门给SOC这类非实时系统用。
AP讲究SOA架构,进程和进程之间的通信,都要按配置好的链路来,不能随便自己搞。
听起来很美好对吧?
问题来了。
问题出在哪
SOA架构下,通信链路是提前配置好的。
比如A进程要发数据给B进程,你得先在配置工具里把这个链路定义好,然后代码里拿到这个链路的handle(控制权限),才能发数据。
配置好了,业务也跑起来了。
但测试的时候麻烦了——
有些业务逻辑不是一直触发的,只有在特定场景下才发数据。比如某个功能模块,只有在检测到前方有障碍物的时候才会触发数据发送。
那我怎么测试这个链路本身是不是正常的?
我想测链路,不是测业务逻辑。
理论上,我应该拿到这个链路的handle,手动发一条测试数据,看看对方能不能收到。
但问题是——这个handle在业务代码里,量产软件里没有暴露出来的接口。
你说把handle暴露出来?那正式软件里就多了一堆测试代码。
汽车行业有个铁律:量产软件里不能有测试代码。
因为测试代码可能带来不确定性,不确定性可能带来bug,bug可能带来召回,召回可能带来…
算了,不想了。
我的解法
想了半天,整了个办法——
加一个测试宏。
具体来说:
-
在业务代码里加一个编译开关(宏)
-
宏开启时,把链路的handle拷贝一份到一个公共的地方
-
测试程序从公共地方拿handle,发送测试数据
-
宏关闭时,这段代码直接不编译进去
然后打包的时候:
-
打一套开了测试宏的程序,专门用来做链路测试
-
打一套没开测试宏的程序,这个是正式发版的
测试的时候用测试版,发版的时候用正式版。
两套程序,一个配置开关,问题解决了。
而且这个开关是在编译期决定的,正式软件里完全没有测试代码的痕迹,不影响量产软件的行为。
为什么这么折腾
写到这儿你可能会问:不就是测个链路吗,至于这么折腾?
还真至于。
汽车软件和互联网软件不一样。
互联网软件出bug了,修完立刻上线,用户刷新一下就行。
汽车软件出bug了,轻则OTA升级,重则召回,更严重的可能涉及安全问题。
所以整个开发流程都在强调:测试环境和生产环境要严格隔离。
测试代码不能进入生产环境,这不是洁癖,是底线。
一个小小的测试宏,背后是汽车行业几十年踩出来的工程规范。
后记
这个问题困扰了我一下午,解决完之后觉得还挺有成就感的。
不是什么高深的算法,就是一个工程上的小技巧。
但正是这种小技巧,体现了经验的积累。
我想,这大概就是为什么汽车行业需要"老兵"——
不是老兵更聪明,而是老兵见过更多坑,知道怎么绕过去。
让香蕉画了张图,也是有模有样,供参考。
更多信息,请关注:mp.weixin.qq.com/s/Cw_2LkiNJ…
如果你也在做汽车软件开发,或者在用AUTOSAR AP,欢迎留言聊聊你遇到的坑。