SOME/IP 协议介绍(三)参数和数据结构的序列化

参数和数据结构的序列化

序列化是基于接口规范定义的参数列表。为了允许服务接口的**迁移,反序列化,**代码应忽略附加在先前已知的参数列表末尾的参数;也就是说,忽略在用于生成或参数化反序列化代码的接口规范中未定义的参数。

接口规范定义了PDU中所有参数的确切位置,并考虑了内存对齐。序列化过程不应尝试自动对齐参数,而应按照接口规范中指定的对齐方式进行对齐。 SOME/IP负载应该在内存中放置,以使SOME/IP负载能够适当地对齐。对于车载娱乐设备的ECU,应该实现8字节(即64位)的对齐,对于所有ECU,至少应实现4字节的对齐。

接下来将指定不同参数的反序列化过程。

基本数据类型

应支持以下基本数据类型:

|---------|-----------------------|--------------|--------------------------------------|
| Type | Description | Size [bit] | Remark |
| boolean | TRUE/FALSE value | 8 | FALSE (0), TRUE (1) |
| uint8 | unsigned Integer | 8 | |
| uint16 | unsigned Integer | 16 | |
| uint32 | unsigned Integer | 32 | |
| sint8 | signed Integer | 8 | |
| sint16 | signed Integer | 16 | |
| sint32 | signed Integer | 32 | |
| float32 | floating point number | 32 | IEEE 754 binary32 (Single Precision) |
| float64 | floating point number | 64 | IEEE 754 binary64 (Double Precision) |

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

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

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

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

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

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

接口规范可以在结构体前面添加一个8位、16位或32位的长度字段。如果未指定长度字段的长度,则必须假定长度为0,并且消息中没有长度字段。

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

字符串(定长)

字符串使用Unicode进行编码,并以"\0"字符结尾。在接口定义中必须指定字符串的字节长度(包括"\0")。使用"\0"填充未使用的空间。

应支持不同的Unicode编码,包括UTF-8、UTF-16BE和UTF-16LE。由于这些编码每个字符的字节长度是动态的,字节的最大长度是UTF-8中字符长度的三倍加上1个字节的"\0"终止符,或者UTF-16中字符长度的两倍加上2个字节的"\0"终止符。

字符串的编码方式应在接口定义中指定。

字符串(动态长度)

动态长度的字符串以长度字段开头。长度以字节为单位,并跟随以"\0"结尾的字符串数据。接口定义还应定义字符串(包括以"\0"结尾)可以占用的最大字节数。

长度字段的长度可以是8位、16位或32位。固定长度的字符串可以视为长度字段为0位。

如果接口规范没有另外指定,长度字段的长度为32位(长度字段的默认长度)。

字符串长度字段的值不考虑在长度字段本身的值中;也就是说,长度字段不计入自身的长度。

支持的编码方式如[SIP_RPC_232第19页]中所定义。

如果接口定义提示下一个数据元素的对齐方式,字符串应通过添加"\0"字符来扩展以满足对齐要求。

数组(固定长度)

固定长度数组的长度由接口定义确定。它们可以被视为重复的元素。在[SIP_RPC_253 页错误!未定义书签。]中展示了动态长度数组,也可以使用。然而,固定长度数组可以更容易地集成到早期版本的AUTOSAR和非常小的设备中;因此,两种选项都得到支持。

一维数组

固定长度为n的一维数组包含恰好n个相同类型的元素。布局如图2所示。

多维数组

多维数组的序列化遵循C++编程语言中多维数组的内存布局(按行主序),如图3所示

可选字段

可选字段应被编码为包含0到1个元素的数组。对于具有动态长度的数组的序列化,请参阅[SIP_RPC_253]。

动态长度数组

具有动态长度的数组的布局基本上基于固定长度数组的布局。为了确定数组的大小,序列化在数据前面添加一个长度字段(默认长度为32位),该字段计算数组的字节数。长度不包括长度字段的大小。因此,在传输零元素的数组时,长度设置为零。

接口定义可以定义长度字段的长度。允许长度为0、8、16和32位。如果将长度设置为0位,则数组中的元素数量必须是固定的;因此,它是具有固定长度的数组。

动态数组的布局如图4和图5所示。

在一维数组中,使用一个长度字段,该字段表示数组使用的字节数。可以通过将字节数除以元素的大小来轻松计算元素的数量。

在多维数组中,需要多个长度字段。接口定义应定义每个维度的最大长度,以便允许进行静态缓冲区大小的分配。在以字节为单位测量长度时,可以在反序列化过程中跳过复杂的多维数组。

枚举

接口定义可以基于无符号整数数据类型(uint8、uint16、uint32、uint64)指定枚举类型。

位域

位域应作为基本数据类型uint8/uint16/uint32进行传输。接口定义应能够定义每个位的名称。接口定义应能够定义位可以设置为的值的名称。

每个SOME/IP实现可以选择对位域进行解/序列化,或者将uint8/uint16/uint32传递给应用程序。SOME/IP实现可以允许开启或关闭位域的解/序列化。

联合(变体)

联合(也称为变体)是一种可以包含不同类型元素的参数。例如,如果定义了一个uint8类型和uint16类型的联合,该联合将携带一个uint8或uint16类型的元素。显然,当使用不同类型的元素时,后续参数的对齐可能会被扭曲。为了解决这个问题,可能需要填充。

默认情况下,SOME/IP中联合的序列化布局如下:

长度字段和类型字段的顺序可以通过接口规范进行调整。如果未指定,则使用[TR_SOMEIP_00119]中的默认布局。

长度字段的长度应由接口规范定义,并且可以是32位、16位、8位或0位。长度字段为0位表示不会将长度字段写入PDU。如果长度字段为0位,则联合中的所有类型的长度必须相同。

如果接口规范定义了一个长度字段为0位的联合,并且具有不同长度的类型,则SOME/IP实现应该发出警告,并使用最长元素的长度,并用零(0x00)填充其他元素。

如果接口规范未指定联合的长度字段的长度,则应使用32位长度的长度字段。

长度字段以字节为单位定义元素和填充的大小,不包括长度字段和类型字段的大小。

类型字段的长度应由接口规范定义,并且可以是32位、16位或8位。

如果接口规范未指定联合的类型字段的长度,则应使用32位长度的类型字段。

类型字段描述元素的类型。类型字段的可能值由接口规范为每个联合单独定义。类型按照接口规范中的编码以升序排列,从1开始。0保留为NULL类型,即空联合。接口定义应允许使用NULL。

根据类型字段中的类型,元素将进行序列化。结合长度字段,可以在元素后面添加填充。反序列化器应根据长度字段跳过字节。每种类型的长度字段的值应由接口规范定义。通过使用结构体,可以实现不同的填充布局。

示例:uint8/uint16联合,均填充为32位

在此示例中,长度字段的长度指定为32位。该联合应支持uint8和uint16作为元素。两者都填充到32位边界(长度为4)。uint8的序列化如下所示:

uint16的序列化如下所示:

将映射或字典描述为键值对数组是最基本的方式。实现映射或字典的最基本方法是使用一个具有两个字段(键和值)的结构体数组。由于结构体没有长度字段,这种方式与特殊的映射或字典类型一样高效。如果选择uint16作为键和值,一个包含3个条目的序列化映射如下所示:

相关推荐
_oP_i1 小时前
HTTP 请求Media typetext/plain application/json text/json区别
网络协议·http·json
OkeyProxy2 小时前
HTTP、HTTPS和SOCKS5代理協議
网络协议·https·云计算·代理服务器·海外ip代理
zquwei3 小时前
SpringCloudGateway+Nacos注册与转发Netty+WebSocket
java·网络·分布式·后端·websocket·网络协议·spring
别NULL3 小时前
机试题——疯长的草
数据结构·c++·算法
群联云防护小杜4 小时前
如何给负载均衡平台做好安全防御
运维·服务器·网络·网络协议·安全·负载均衡
ihengshuai4 小时前
HTTP协议及安全防范
网络协议·安全·http
ZSYP-S4 小时前
Day 15:Spring 框架基础
java·开发语言·数据结构·后端·spring
唐叔在学习5 小时前
【唐叔学算法】第21天:超越比较-计数排序、桶排序与基数排序的Java实践及性能剖析
数据结构·算法·排序算法
ALISHENGYA5 小时前
全国青少年信息学奥林匹克竞赛(信奥赛)备考实战之分支结构(switch语句)
数据结构·算法
MuLogin_Browser5 小时前
如何保障多个Facebook账号稳定运行:一账号一稳定IP?
服务器·tcp/ip·facebook