SomeIP报文详解

SomeIP 协议详解释

1、SomeIP简介

1.1、SomeIP背景

SomeIP(Scalable service-Oriented Middleware over IP)是车载领域面向服务的通信协议,由 Benjamin KrebsLars Völker 等人主导设计,后续才被纳入 AUTOSAR 规范体系,专门解决车载 ECU(电子控制单元)间的高可靠、低延迟、可扩展通信需求,广泛应用于 ADAS、自动驾驶、车载信息娱乐系统(IVI)等场景(例如透明车底功能中多路摄像头数据传输、传感器融合数据交互)。

一句话总结就是:车载环境中的RPC + Pub/Sub框架,运行在以太网上。

1.2、参考文档

Benjamin Krebs,Lars Völker 博士主导设计文档

AutoSar AP的SOME/IP的标准文档

1.3、相关术语解释

RPC(Remote Procedure Call,远程过程调用)是一种跨进程 / 跨设备的通信技术,核心目标是让开发者像调用本地函数一样调用远程设备(如另一台 ECU、服务器)上的函数,无需关注底层网络传输细节(如 IP、端口、协议封装)。

Method(方法)服务端中可被客户端远程调用的函数或子程序。分为两种类型。一种是 Request/Response(请求 - 应答)型,客户端发请求后服务端需返回响应;另一种是 Fire&Forget(发后即弃)型,客户端发送请求后无需服务端回应,例如客户端触发一次传感器自检指令,无需等待反馈

Event(事件)当特定条件满足时,服务端向已订阅的客户端主动推送的消息,比如传感器数据更新、设备故障告警等。其无需客户端发起请求,依赖订阅机制,支持周期发送、数据变更时发送等模式。

Field(字段)用于表示服务的可远程访问属性,比如摄像头的曝光参数、雷达的探测距离等。支持三种交互方式,Getter 用于客户端读取属性值,Setter 用于客户端修改属性值,Notifier 用于属性值变化时服务端主动推送更新。

EventGroup(事件组)多个事件或字段通知器的逻辑组合,方便客户端批量订阅。比如将车载座舱内的温度、湿度、空气质量等多个环境相关的事件归为一个事件组,客户端订阅该组即可获取所有相关数据,无需逐个订阅。

2、SomeIP头格式详解

Message ID(消息标识):32 位字段,由 16 位 Service ID 和 16 位 Method ID 组成。

1.Service ID部分:用户/系统指定的,整车唯一。用于调用应用程序的方法或标识事件。

2.Method ID部分:通常拆解为MethodEvent两部分,如下表

Method ID 范围 区分
Method ID 0x0000-0x7FFF Method ID 的第一位为 0
Event ID 0x8000-0x8FFF Event ID 的第一位为 1

Length : 表示后续数据的总长度(不包含Message ID (4 bytes) 和 Length 字段本身 (4 bytes))

Request ID : 由 Client ID [16 Bits]Session ID [16 Bits]构成.

Client ID表示 用于区分使用同一Method的不同客户端

session ID 由数据的发送方每发送一次数据+1,从0x1加到0xffff后,从1重新开始,用于区分每一条消息。

字段 含义
Service ID 哪个服务
Method ID 哪个方法
Client ID 谁调用
Session ID 是这位客户端的第几次调用

通俗点理解可以这样说:

复制代码
*******************************************

Service ID 含义:调用哪个服务。
0x1111 → "雷达服务"
0x2222 → "摄像头服务"

*******************************************

Method ID  含义:调用服务中的哪个方法。
例如雷达服务:
Method ID = 0x0001 → GetStatus
Method ID = 0x0002 → GetDistance

*******************************************

Client ID 含义:标识这个请求来自哪个 Client。

由客户端在 SOME/IP 配置中分配,作用:

   服务端看到 Client ID,知道是哪个 ECU 发来的请求。

   同一个 ECU 的所有请求使用相同 Client ID。

例:
CameraECU = 0x31
RadarECU = 0x21

*******************************************

Session ID 含义:标识同一 Client 发出的第几次调用。

这个字段最重要,因为它让服务端能够:
    ✔ 区分该客户端的每一次请求
    ✔ 把响应与请求匹配

一般是一个自增计数器:

    第 1 次调用 → Session ID = 1
    第 2 次调用 → Session ID = 2
    第 1000 次调用 → 1000

客户端自己维护(通常从 0 或 1 开始递增)。
*******************************************


可以总结为:
Service ID + Method ID  → 我调用什么服务中的什么方法
Client ID + Session ID  → 我是谁,这一次请求是第几次请求

Protocol Version (SomeIP协议版本): 说明当前报文遵循 WHICH 版本的 SOME/IP 协议格式。

目前行业普遍使用:

cpp 复制代码
Protocol Version = 0x01

Interface Version (服务接口的版本号):表示当前接口的版本。

复制代码
在 AUTOSAR 或 CommonAPI 中,服务接口定义包含版本号,例如(fidl):

interface DistanceService {
    version 2
    method getDistance(): float32
}

Interface Version = 2

如果客户端使用 Interface Version = 1 调用 getDistance()

    .服务端可以返回错误码(Return Code = NOT_SUPPORTED)
    .或者提供向下兼容处理

Message Type (消息类型):这是报文解析和区分请求、响应、事件的关键字段。

Message Type 告诉服务端或客户端,这个报文是:

请求(Request)、响应(Response)、事件(Event)、发布/订阅消息(Subscribe / Subscribe Ack / Notification)。

  1. 普通 SOME/IP Message Types
名称 含义
0x00 REQUEST 普通请求,期望服务端返回响应(即使返回 void)
0x01 REQUEST_NO_RETURN "Fire & Forget",客户端发送请求但不关心响应
0x02 NOTIFICATION 客户端请求服务端执行通知/事件回调,不期望响应
0x80 RESPONSE 服务端响应请求,正常返回
0x81 ERROR 服务端响应请求,返回错误

✅ 核心理解:

0x00/0x01/0x02 → 客户端发出的请求

0x80/0x81 → 服务端响应客户端

普通报文(非 TP)使用 TCP 或 UDP,适合小数据量请求/响应。

  1. TP(Transport Protocol)Message Types

AUTOSAR SOME/IP 支持 TP(Transport Protocol) 用于大 payload(例如图像、雷达数据等)分包发送。TP 类型在普通类型基础上加了偏移量:

名称 含义
0x20 TP_REQUEST 大数据请求,期望响应
0x21 TP_REQUEST_NO_RETURN 大数据 Fire & Forget 请求
0x22 TP_NOTIFICATION 大数据通知/事件回调请求,不期望响应
0xA0 TP_RESPONSE 大数据响应消息
0xA1 TP_ERROR 大数据响应错误消息

vsomeip 自动支持 TP 分包

客户端发大 payload 会选择 TP_REQUEST 或 TP_REQUEST_NO_RETURN

服务端收到 TP_REQUEST 会自动组装完整 payload,再调用 Stub 方法

在业务逻辑里一般不需要关心分包,Message Type 自动设置。

需要注意一点

1、客户端发起 Request → 服务端处理 → 服务端返回 Response

2、服务端无法主动发起 Request 给客户端

3、所有 GET/SET/Method 调用都必须由客户端发起

Return Code (标识请求是否被处理):

AUTOSAR 对不同 Message Type 的 Return Code 要求

Message Type Return Code 要求
REQUEST (0x00) N/A,必须填 0x00 (E_OK)
REQUEST_NO_RETURN (0x01) N/A,必须填 0x00 (E_OK)
NOTIFICATION (0x02) N/A,必须填 0x00 (E_OK)
RESPONSE (0x80) 必须填写响应结果(各种错误码或 E_OK)
ERROR (0x81) 必须填写错误码(但不能是 0x00)

Payload (序列化):

消息真正携带的业务数据(Service 方法参数、事件数据、返回值等)。

序列化这里先简单介绍一下,后面在使用中在详细说明。

3、CommonAPI + SomeIP

SOME/IP 是底层通信协议,直接使用 SOME/IP 来写代码会非常底层(构造 payload、管理序列号、处理 SD、编码解码等),所以一般不会直接用纯 SOME/IP。

CommonAPI(由 GENIVI/Eclipse 基金会提供)本身不是网络协议,它主要负责:定义一个接口语言 FIDL、自动生成 C++ API(Proxy / Stub)、帮你做分布式接口的封装和底层"binding"结合使用、它让你调用远程服务就像调用本地对象一样,不用自己写通信相关的代码。

也就是说CommonAPI是对SomeIP的二次封装,让使用SomeIP更加的简洁方便。

结语

感谢您的阅读,如有问题可以私信或评论区交流。

^ _ ^

相关推荐
利刃大大42 分钟前
【c++中间件】redis介绍 && redis-plus-plus库使用
c++·redis·中间件
永不停转1 小时前
关于 QGraphicsItemGroup 内部项目发生变化后group重新定位的问题
c++·qt
IT永勇2 小时前
C++设计模式-装饰器模式
c++·设计模式·装饰器模式
Murphy_lx2 小时前
std_ofstream
c++
草莓熊Lotso2 小时前
红黑树从入门到进阶:4 条规则如何筑牢 O (logN) 效率根基?
服务器·开发语言·c++·人工智能·经验分享·笔记·后端
啊董dong2 小时前
课后作业-2025年11月23号作业
数据结构·c++·算法·深度优先·noi
带鱼吃猫3 小时前
Linux系统:策略模式实现自定义日志功能
linux·c++
zzzsde3 小时前
【C++】C++11(1):右值引用和移动语义
开发语言·c++·算法
学困昇3 小时前
C++11中的包装器
开发语言·数据结构·c++·c++11