3. ARXML数据类型:基础数据类型、复合数据类型与引用类型
各位同学,今天我们来聊聊ARXML里的数据类型。说实话,我刚接触AUTOSAR那会儿,看到ARXML里密密麻麻的类型定义,头都大了。但后来我发现,搞懂了数据类型,整个AUTOSAR的骨架就清晰了一半。
ARXML的数据类型,说白了就是用来描述ECU之间、以及ECU内部各个模块之间传递的数据长什么样。它分三大类:基础数据类型、复合数据类型,还有引用类型。咱们一个一个来看。
3.1 基础数据类型
基础数据类型,就是那些不能再拆分的原子类型。嗯,就像盖房子的砖头。AUTOSAR里最常用的有这么几种:
| 类型 | ARXML标签 | 说明 |
|---|---|---|
| 布尔型 | Boolean | true/false,常用于开关、标志位 |
| 整型 | Integer | 有符号/无符号,可指定位宽 |
| 浮点型 | Float | 单精度/双精度,用于物理量 |
| 字符串 | String | 文本数据,长度可固定或可变 |
我个人习惯,在定义信号时优先用Integer而不是Float。为什么?因为浮点数在嵌入式系统里处理起来开销大,而且不同芯片的浮点运算结果可能有微小差异。我在项目中遇到过两次,因为浮点数精度问题导致两个ECU对同一个车速值的判断不一致,最后排查了两天才找到原因。
来看一个ARXML里定义Integer的例子:
<INTEGER-TYPE>
<SHORT-NAME>VehicleSpeed_T</SHORT-NAME>
<CATEGORY>TYPE_REF</CATEGORY>
<LOWER-MULTIPLICITY>0</LOWER-MULTIPLICITY>
<UPPER-MULTIPLICITY>1</UPPER-MULTIPLICITY>
<SW-DATA-DEF-PROPS>
<SW-DATA-DEF-PROPS-VARIANTS>
<SW-DATA-DEF-PROPS-CONDITIONAL>
<PHYS-CONSTRS>
<LOWER-LIMIT>0</LOWER-LIMIT>
<UPPER-LIMIT>300</UPPER-LIMIT>
<UNIT>km/h</UNIT>
</PHYS-CONSTRS>
<COMPU-METHOD>Linear_CompuMethod</COMPU-METHOD>
</SW-DATA-DEF-PROPS-CONDITIONAL>
</SW-DATA-DEF-PROPS-VARIANTS>
</SW-DATA-DEF-PROPS>
</INTEGER-TYPE>
这里要注意,LOWER-LIMIT和UPPER-LIMIT定义的是物理值的范围,不是内部存储的位宽。位宽是在SW-BIT-REPRESENTATION里定义的,很多新手容易搞混。
3.2 复合数据类型
复合数据类型,就是把多个基础类型组合在一起。你想想看,一个GPS位置信息,包含经度、纬度、海拔、时间戳,总不能定义四个独立的信号吧?这时候就需要复合类型了。
AUTOSAR里主要有两种复合类型:
- Array(数组):相同类型元素的集合,比如一组温度传感器的读数
- Record(记录):不同类型元素的集合,比如上面说的GPS位置信息
来看一个Record的例子,定义一个诊断故障码(DTC)的数据结构:
<RECORD-TYPE>
<SHORT-NAME>DTC_Info</SHORT-NAME>
<ELEMENTS>
<RECORD-ELEMENT>
<SHORT-NAME>DTC_Code</SHORT-NAME>
<TYPE-TREF>/DataTypes/Integer_16bit</TYPE-TREF>
</RECORD-ELEMENT>
<RECORD-ELEMENT>
<SHORT-NAME>DTC_Status</SHORT-NAME>
<TYPE-TREF>/DataTypes/DTC_Status_Type</TYPE-TREF>
</RECORD-ELEMENT>
<RECORD-ELEMENT>
<SHORT-NAME>Timestamp</SHORT-NAME>
<TYPE-TREF>/DataTypes/UnixTimestamp</TYPE-TREF>
</RECORD-ELEMENT>
</ELEMENTS>
</RECORD-TYPE>
Array的定义也很直观,比如定义一个5元素的数组:
<ARRAY-TYPE>
<SHORT-NAME>Temperature_Sensor_Array</SHORT-NAME>
<ELEMENT>
<SHORT-NAME>Sensor_Value</SHORT-NAME>
<TYPE-TREF>/DataTypes/Temperature_Type</TYPE-TREF>
<ARRAY-SIZE>
<NUM-ELEMENTS>5</NUM-ELEMENTS>
</ARRAY-SIZE>
</ELEMENT>
</ARRAY-TYPE>
3.3 引用类型与ID引用
引用类型,说白了就是「指向另一个数据类型的指针」。在ARXML里,我们不直接复制数据定义,而是通过引用来复用。这样做的好处是:改一处,处处生效。
引用类型有两种形式:
- 类型引用(Type Reference):用
TYPE-TREF标签,指向另一个已定义的数据类型 - ID引用(ID Reference):用
REF标签,指向具体的实例或对象
举个例子,假设多个信号都使用同一个「车速」数据类型:
<SIGNAL>
<SHORT-NAME>FrontLeftWheelSpeed</SHORT-NAME>
<DATA-TYPE>
<TYPE-TREF>/DataTypes/VehicleSpeed_T</TYPE-TREF>
</DATA-TYPE>
</SIGNAL>
<SIGNAL>
<SHORT-NAME>FrontRightWheelSpeed</SHORT-NAME>
<DATA-TYPE>
<TYPE-TREF>/DataTypes/VehicleSpeed_T</TYPE-TREF>
</DATA-TYPE>
</SIGNAL>
这里两个信号都引用了同一个VehicleSpeed_T类型。如果以后需要修改车速的范围或单位,只需要改一处定义,所有引用它的信号自动生效。这就是引用的威力。
3.4 知识体系总览
为了让大家更直观地理解这三类数据类型的关系,我画了一张图:
从这张图可以看出来,基础类型是最底层的构建单元,复合类型把它们组合成更复杂的数据结构,而引用类型则让整个模型具备了灵活性和可维护性。三者缺一不可。
3.5 实际项目中的选择建议
说了这么多理论,到底什么时候用哪种类型?我根据自己的项目经验,总结了几条原则:
- 能用基础类型就别用复合类型——简单就是美,调试也方便
- 多个信号共享同一物理含义时,一定要用引用——比如车速、转速、温度这些基础物理量
- Record里的元素不要超过10个——超过10个,建议拆分成多个子Record,否则维护起来很痛苦
- Array的长度尽量用常量定义——不要写死数字,用
NUM-ELEMENTS引用一个常量,方便后期调整
好了,关于ARXML的数据类型,今天就聊到这里。记住:基础类型是砖,复合类型是墙,引用类型是图纸。把这三样搞明白了,AUTOSAR的数据建模你就掌握了八成。
公众号:蓝海资料掘金营,微信deep3321