SomeIP 协议详解释
1、SomeIP简介
1.1、SomeIP背景
SomeIP(Scalable service-Oriented Middleware over IP)是车载领域面向服务的通信协议,由 Benjamin Krebs 与 Lars Völker 等人主导设计,后续才被纳入 AUTOSAR 规范体系,专门解决车载 ECU(电子控制单元)间的高可靠、低延迟、可扩展通信需求,广泛应用于 ADAS、自动驾驶、车载信息娱乐系统(IVI)等场景(例如透明车底功能中多路摄像头数据传输、传感器融合数据交互)。
一句话总结就是:车载环境中的RPC + Pub/Sub框架,运行在以太网上。
1.2、参考文档
Benjamin Krebs,Lars Völker 博士主导设计文档
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部分:通常拆解为Method和Event两部分,如下表
| 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)。
- 普通 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,适合小数据量请求/响应。
- 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更加的简洁方便。
结语
感谢您的阅读,如有问题可以私信或评论区交流。
^ _ ^