SOME/IP 协议详解——远程过程调用(RPC)
文章目录
- 1. 传输协议绑定
- 1.1 UDP 绑定
- 1.2 TCP 绑定
- 1.3 多服务实例(重要)
- 1.4 通过 UDP 传输大型 SOME/IP 消息(SOME/IP - TP)
- 2. 请求 / 响应通信
- 3. Fire&Forget 通信
- 4. 通知事件
- 5. 字段
- 6. 错误处理
- 6.1 返回码
- 6.2 错误消息
- 6.3 错误处理概述
- 6.4 通讯错误及通讯错误处理
- 7. SOME/IP 协议的使用和指导原则
- 7.1 选择传输协议
- 7.2 传输 CAN 和 FlexRay 帧
1. 传输协议绑定
- 协议支持: SOME/IP 目前支持 UDP(用户数据报协议)和 TCP(传输控制协议)。
- 具体规则
- 如果一个服务器运行同一服务的多个实例,属于不同服务实例的消息应通过服务器端的传输协议端口映射到服务实例。
- 示例:一辆车有四个轮胎压力传感器,每个传感器作为一个服务实例。当这些传感器发送轮胎压力数据(即消息)时,服务器(如车辆的中央控制单元)需要根据传输协议端口准确地知道每个消息来自哪个轮胎的传感器。
- 所有传输协议绑定应支持在一个传输层协议数据单元(PDU,即 UDP 数据包或 TCP 段)中传输多个 SOME/IP 消息。
- 示例:在一个车辆系统中,多个电子控制单元需要同时向中央控制单元发送状态消息。使用 UDP 时,一个 UDP 数据包可以包含多个 SOME/IP 消息,这些消息可能来自不同的 ECU,如发动机控制单元、刹车控制单元等;使用 TCP 时,一个 TCP 段也可以携带多个这样的消息。
- 接收 SOME/IP 实现应能够接收通过 UDP 或 TCP 传输的未对齐的 SOME/IP 消息。理由是:当在 UDP 或 TCP 中传输多个 SOME/IP 有效载荷时,只有当每个有效载荷的长度是对齐大小(例如 32 位)的倍数时,才能保证有效载荷的对齐。
- 如果一个服务器运行同一服务的多个实例,属于不同服务实例的消息应通过服务器端的传输协议端口映射到服务实例。
1.1 UDP 绑定
- 传输方式:SOME/IP 协议利用 UDP 传输消息时,直接将 SOME/IP 消息封装在 UDP 数据包内。这意味着 SOME/IP 消息作为 UDP 数据包的有效载荷进行传输,UDP 为其提供基本的传输服务。
- 分片限制:SOME/IP 协议本身不限制 UDP 的分片功能。UDP 分片是将一个较大的 UDP 数据包分割成多个较小的片段进行传输,在网络层可能会因为链路层的最大传输单元(MTU)限制而发生。例如,当一个 SOME/IP 消息较大,超过了网络链路层的 MTU 时,UDP 会自动将其分片,而 SOME/IP 协议允许这种分片操作。
- 消息识别与头部独立性:在单个 UDP 数据包中可能包含多个 SOME/IP 消息。接收方通过 SOME/IP 消息头部中的长度字段来确定每个消息的边界。每个 SOME/IP 有效载荷都有自己独立的 SOME/IP 头部,这使得每个消息在 UDP 数据包内能够被独立识别和处理,即便它们在同一个 UDP 数据包中传输。
1.2 TCP 绑定
- 与 UDP 绑定的关系及特性增强:TCP 绑定基于 UDP 绑定构建,在其基础上提供了更强大的功能。TCP 本身具有可靠性特性,能够处理如数据丢失、重复、乱序以及网络拥塞等问题,SOME/IP 利用 TCP 的这些特性来确保更可靠的消息传输,尤其适用于对数据完整性和准确性要求较高的场景。
- Nagle 算法设置:为了降低延迟并提高反应速度,在使用 TCP 绑定进行 SOME/IP 通信时,应关闭 Nagle 算法(即设置 TCP_NODELAY 选项)。Nagle 算法的目的是减少网络中微小数据包的数量,但在某些实时性要求较高的场景下,关闭它可以使消息能够更快地发送出去,减少不必要的等待时间。
- 连接管理责任与行为
- 连接建立与关闭时机:TCP 连接由客户端负责管理。当客户端需要发送第一个方法调用或者尝试接收第一个通知时,它会主动打开 TCP 连接;当 TCP 连接不再需要时(例如,相关服务已停止或超时),客户端负责关闭连接。这确保了连接的有效性和资源的合理利用,避免不必要的连接占用网络资源和系统开销。
- 连接丢失处理:如果 TCP 连接丢失,客户端未完成的请求将被视为超时。这意味着客户端需要在应用层处理这种超时情况,可能需要采取相应的措施,如重新发送请求或者进行错误处理,以保证业务逻辑的正确性。
- 多服务实例与连接关系:对于一个服务实例的所有方法、事件和通知,都使用单个 TCP 连接进行传输,以保证数据的有序性和连贯性。当存在多个服务实例时,每个服务实例需要单独的 TCP 连接,这样可以避免不同服务实例之间的通信干扰,确保每个服务实例的通信独立、稳定。
- 魔数饼干(Magic Cookies)的作用:为了便于测试工具识别通过 TCP 传输的 SOME/IP 消息边界,可在 TCP 消息流中定期插入 SOME/IP 魔数饼干消息。这些魔数饼干消息具有特定的格式和内容,就像在消息流中设置的特殊标记,测试工具可以通过检测这些标记来准确地确定 SOME/IP 消息的起始和结束位置,从而更好地进行测试和分析工作。
1.3 多服务实例(重要)
- 实例区分方式:同一服务的不同实例通过唯一的实例 ID 进行区分。这个实例 ID 在服务发现和通信过程中起到关键作用,使得系统能够准确识别和定位不同的服务实例,就像每个人都有唯一的身份证号码一样,用于在众多服务实例中准确找到目标实例。
- 部署情况与端口分配:这些服务实例可以分布在不同的电子控制单元(ECU)上,也可以多个实例同时存在于一个 ECU 中。在端口分配方面,不同的服务可以共享传输层协议(如 UDP 或 TCP)的相同端口号,但同一服务的不同实例在单个 ECU 上必须监听不同的端口。这样的设计确保了在复杂的汽车电子系统中,不同服务实例之间的通信不会发生冲突,并且能够被准确地路由和处理。例如,多个不同的服务可以共同使用 UDP 的 5000 端口进行通信,但如果一个服务有多个实例在同一 ECU 上运行,每个实例将使用不同的端口,如 5001、5002 等,通过服务 ID、实例 ID 以及端口号的组合,系统能够精确地找到目标服务实例进行通信。
1.4 通过 UDP 传输大型 SOME/IP 消息(SOME/IP - TP)
-
SOME/IP - TP 的引入
- SOME/IP 的 UDP 绑定只能传输能直接放入 IP 数据包的 SOME/IP 消息。
- 对于大于一定尺寸(例如 32KB)的 SOME/IP 消息,需要使用 SOME/IP 传输协议(SOME/IP - TP)。
- 大尺寸的 SOME/IP 消息被称为 “original” SOME/IP 消息,这些消息在 SOME/IP - TP 中被拆分成多个 “segments”(段)进行传输。
- 只有在需要传输非常大的数据块(> 1400 字节)且在出现错误时对延迟没有严格要求的情况下才使用 TCP。
-
SOME/IP - TP 的相关规则
- 使用 SOME/IP - TP 传输 SOME/IP 消息时需要激活会话处理(Session Handling),且每个原始消息的会话 ID 必须唯一。
- 所有 SOME/IP - TP 段都应携带原始消息的会话 ID,确保所有段具有相同的会话 ID。
- SOME/IP - TP 段的消息类型(Message Type)的 TP - Flag 应设置为 1。
- SOME/IP - TP 头的结构如下,SOME/IP - TP 段在 SOME/IP 头之后应有一个 TP 头,其结构如下(从高到低位):
- Offset [28 bits]
- Reserved Flag [1 bit](三次)
- More Segments Flag [1 bit]
- SOME/IP - TP 头应按照网络字节顺序(大端序)进行编码。
- 偏移量(Offset)字段应传输一个 32 位无符号整数的高 28 位,低 4 位应始终解释为 0。这意味着偏移量只能传输 16 字节倍数的值。
- TP 头部的偏移量字段应设置为原始消息中被传输分段的偏移量(以字节为单位)。
- 发送方应将保留标志(Reserved Flags)设置为 0,接收方应忽略这些标志。
- 除了最后一段,所有分段的 “更多分段” 标志(More Segments Flag)应设置为 1,最后一段应设置为 0。
- SOME/IP 长度字段应按先前规定使用,涵盖 SOME/IP 头部的前 8 字节、TP 头部的 4 字节以及分段本身。
- 分段的长度必须反映基于偏移量字段的下一分段的对齐情况。因此,除最后一段外,所有分段的长度应为 16 字节的倍数。
- 由于基于 UDP 的 SOME/IP 消息负载限制为 1400 字节,正确对齐的分段的最大长度为 1392 字节。
- SOME/IP - TP 消息应使用与原始消息相同的消息 ID(包括服务 ID 和方法 ID)、请求 ID(包括客户端 ID 和会话 ID)、协议版本、接口版本和返回码。
- 示例:描述一个 5880 字节负载的原始 SOME/IP 消息
- 原始 SOME/IP 消息将被分割成 5 个连续的 SOME/IP 段进行传输。每个段的负载最多为 1392 字节。每个段的 SOME/IP - TP 模块添加了额外的 TP 字段(红色标记)。
- 展示了前 4 个段的头信息,每个段包含 1392 字节负载,更多段标志设置为 1。
- 最后一个段(第 5 段)的头信息,包含剩余的 312 字节负载,更多段标志设置为 0。
-
发送方行为规则
- 分段决策依据:发送方仅对配置为可分段的消息进行分段操作,这是根据系统或应用的配置来确定的,确保只有需要分段的大型消息才会被处理,避免不必要的资源消耗。
- 段顺序与大小优化:发送方按照顺序发送段,并且在满足协议规范限制的前提下,尽量最大化每个段的大小。所有设置了更多段标志为 1 的段(即非最后一段)应具有相同的大小,这样可以简化接收方的重组过程,提高重组效率,同时也有助于合理利用网络资源。发送方不能发送重叠或重复的段,以保证消息的准确性和完整性,避免在接收方重组时出现混淆或错误。
-
接收方行为规则
- 消息重组依据:接收方根据消息的配置值(如消息 ID、协议版本、接口版本和消息类型(不含 TP 标志))来匹配用于重组的段,确保不同的消息不会被错误地组合在一起。通过这些关键信息,接收方能够从接收到的众多段中准确筛选出属于同一原始消息的段,并按照正确的顺序进行重组。
- 会话 ID 的作用:会话 ID 在重组过程中起到了重要的作用,它用于检测下一个需要重组的原始消息,以及处理乱序到达的段。当接收方收到一个具有不同会话 ID 的新段时,会启动新的重组过程,并可能丢弃之前未成功重组的旧段,确保每个会话内的消息重组独立、准确。
- 资源限制与处理:接收方应在其配置的有限资源范围内进行重组操作,特别是缓冲区大小的限制。如果重组后的消息达到缓冲区大小限制,接收方应停止重组并跳过剩余部分,仅将正确重组且大小在配置范围内的消息传递给应用程序,防止因消息过大导致缓冲区溢出等问题,保证系统的稳定性和可靠性。
- 错误处理与容忍度:接收方能够处理各种异常情况,如段的重排序(支持一定的重排序距离,至少 3 个位置的乱序)、重叠和重复段(通过覆盖等方式正确重组)。如果检测到明显错误(如段长度不符合要求),接收方应能够优雅地处理,例如取消重组操作,以避免错误数据的传播和影响应用程序的正常运行。同时,接收方不支持不同原始消息的段在同一缓冲区中交错处理,确保每个消息的处理独立、有序,防止数据混乱。
2. 请求 / 响应通信
- 请求 / 响应通信的定义和概述
- 即客户端发送请求消息,服务器回复响应消息。
- 客户端在请求消息中的操作
- 对于 SOME/IP 请求消息,客户端需要对负载和头进行以下操作:
- 构建负载。
- 根据客户端要调用的方法设置消息 ID。
- 设置长度字段为 8 字节(用于 SOME/IP 头)加上序列化负载的长度。
- 可选地,将请求 ID 设置为唯一编号(仅对客户端唯一)。
- 设置协议版本。
- 根据接口定义设置接口版本。
- 将消息类型设置为 REQUEST(即 0x00)。
- 将返回码设置为 0x00。
- 对于 SOME/IP 请求消息,客户端需要对负载和头进行以下操作:
- 请求消息负载的构建
- 为了构建请求消息的负载,所有输入或输出参数应按照方法签名中的参数顺序进行序列化。
- 服务器在响应消息中的操作
- 服务器构建响应消息的头和负载时,需要进行以下操作:
- 构建负载。
- 从相应请求中获取消息 ID。
- 设置长度为 8 字节加上新负载大小。
- 从相应请求中获取请求 ID。
- 将消息类型设置为 RESPONSE(即 0x80)或 ERROR(即 0x81)。
- 根据调用方法的返回码或错误消息设置返回码。
- 服务器构建响应消息的头和负载时,需要进行以下操作:
- 响应消息负载的构建
- 为了构建响应消息的负载,所有输入或输出参数应按照方法签名中的参数顺序进行序列化。
- 请求 / 响应的顺序和处理
- 服务器在收到特定请求 ID 的请求消息之前,不应发送针对该请求 ID 的响应消息。
- 客户端在完全发送特定请求 ID 的请求消息之前,不应接收针对该请求 ID 的响应消息。
3. Fire&Forget 通信
- Fire&Forget Communication 的定义
- 即没有响应消息的请求被称为 Fire&Forget。
- 客户端在 Fire&Forget 请求消息中的操作
- 对于 SOME/IP 的无返回请求消息(Fire&Forget),客户端需要对负载和头进行以下操作:
- 构建负载。
- 根据客户端要调用的方法设置消息 ID。
- 设置长度字段为 8 字节(用于 SOME/IP 头)加上序列化负载的长度。
- 可选地,将请求 ID 设置为唯一编号(仅对客户端唯一)。
- 设置协议版本。
- 根据接口定义设置接口版本。
- 将消息类型设置为 REQUEST_NO_RETURN(即 0x01)。
- 将返回码设置为 0x00。
- 对于 SOME/IP 的无返回请求消息(Fire&Forget),客户端需要对负载和头进行以下操作:
- Fire&Forget 消息的错误处理
- Fire&Forget 消息不应返回错误。错误处理和返回码应由应用程序在需要时自行实现。
4. 通知事件
- 通知事件的定义和目的
- 通知事件描述了一种通用的发布 / 订阅概念。通常,服务器发布一个服务,客户端订阅该服务。在某些情况下,服务器会向客户端发送事件,这些事件可能是更新的值或发生的事件。
- SOME/IP 仅用于传输更新后的值,而发布和订阅机制由 SOME/IP - SD 实现。
- SOME/IP 通知消息的构建
- 对于 SOME/IP 通知消息,服务器需要对负载和头进行以下操作:
构建负载。- 根据服务器要发送的事件设置消息 ID。
- 设置长度字段为 8 字节(用于 SOME/IP 头)加上序列化负载的长度。
- 将客户端 ID 设置为 0x00。设置会话 ID。在活动会话处理的情况下,每次传输时会话 ID 应递增。
- 设置协议版本。
- 根据接口定义设置接口版本。
- 将消息类型设置为 NOTIFICATION(即 0x02)。
- 将返回码设置为 0x00。
- 通知消息的负载应包含事件的序列化数据。
- 对于 SOME/IP 通知消息,服务器需要对负载和头进行以下操作:
- 多客户端情况下的通知处理(重要)
- 当同一 ECU 上存在多个订阅客户端时,系统应处理通知的复制,以节省通信介质上的传输。这在通过多播消息传输通知时尤为重要。
- 发送通知的策略
- Cyclic update(周期性更新):在固定时间间隔内发送更新后的值(例如,每 100 毫秒发送与安全相关的消息)。
- Update on change(变化时更新):当值发生变化时发送更新(例如,门打开时)。
- Epsilon change(阈值变化):只有当与上一个值的差值大于某个阈值时才发送更新。这种概念可能是自适应的,即基于历史预测,只有当预测值与当前值的差值大于阈值时才发送更新。
5. 字段
- 字段的定义和基本概念
- 一个字段代表一种状态并具有有效值。消费者在订阅该字段后会立即收到字段值作为初始事件。
- 一个字段应由获取器(getter)、设置器(setter)和通知器(notifier)事件组成。
- 一个字段必须至少包含获取器、设置器或通知器中的一个。
- 字段的获取器应是一个请求 / 响应调用,请求消息中的负载为空,响应消息中的负载包含字段的值。
- 字段的设置器应是一个请求 / 响应调用,请求消息中的负载包含期望设置的字段值,响应消息中的负载包含实际设置的字段值。
- 注意:如果请求负载的值被修改(例如,因为超出范围),修改后的值将在响应负载中传输。
- 通知器的操作
- 当客户端订阅字段时,通知器应发送一个事件消息,将字段的值传输给客户端。
- 通知器应在字段值发生变化时发送事件消息,并遵循事件的相关规则。
6. 错误处理
- 错误处理机制概述
- 错误处理可以在应用层或通信层进行,SOME/IP 支持两种机制:
- 返回码(Return Codes)在响应消息中的方法。
- 显式错误消息(Explicit Error Messages)。
- 使用哪种机制取决于配置。
- 错误处理可以在应用层或通信层进行,SOME/IP 支持两种机制:
- 返回码机制
- 响应消息中的返回码应用于将应用程序错误和方法的响应数据从方法提供者传输到调用者。
- 注意:从 SOME/IP 的角度来看,返回码和响应方法中的错误不被视为错误。这意味着如果请求 / 响应方法退出时返回码不等于 0x00,消息类型仍然是 0x80(如果应用程序错误或 AUTOSAR 客户端 - 服务器操作不同于 E_OK)。
- 例如,假设一个客户端调用服务器上的一个方法来获取车辆的当前速度。如果服务器成功获取并返回速度数据,返回码为 0x00,消息类型为 0x80(响应消息)。但如果服务器在获取速度数据时遇到问题(例如,传感器故障),返回码可能为非 0x00 的值(如 0x01 表示发生未指定错误),但消息类型仍然是 0x80。
- 显式错误消息机制
- 显式错误消息应用于将应用程序错误和响应数据或通用 SOME/IP 错误从方法提供者传输到调用者。
- 如果需要传输更详细的错误信息,错误消息(消息类型 0x81)的负载应填充错误特定数据,例如异常字符串。错误消息应代替响应消息发送。
- 例如,继续上面的车辆速度获取例子,如果服务器在获取速度数据时遇到了数据库连接错误,它可以发送一个显式错误消息(消息类型 0x81),在消息负载中包含 “数据库连接失败” 这样的错误描述信息。
- 错误消息的应用场景
- 这可以用于处理服务器中可能出现的所有不同类型的错误,以及通信介质或中间组件(例如交换机)可能出现的问题,这些问题可能需要通过可靠传输来处理。
- 所有消息在其头中都有一个返回码字段。
- 只有响应消息(消息类型 0x80)和错误消息(消息类型 0x81)应使用返回码字段将返回码携带到请求(消息类型 0x00)的响应中。
- 这个规则主要强调了返回码字段的正确使用主体。在 SOME/IP 协议的消息交互过程中,当有请求消息(消息类型为 0x00)发出后,只有与之对应的响应消息(0x80)和错误消息(0x81)能够利用返回码字段来携带返回码。
- 例如,在汽车电子系统中,一个控制单元(客户端)向另一个单元(服务器)发送请求消息,要求获取汽车发动机的实时温度数据。如果服务器成功获取数据并返回(消息类型 0x80),就可以在返回码字段填写代表成功的代码(如 0x00 表示无错误);如果获取数据过程出现错误,服务器发送错误消息(0x81),在返回码字段填写对应的错误代码(如 0x01 表示出现未指定错误),以此来回应最初的请求消息。这种限制确保了返回码是作为对请求消息的反馈而存在的,不会被其他无关消息随意使用。
- 除了消息类型为 0x80(响应消息)和 0x81(错误消息)之外的其他所有消息,都必须将返回码这个字段设置为 0x00。
- 继续以汽车电子系统为例,假设车辆系统中有广播消息用于通知各个单元车辆的行驶模式发生了改变(消息类型假设为 0x02,非 0x80 和 0x81),这种消息并不用于回应某个具体请求,所以它的返回码字段就应该按照规定设置为 0x00。这是为了让接收消息的单元能够明确这些消息不是用于反馈请求结果的,避免混淆。因为如果这些非响应 / 非错误消息的返回码字段可以随意设置,接收方可能会错误地将其当作对某个请求的响应或者错误反馈来处理,从而导致系统逻辑混乱。
6.1 返回码
- 返回码定义
- 返回码应为 8 位无符号整数(UINT8)。
- 当前定义的返回码如下图所示。
- SOME/IP 错误消息(即返回码 0x01 - 0x1F)不应带有错误消息。
6.2 错误消息
- 错误消息格式
- 在 SOME/IP 协议中,通常情况下,错误消息可以有自己独特的布局,而不是复用响应消息的布局。
- 推荐的错误消息布局包括:
- 特定异常的联合(Union of specific exceptions)
- 至少需要存在一个通用异常字段。
- 例如,在上述汽车电子系统中,如果 ECM 在获取发动机转速数据时出现错误,错误消息中可能有一个通用的异常字段来表示 “数据获取失败”,这是一个基础的、通用的错误标识。同时,可能还会有更具体的异常联合,比如 “传感器故障” 或者 “数据传输中断” 等具体的异常情况在错误消息中体现。
- 用于异常描述的动态长度字符串(Dynamic Length String for exception description)
- 这个字符串用于传输人类可读的异常描述,便于测试和调试。
- 继续以发动机转速数据获取错误为例,错误消息中除了有表示故障类型的字段外,还可以有一个动态长度字符串字段,如 “发动机转速传感器在 0.5 秒内未返回数据,导致无法获取当前转速”,这个字符串详细地描述了故障情况,方便技术人员在测试和维修时快速定位问题。
- 特定异常的联合(Union of specific exceptions)
- 错误处理规则
- SOME/IP 消息的接收者不应为事件 / 通知返回错误消息。
- SOME/IP 消息的接收者不应为 Fire&Forget 方法返回错误消息。
- 如果消息类型在请求或响应中设置不正确,SOME/IP 消息的接收者不应为事件 / 通知和 Fire&Forget 方法返回错误消息。
6.3 错误处理概述
-
概述
- 错误处理应基于接收到的消息类型。例如,只有方法可以返回返回码。
- 对于通过 UDP 接收的 SOME/IP 消息,应进行以下检查:
- UDP 数据报大小应至少为 16 字节(这是 SOME/IP 消息的最小尺寸)。
- 长度字段的值应小于或等于 UDP 数据报负载中的剩余字节。
- 如果上述检查失败,应发出格式错误的错误消息。
- SOME/IP 消息应基于下图所示的错误处理流程进行检查。此流程不包括基于应用程序的错误处理,仅涵盖通信错误处理。
-
TCP 连接检查
- 当通过 TCP 接收 SOME/IP 消息时,如果指定的错误发生,接收方应检查 TCP 连接并在必要时重新建立 TCP 连接。
- 检查 TCP 连接可能包括以下步骤:(重要)
- 检查是否接收到数据(例如,其他事件组)。
- 发送一个 Magic Cookie 消息并等待 TCP ACK。
- 重新建立 TCP 连接。
6.4 通讯错误及通讯错误处理
-
可靠性语义
- 当考虑 RPC 消息的传输时,存在不同的可靠性语义:
- Maybe(也许):消息可能到达通信伙伴。
- At least once(至少一次):消息至少到达通信伙伴一次。
- Exactly once(恰好一次):消息恰好到达通信伙伴一次。
- 使用上述术语时,请求 / 响应术语适用于两种消息(即请求和响应或错误)。
- 当考虑 RPC 消息的传输时,存在不同的可靠性语义:
-
SOME/IP 的可靠性实现
- 虽然不同实现可能采用不同方法,但 SOME/IP 目前在使用 UDP 绑定时实现 “Maybe” 可靠性,在使用 TCP 绑定时实现 “Exactly once” 可靠性。进一步的错误处理留给应用程序。
-
“Maybe” 可靠性的处理
- 对于 “Maybe” 可靠性,仅需要超时机制。当使用请求 / 响应通信结合 UDP 作为传输协议时,下图展示了 “Maybe” 可靠性的状态机。
- 对于 “Maybe” 可靠性,仅需要超时机制。当使用请求 / 响应通信结合 UDP 作为传输协议时,下图展示了 “Maybe” 可靠性的状态机。
-
“Exactly once” 可靠性
- 对于 “Exactly once” 可靠性,可以使用 TCP 绑定,因为 TCP 被定义为允许可靠通信。
7. SOME/IP 协议的使用和指导原则
7.1 选择传输协议
- SOME/IP 支持用户数据报协议(UDP)和传输控制协议(TCP)。
- UDP 是一种非常精简的传输协议,仅支持最重要的功能(如通过校验和进行多路复用和错误检测)。TCP 则增加了额外的功能以实现可靠的通信,不仅处理位错误,还处理分段、丢失、重复、重排序和网络拥塞。
- 在车辆内,许多应用需要非常短的超时来快速响应。由于应用本身可以处理不太可能发生的错误事件,这些要求更适合使用 UDP。例如,在使用循环数据的情况下,通常最好的方法是等待下一个数据传输,而不是试图修复最后一个。UDP 的主要缺点是它不处理分段,因此只能传输较小的数据块。
- 指导原则:
- 仅在需要传输非常大的数据块(> 1400 字节)且在错误情况下没有硬延迟要求时使用 TCP。
- 在错误情况下需要硬延迟要求(<100ms)时使用 UDP。
- 在需要传输非常大的数据块(> 1400 字节)且在错误情况下有硬延迟要求时,使用 UDP 与 SOME/IP - TP。
- 尝试使用外部传输或传输机制(网络文件系统、APIX 链接、1722 等),当它们更适合使用情况时。在这种情况下,SOME/IP 可以传输文件句柄或可比标识符,这给设计者额外的自由度(例如在缓存方面)。
- 所使用的传输协议是由接口规范按照每条消息来指定的。
- 在一个通信系统中,不同的消息可能有不同的特性和需求。例如,在汽车电子系统中,有的消息可能对实时性要求极高,但对数据完整性要求相对较低;而有的消息则必须保证数据准确无误地传输。接口规范会根据每条消息的这些特性来确定应该采用哪种传输协议。这意味着对于每一条具体的消息,系统会根据预先定义好的接口规范来选择合适的传输协议,可能是 UDP(用户数据报协议)、TCP(传输控制协议)或其他协议。
- 方法、事件和字段通常应该只使用一种传输协议。
- 在系统设计中,方法(例如远程调用的操作方法)、事件(如系统中的状态变化事件)和字段(如传输的数据中的各个数据字段)通常为了保持一致性和便于管理,最好采用同一种传输协议。这样做可以简化系统的设计和维护,避免因为使用多种协议而带来的复杂性和潜在的兼容性问题。例如,如果方法调用采用 TCP 协议,那么与之相关的事件通知和数据字段也最好采用 TCP 协议,这样可以确保整个操作流程在相同的传输机制下进行,减少出错的可能性。
7.2 传输 CAN 和 FlexRay 帧
- 总体要求
- SOME/IP 协议应该允许对 CAN(Controller Area Network,控制器局域网)和 FlexRay 帧进行隧道传输(tunnel)。这意味着 SOME/IP 需要具备在其网络通信中封装和传输 CAN 和 FlexRay 数据帧的能力。
- 示例:
- 假设在一辆汽车中,发动机控制单元(ECU)通过 CAN 总线与其他电子控制单元进行通信,传递发动机转速、温度等数据。同时,车辆的底盘控制系统使用 FlexRay 总线来传输诸如悬挂系统状态、转向角度等数据。
- 当车辆的信息娱乐系统(通过 SOME/IP 进行通信)需要获取发动机转速和底盘状态数据时,SOME/IP 就需要将来自 CAN 和 FlexRay 的相关数据帧进行隧道传输。
- 消息 ID 空间协调
- 然而,在进行这种隧道传输时,消息 ID(Message ID)空间需要在两种使用情况下(即传输 CAN 和 FlexRay 帧时)进行协调。这是因为 CAN 和 FlexRay 本身都有自己的消息 ID 标识机制,为了避免在 SOME/IP 网络中出现消息 ID 冲突,需要对这些 ID 进行统一的协调和管理。
- 例如,在 CAN 网络中,发动机转速数据的消息 ID 可能是 0x100,而在 FlexRay 网络中,底盘悬挂系统状态数据的消息 ID 可能是 0x200。为了在 SOME/IP 网络中正确区分和处理这些数据,需要对消息 ID 进行协调。可能会规定在 SOME/IP 网络中,来自 CAN 的消息 ID 在传输时变为 0x1000 + 0x100 = 0x1100,来自 FlexRay 的消息 ID 变为 0x2000 + 0x200 = 0x2200,这样就能避免 ID 冲突。
- SOME/IP 头的使用
- 整个 SOME/IP 头(Header)应该用于传输 / 隧道 CAN/FlexRay。这表明在通过 SOME/IP 传输 CAN 和 FlexRay 帧时,需要使用完整的 SOME/IP 头来封装这些帧,以确保在网络中的正确传输和识别。
- 当 SOME/IP 将来自 CAN 的发动机转速数据帧传输给信息娱乐系统时,会使用完整的 SOME/IP 头来封装该 CAN 帧。SOME/IP 头中可能包含源 IP 地址(发动机控制单元的 IP)、目的 IP 地址(信息娱乐系统的 IP)、消息类型等信息,确保数据能够准确无误地从发动机控制单元传输到信息娱乐系统。同样,对于来自 FlexRay 的底盘状态数据帧也是如此。