目录

  • 本篇系对以太网SOME/IP协议的参数数据结构的序列化/反序列化的解读。

概述:SOME/IP 参数和数据结构的序列化

大小端/字节序

  • 每个参数(parameter)的字节顺序由接口定义进行规定。

  • 所有的 SOME/IP Header 字段,应该以网络字节序(大端)编码。

PRS_SOME/IP_00368

  • Payload中参数的字节顺序由配置决定。

PRS_SPME/IP_00026

参数和数据结构的序列化

  • 序列化Serialization)是指将数据结构对象状态转换为二进制串(字节数组)的过程。

SOME/IP协议在传输过程中也自然需要进行序列化反序列化

  • SOME/IP需要基于通信接口规范定义的参数列表进行序列化。

接口规范明确了PDU协议数据单元)中所有数据结构的精确位置,并且在设计时必须考虑存储器对齐的问题。

  • 对齐操作通过在数据项之后添加填充元素来【调整数据的起始位置】,以确保数据从特定的、对齐的内存地址开始。

这是因为在某些处理器架构中,当数据从某个数的倍数(例如32位的倍数)地址开始时,数据访问会更加高效。

  • 如果可变大小数据不是序列化数据流中的最后一个元素,则:应该通过在可变大小数据后面插入填充元素来实现数据的对齐。

PRS_SOMEIP_00611 / RS_SOMEIP_00028 , RS_SOMEIP_00029

  • 请注意,Padding 值未被定义。

Member2: 以 UInt8 元素组成的一维可变长数组 / Member5: 以 UInt8 元素组成的一维可变长数组

Member2: 以 UInt8 元素组成的一维可变长数组 / Member5: 以 UInt8 元素组成的一维可变长数组

  • 对齐应该能总是被计算出,从 SOME/IP 报文的起始处。

  • 固定长度数据元素后面不得有填充元素,以确保后面数据的对齐。

如果定长数据元素后面的数据被填充,则这必须被显式地考虑进数据类型定义中。

  • 可变长度数据元素后面的数据对齐应为8、16、32、64、128或256位。

RS_SOMEIP_000028 / RS_SOMEIP_000029

基本数据类型

  • 应支持以下基本数据类型:
TypeDescriptionSize [bit]Remark
booleanTRUE/FALSE value8FALSE (0), TRUE (1)
uint8unsigned Integer8
uint16unsigned Integer16
uint32unsigned Integer32
sint8signed Integer8
sint16signed Integer16
sint32signed Integer32
float32floating point number32IEEE 754 binary32 (Single Precision)
float64floating point number64IEEE 754 binary64 (Double Precision)
  • 每个参数的字节顺序由接口定义进行规定。

结构化数据类型 (结构体)

  • 结构体的序列化应尽可能接近内存布局

这意味着参数应按顺序序列化缓冲区中。
对于结构体来说,特别要考虑正确的内存对齐
如果需要对齐,请在接口定义中插入保留/填充元素,因为SOME/IP实现不会自动添加此类填充。

  • SOME/IP实现不应自动插入虚拟/填充元素。

  • 如果SOME/IP实现遇到导致PDU未正确对齐的接口规范(例如,由于未对齐的结构体),SOME/IP实现应在发现不对齐的结构体时发出警告,但不应在生成代码时失败

  • 结构体的序列化应按照规范精确地进行。

  • 可以在结构体前面添加一个8位、16位或32位的【可选】的【长度字段】,其取决于接口规范的配置。

如果未指定长度字段的长度,则必须假定长度为0,并且消息中没有长度字段。

  • 结构体的长度字段描述了结构体的字节数

如果长度大于接口定义中指定的结构体长度,则只有接口规范中指定的字节将被解释,其他字节将根据长度字段被跳过。
这样可以实现可扩展的结构体,从而更好地实现接口的迁移。

  • 如果长度效于所有结构体成员的长度之和,且接收者无法在本地提供缺失数据的替换时,则 反序列化应被中止,且该报文应被视为是畸形的。

  • 结构体的序列化应遵循结构化的数据类型的【深度优先遍历】。

字符串

如下需求是定长字符串和动态长度字符串的共同点

  • [PRS_SOMEIP_00372] 不同的Unicode字符集编码应被支持,包括: UTF-8 / UTF-16BE / UTF-16LE

PRS_SOMEIP_00372 / RS_SOMEIP_00038

  • [PRS_SOMEIP_00948] UTF-8 字符串应以 \0 字符 结束。

这意味着字符串应以 1 个 0x00 字节结束。
RS_SOMEIP_00038

  • [PRS_SOMEIP_00084] UTF-16LE 和 UTF-16BE 字符串应以“\0”字符结尾。这意味着它们应以(至少)两个0x00字节结束

  • [PRS_SOMEIP_00085] UTF-16LE和UTF-16BE字符串的应是偶数的长度(even length)。

  • [PRS_SOMEIP_00086] 应忽略UTF-16LE和UTF-16BE有一个奇数长度的最后一个字节将被忽略。

  • [PRS_SOMEIP_00087] 所有字符串应始终以包含字符串的待序列化数组的前三个(UTF-8)或两个(UTF-16)字节中的字节顺序标记BOM)开头。

BOM应包含在固定长度字符串和动态长度字符串中。
BOM允许检测所使用的编码。

固定长度的字符串

  • [PRS_SOMEIP_00760] 固定长度的字符串可以以可选的【长度字段】开头。 PRS_SOMEIP_00760

Upstream requirements: RS_SOMEIP_00038

  • [PRS_SOMEIP_00373] 尽管字符串长度固定,但应以“\0”字符结尾

  • [PRS_SOMEIP_00374] 必须在数据类型定义中指定字符串(包括“\0”)的长度(以字节为单位)

动态长度的字符串

  • [PRS_SOMEIP_00089] 动态长度的字符串应以长度字段开头。(强制要求)

长度以字节为单位

  • [PRS_SOMEIP_00090] 长度字段放置在BOM之前,BOM包含在长度中

  • [PRS_SOMEIP_00091] 字符串以“\0”结尾。 PRS_SOMEIP_00091

  • 注意,字符串的最大字节数(包括以“\0”结尾)也应从数据类型定义中得出。
  • [PRS_SOMEIP_00092] : 对于 [PRS_SOMEIP_00084], [PRS_SOMEIP_00085] 和 [PRS_SOMEIP_00086] 条款,也适用于具有动态长度的字符串

  • [PRS_SOMEIP_00093] 动态长度字符串的长度字段应为8、16或32位。这应由配置决定。

  • [PRS_SOMEIP_00094] 如果未配置该字段,则添加在字符串前面的长度字段的长度为32位(长度字段的默认长度)。

  • [PRS_SOMEIP_00095] 长度字段的值中不考虑字符串长度字段的长度;即 长度字段本身不计数。

数组

固定长度的数组

  • 固定长度数组更容易在非常小的设备中使用。使用动态长度数组的ECU可能需要更多资源。

  • [PRS_SOMEIP_00944] 固定长度的数组可以以可选的长度字段开头

注意,固定大小数组的溢出只能通过长度字段检测。

一维数组
  • [PRS_SOMEIP_00099] 具有固定长度“n”的一维数组应恰好包含相同类型的“n”个元素。可选的长度字段可以位于第1个元素之前

注意,如果为特定的固定长度数组定义了【长度字段】,则该数组在总线上表示为长度字段和相同数据类型的n个元素的集合的组合
[PRS_SOMEIP_00099]的布局如图4.7所示。

多维数组
  • [PRS_SOMEIP_00101] 多维数组的序列化遵循C/C++编程语言中多维数组的内存布局(以行为主的顺序 / row-major order)

注意,如果为特定的多维固定长度数组定义了【长度字段】,则该数组在总线上表示为长度字段和n个集合的组合,每个集合由一个长度字段和相同数据类型的m个元素组成。

动态长度的数组

  • [PRS_SOMEIP_00375] 具有动态长度的数组布局应基于固定长度数组的布局

  • [PRS_SOMEIP_00376] 动态长度数组开头的长度字段应该用于指定数组的长度(以字节为单位)

  • [PRS_SOMEIP_00107] 动态长度数组应具有长度为8、16或32位的长度字段。这应由配置决定

  • [PRS_SOMEIP_00377] 长度不包括长度字段的大小。

如果长度字段的长度设置为0位,则数组中的元素数量必须固定;因此,此时是固定长度的数组。 (参考图 4.9 / 4.10)

  • 在一维数组中,使用一个长度字段,该字段携带用于数组的字节数。
  • 静态长度元素的数量,可以很容易地通过除以元素的大小来计算。
  • 在动态长度元素的情况下,无法直接计算元素的数量,必须按顺序解析元素。

图4.10显示了动态长度多维数组的结构。

  • [PRS_SOMEIP_00114]
  • 在多维数组中,每个不同维度的子数组都应有自己的长度字段。
  • 如果需要静态缓冲区大小分配,数据类型定义应定义每个维度的最大长度。
  • 理由:在以字节为单位测量长度时,可以在反序列化中跳过复杂的多维数组。
  • SOME/IP还支持同一维度中列的不同长度和行的不同长度。见图4.10中的k_1和k_2。每个动态长度数组前面都需要有一个长度指示器。这适用于外部和所有内部/嵌套数组。
  • [PRS_SOMEIP_00945] 如果未配置,则添加在动态长度数组前面的长度字段的长度为32位(长度字段的默认长度)。

枚举类型(Enumeration)

  • [PRS_SOMEIP_00705] 在SOME/IP中不考虑枚举。枚举应作为无符号整数数据类型传输

位域(Bit Field)

  • [PRS_SOMEIP_00300] 位字段应作为无符号数据类型uint8/uint16/uint32/uint64传输。
  • 数据类型定义将能够定义每个位的名称和值

Union / Variant

Y 推荐文献

https://www.autosar.org/fileadmin/standards/R24-11/FO/AUTOSAR_FO_PRS_SOMEIPProtocol.pdf

https://www.autosar.org/fileadmin/standards/R19-11/FO/AUTOSAR_RS_SOMEIPProtocol.pdf

X 参考文献

原创作者: johnnyzen 转载于: https://www.cnblogs.com/johnnyzen/p/18934606
Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐