SOME/IP--协议英文原文讲解4

news/2025/1/31 0:21:18 标签: tcp/ip, 网络协议, 网络

前言
SOME/IP协议越来越多的用于汽车电子行业中,关于协议详细完全的中文资料却没有,所以我将结合工作经验并对照英文原版协议做一系列的文章。基本分三大块:

1. SOME/IP协议讲解

2. SOME/IP-SD协议讲解

3. python/C++举例调试讲解


4.1.3 Endianess -- 字节序
[PRS_SOMEIP_00368]
Upstream requirements: RS_SOMEIP_00026
All SOME/IP Header Fields shall be encoded in network byte order (big endian). -- Header 由于是基于网络传输 跟随为 网络字节序--大端存贮

[PRS_SOMEIP_00759]
Upstream requirements: RS_SOMEIP_00026
The following fields in the payload of SOME/IP messages shall be encoded in network
byte order (big endian): payload和Header一样的字节序
• the optional length field of extensible structs ([PRS_SOMEIP_00079]),
• the TLV tag ([PRS_SOMEIP_00203]) and the length field ([PRS_SOMEIP_00221]) of 
  structured datatypes and arguments with identifier and optional members,
• the optional length field for fixed length strings ([PRS_SOMEIP_00760]),
• the length field for dynamic length strings ([PRS_SOMEIP_00089]),
• the optional length field for extensible fixed length arrays ([PRS_SOMEIP_00944]),
• the length field of dynamic length arrays ([PRS_SOMEIP_00376]),
• the length field of unions ([PRS_SOMEIP_00126]),
• and the type field of unions ([PRS_SOMEIP_00129]).

以上说明的是payload哪些变长类型时需要添加length字段,后面会有详细介绍。

[PRS_SOMEIP_00369]
Upstream requirements: RS_SOMEIP_00026
The byte order of the parameters inside the payload shall be defined by configuration. 
An exception is the tag for TLV (as defined by [PRS_SOMEIP_00202]
and [PRS_SOMEIP_00203]) which shall have byte order according to
[PRS_SOMEIP_00204] and [PRS_SOMEIP_00759].
payload的数据参数类型和排列顺序应该被定义在配置文件中,这样双方对着配置文件就可以序列化和反序列化了。不过TLV除外--后面讲解

4.1.4 Serialization of Data Structures
The serialization is based on the parameter list defined by the interface specification.
The interface specification defines the exact position of all data structures in the PDU
and has to consider the memory alignment.
Alignment is used to align the beginning of data by inserting padding elements after
the data in order to ensure that the aligned data starts at certain memory addresses.
There are processor architectures which can access data more efficiently (i.e. master)
when they start at addresses which are multiples of a certain number (e.g multiples of
32 Bit).
[PRS_SOMEIP_00611]
Upstream requirements: RS_SOMEIP_00028, RS_SOMEIP_00029
Alignment of data shall be realized by inserting padding elements after the variable
size data if the variable size data is not the last element in the serialized data stream.--强调了变长元素如果不是最后一个元素 必须填充。

这段话主要解释了 SOME/IP 进行数据结构序列化时的对齐规则,其中涉及 数据对齐 (Alignment)填充 (Padding) 机制,重点如下:

1. 序列化 (Serialization) 基于接口定义

"The serialization is based on the parameter list defined by the interface specification."

  • 序列化 指的是将内存中的数据转换成一个标准格式的数据流,以便传输或存储。
  • 接口规范 (interface specification) 决定了 每个数据结构在 PDU (Protocol Data Unit) 中的具体位置,因此数据的存放方式是 提前规定好的,不能随意调整。

2. 需要考虑数据对齐

"The interface specification defines the exact position of all data structures in the PDU and has to consider the memory alignment."

  • PDU (协议数据单元) 是 SOME/IP 传输数据的基本单位。
  • 数据对齐 是指 确保数据在特定的内存地址上对齐存放,以优化 CPU 访问效率
  • 这意味着:SOME/IP 不能简单地按顺序存放数据,而是要保证合适的对齐规则,如果不满足对齐要求,就需要填充 (Padding)

3. 为什么要对齐?

"Alignment is used to align the beginning of data by inserting padding elements after the data in order to ensure that the aligned data starts at certain memory addresses."

  • 某些处理器架构 (CPU) 访问特定地址的数据时更高效,比如:
    • 32 位数据 (4 字节) 最好存放在 4 的倍数的地址上
    • 64 位数据 (8 字节) 最好存放在 8 的倍数的地址上
  • 如果数据 不对齐,有些 CPU 可能需要 额外的指令 才能正确读取,导致性能下降

4. 一些架构依赖对齐来提高访问效率

"There are processor architectures which can access data more efficiently (i.e. master) when they start at addresses which are multiples of a certain number (e.g. multiples of 32 Bit)."

  • CPU 访问内存时,往往有最佳对齐要求
    • 32 位 (4 字节) 访问时,最优地址是 4 的倍数
    • 64 位 (8 字节) 访问时,最优地址是 8 的倍数
  • 如果数据 没有正确对齐,可能会:
    1. 触发 CPU 额外的访问操作(如 x86 可能执行 2 次读取)。
    2. 导致某些 RISC 架构直接崩溃(如某些 ARM 处理器不允许非对齐访问)。

5. SOME/IP 通过插入 Padding 确保对齐

[PRS_SOMEIP_00611] Alignment of data shall be realized by inserting padding elements after the variable size data if the variable size data is not the last element in the serialized data stream.

  • 如果一个变量大小的数据 (variable size data) 不是最后一个元素,就需要在后面填充 (Padding) 来确保对齐。
  • 这是为了让后续的定长数据 (如 UINT32, UINT64) 能够正确对齐

💡 关键点:

  • 固定大小的数据 (如 UINT32, UINT64) 一般直接对齐存放
  • 变长数组 (variable size array) 后面需要填充 (Padding),以保证下一个数据项正确对齐
  • 如果变长数据是最后一个元素,则可以不填充 Padding(因为没有后续数据需要对齐)。

总结

  1. SOME/IP 在序列化数据时,会严格按照接口规范定义的顺序存放数据。
  2. CPU 访问某些特定地址上的数据更高效,因此数据对齐很重要。
  3. 如果某个变长数组不是最后一个数据,就要在它后面插入 Padding,以保证后续数据的对齐。
  4. 填充 (Padding) 只是为了对齐,不会影响数据本身的意义。

Note: Please note that the padding value is not defined. -- 填充的值不做定义 随意设置

这个例子中为啥变长数组结束的地址已经是4字节对齐了为啥还要再填充?

关键点:变长数组的长度是不确定的

协议规范规定,变长数组后必须填充 (Padding),除非它是最后一个成员
这个规则并不依赖于当前变长数组是否对齐,而是为了保证序列化数据的一致性和解析的通用性。

📌 主要原因有两个:

  1. 协议层面的通用性

    • SOME/IP 设计时,要求 所有变长数据 (Variable-size Data) 不是最后一个字段时,必须填充 Padding
    • 这样可以保证 所有固定大小的数据 (如 UINT32, UINT64) 都是按照它们的对齐要求放置的,避免不同情况下处理逻辑的复杂性。
  2. 防止解析时出现不确定行为

    • 变长数组的大小可能会发生变化,比如:
      • 如果当前变长数组的长度为 4 字节,你会觉得可以不填充。
      • 但如果 数组长度变成 3 字节,那 UINT32 就会变成非对齐存储,需要额外的填充。
    • 为了解决这种情况,协议强制规定变长数据后必须填充 Padding,以确保固定大小的数据始终是对齐的。

[PRS_SOMEIP_00569]
Upstream requirements: RS_SOMEIP_00028, RS_SOMEIP_00029
Alignment shall always be calculated from start of SOME/IP message.字段对齐内存计算时必须从整个SOMEIP消息的开始位置计算 包括SOME/IP的header
[PRS_SOMEIP_00612]
Upstream requirements: RS_SOMEIP_00028, RS_SOMEIP_00029
There shall be no padding behind fixed length data elements to ensure alignment of
the following data. 定长字段后面不用添加对齐填充。
Note:
If data behind fixed length data elements shall be padded, this has to be explicitly
considered in the data type definition. 如果定长后有填充 必须单独说明
[PRS_SOMEIP_00613]
Upstream requirements: RS_SOMEIP_00028, RS_SOMEIP_00029
The alignment of data behind variable length data elements shall be 8, 16, 32, 64,
128 or 256. Bits. 填充的长度必须是1、2、4、8、16、32、64字节。

基本类型

The Byte Order is specified for each parameter by configuration.字节序 按照 参数规范定义的排列(上面有讲)

[PRS_SOMEIP_00615]
Upstream requirements: RS_SOMEIP_00030, RS_SOMEIP_00031, RS_SOMEIP_00032
For the evaluation of a Boolean value only the lowest bit of the uint8 is interpreted and
the rest is ignored.
对于布尔数据的类型 仅使用最低为 其它位不考虑 

[PRS_SOMEIP_00077]
Upstream requirements: RS_SOMEIP_00033
The SOME/IP implementation shall not automatically insert dummy/padding data.

不能像C语言那样 随便插入 填充字节来内存对齐(网络序列不需要 因为反序列化就是按照字节来解析的 没有内存对齐的烦恼) 结构体中每个成员的的序列化要按照规范要求来(下面有介绍各种情况) 

[PRS_SOMEIP_00079]

Upstream requirements: RS_SOMEIP_00033, RS_SOMEIP_00040

An optional length field of 8, 16 or 32 Bit may be inserted in front of the Struct depending on the configuration.

[PRS_SOMEIP_00370]

Upstream requirements: RS_SOMEIP_00033, RS_SOMEIP_00040

The length field of the struct shall describe the number of bytes this struct occupies for SOME/IP transport.

可以在结构体前加上描述结构体长度的字段,这个字段可以是1、2、4字节。---需要客户指定

[PRS_SOMEIP_00712]

Upstream requirements: RS_SOMEIP_00028, RS_SOMEIP_00033

The serialization of structs shall follow the depth-first-traversal of the structured data type.

序列化嵌套结构体 应采用深度优先遍历--按照嵌套的顺序依此序列化。


https://github.com/0voice


http://www.niftyadmin.cn/n/5838179.html

相关文章

冯诺依曼系统及操作系统

目录 一.冯诺依曼体系结构 二.操作系统 三.系统调用和库函数概念 一.冯诺依曼体系结构 我们常见的计算机,如笔记本。我们不常见的计算机,如服务器,大部分都遵守冯诺依曼体系 截至目前,我们所认识的计算机,都是由一…

clean code阅读笔记——如何命名?

命名的原则 1. “小处诚实非小事“ 有个词叫做”以小见大“。以建筑作喻,宏大建筑中最细小的部分,比如关不紧的门、未铺平的地板,甚至时凌乱的桌面,都会将整个大局的魅力毁灭殆尽,这就是整洁代码之所系。 2. 有意义…

OpenCV图像显示imshow()函数——详解

OpenCV图像显示imshow()函数——详解 本文目录: 零、时光宝盒 一、OpenCV 图像显示使用imshow()函数语法 二、imshow()显示图片时发生图片显示不全的解决方法 解决办法(1) 解决办法(2) 总结 三、imshow()图像显…

【算法设计与分析】实验1:字符串匹配问题的算法设计与求解

目录 一、实验目的 二、实验环境 三、实验内容 四、核心代码 五、记录与处理 六、思考与总结 七、完整报告和成果文件提取链接 一、实验目的 给定一个文本,在该文本中查找并定位任意给定字符串。 1、深刻理解并掌握蛮力法的设计思想; 2、提高应用…

2024年除夕

多少年前的除夕,一如今天这样的除夕;多少年后的除夕,也一如多少年前的除夕。 无数个这样的除夕下午,我打开电脑,望着窗外安静的小区,车声渐渐稀疏的马路,想写下一些新的感受时,多少…

IPhone13 Pro Max设备详情

目录 产品宣传图内部图——后设备详细信息 产品宣传图 内部图——后 设备详细信息 信息收集于HubWeb.cn

ThinkPad E480安装Ubuntu 18.04无线网卡驱动

个人博客地址:ThinkPad E480安装Ubuntu 18.04无线网卡驱动 | 一张假钞的真实世界 遗憾的是虽然下面的方法可以解决,但是内核升级后需要重新安装。 基本信息 Ubuntu 18.04ThinkPad E480使用下面的命令查看 Linux 内核: $ uname -r 5.0.0-3…

Node.js 中文编码问题全解析

Node.js 中文编码问题全解析 问题背景 在 Node.js 中执行 Gradle 命令时遇到中文输出乱码问题。这个问题涉及 Windows 系统、Java 进程和 Node.js 三个层面的编码处理。 问题分析 最初的错误代码 gradleProcess.stdout.setEncoding(utf-8); // 错误:假设输出是…