1 摘要
SD状态机可分为两种:Server端状态机与Client状态机,每种状态机均可以分为两种状态:Down State(下电休眠)与Available State(上电唤醒)。其中Available State可再进一步细分为Initial Wait Phase, Repetition Phase, Main Phase。本文将对两种状态机进行详细介绍并进行实例示例。
2 SD状态机详解
- SOME/IP-SD: 基于 SOME/IP 的服务发现协议,用于在网络中动态查找可用的服务/事件组(Offer)以及请求所需的服务/事件组(Find)。
- Server-SD: 运行在提供特定服务(Service Instance)的 ECU 上。负责宣告(Offer)本 ECU 提供的服务及其可用性。
- Client-SD: 运行在需要消费特定服务(Service Instance)的 ECU 上。负责寻找(Find)网络中可用的所需服务。
它们各自实现了一个状态机来管理服务发现和宣告的生命周期,主要目标是高效地传播服务可用性信息,同时最小化网络流量(尤其是在服务状态稳定时)。
2.1 Client-SD 状态机:寻找服务
Client-SD 状态机的主要作用是主动发现它感兴趣的服务的可用性(或不可用性),并维护一个已知可用服务实例的列表。其状态转换通常围绕 Find
入口 (ENTRY
) 和 Offer
入口 (ENTRY
) 的接收来驱动。
- 作用:客户端通过SD协议动态发现服务提供者(Server),订阅服务状态变更,支持车载网络的动态拓扑(如ECU休眠/唤醒)。
- 核心状态:
Initial Wait
:等待初始延迟,避免网络泛洪Repetition
:周期性发送服务发现请求Main
:服务可用时正常运行Down
:服务不可用或超时
状态机如下图:
SD启动时序图如下:
关键状态:
INITIAL_WAIT
(初始等待)- 进入条件: Client 启动或需要查找一个新服务时。
- 行为:
- 设置一个初始等待定时器 (
INITIAL_DELAY
)。 - 在这个状态下,不发送任何
Find
报文。
- 设置一个初始等待定时器 (
- 作用: 避免在网络启动或大量客户端同时启动时产生广播风暴。随机化初始延迟有助于错开客户端的查询请求。
- 退出条件:
INITIAL_DELAY
超时 -> 进入REPETITION_PHASE
。- 特殊: 如果收到一个所需的
Offer
入口 (ENTRY
)(可能来自其他Client的响应广播或服务器主动宣告),可能直接进入MAIN_PHASE
(依赖具体实现策略,但标准状态机优先超时)。
REPETITION_PHASE
(重复阶段 - 主动查找)- 进入条件: 通常来自
INITIAL_WAIT
的超时。 - 行为:
- 开始周期性地(以较短间隔)发送
Find
入口 (ENTRY
) 报文。这些报文声明 Client 想要查找的特定Service-ID
,Instance-ID
(可能还有Major Version
等)。 - 设置的定时器周期称为
REPETITION_BASE_DELAY
(重复基本延迟)。 - 每次发送后,等待间隔会以指数方式增长(倍数因子
REPETITION_MAX
, 如 2倍),直到达到CYCLIC_OFFER_DELAY
(周期宣告延迟)。 - 积极监听所需的
Offer
入口 (ENTRY
),不仅来自Server的直接Offer,也来自其他Client(因为SOME/IP-SD多播,Client也能收到Offer)。
- 开始周期性地(以较短间隔)发送
- 作用:
- 主动探测网络中所需服务是否存在。
- 使用指数退避策略,在服务暂时不可用时避免过度查询,在服务新加入时快速发现(初期限流,中期加快)。
- 退出条件:
- 收到一个所需的
Offer
入口 (ENTRY
) -> 进入MAIN_PHASE
。 - 重复间隔增长到
CYCLIC_OFFER_DELAY
(并且未收到Offer) -> 进入MAIN_PHASE
(但此时Client假设服务尚未找到)。 - 需要查找的服务被取消订阅(依赖应用层) -> 可能进入
STOPPED
或清理状态。
- 收到一个所需的
- 关键点: Client 在未收到 Offer 时仍然会持续发送 Find,但速率越来越慢。
- 进入条件: 通常来自
MAIN_PHASE
(主阶段 - 维护/确认)- 进入条件: 成功从
REPETITION_PHASE
收到所需的Offer
入口 (ENTRY
) 或REPETITION_PHASE
超时进入(表示服务不存在或未响应)。 - 行为:
- 如果服务可用: Client 已经接收到所需的 Offer。它会监听 Server 周期性发送的
Offer
入口 (ENTRY
) 报文(包含TTL
)。Client 会根据收到的这些 Offer 更新其内部的服务可用性状态和 TTL 定时器。 - 如果服务不可用: Client 知道服务当前未被 Offer(来自
REPETITION_PHASE
超时进入时),它会以极长的间隔(通常是CYCLIC_OFFER_DELAY
)周期性地发送Find
报文,或者完全不发送(依赖于配置策略,标准倾向于发送但间隔非常长)。 - 监听网络中的
Stop Offer
(STOP_OFFER_ENTRY
),该入口表示服务下线。 - 如果监听的服务Offer超时(TTL定时器到期未刷新),则认为服务下线。
- 如果服务可用: Client 已经接收到所需的 Offer。它会监听 Server 周期性发送的
- 作用:
- 确认和维护已知服务的在线状态。
- 当服务在线时,依靠 Server 的周期性 Offer 更新状态(节能,Client 仅监听)。
- 当服务离线(通过Stop Offer或超时检测到)或初始化未找到时,可能进入
REPETITION_PHASE
(重新查找)或以极慢速度继续 Find。 - 确保在网络或Server出现短暂故障后,Client 最终能再次尝试查找。
- 状态内转换:
- 监听到所需服务的
Offer
-> 重置TTL定时器(如果服务已进入)。 - 监听到所需服务的
Stop Offer
或 TTL 超时 -> 服务状态变不可用。根据策略,可能会重新触发查找(进入INITIAL_WAIT
或REPETITION_PHASE
)或保持MAIN_PHASE
但标识服务不可用并慢速 Find。 - 应用层重新请求查找服务 -> 可能重新进入
REPETITION_PHASE
。
- 监听到所需服务的
- 进入条件: 成功从
Down
(停止)- 进入条件: 应用层明确要求停止查找该服务(服务不再需要)。
- 行为:
- 停止所有与服务发现相关的定时器。
- 不再发送
Find
入口。 - 清理内部该服务的状态。
- 作用: 释放资源,避免不必要的网络流量。
2.2 Server-SD 状态机:宣告服务
Server-SD 状态机的主要作用是宣告本 ECU 提供的服务的可用性,并在服务下线或 ECU 下线时撤销宣告。其状态转换通常围绕宣告的开始 (Offer
) 和停止 (Stop Offer
) 来驱动。
- 作用:服务端注册服务并广播服务状态,响应客户端查询,维持服务可用性心跳。
- 核心状态:
Down
:服务未就绪Not Available
:已注册但主动声明不可用Available
:服务在线并广播OfferDown
:服务终止
状态机如下图:
SD启动时序图如下:
关键状态:
WAIT
(等待)- 进入条件: 服务刚刚实例化完成或 ECU 启动时(对于需要启动宣告的服务)。
- 行为:
- 设置一个初始等待定时器 (
INITIAL_DELAY
)。 - 在这个状态下,不发送任何
Offer
或Stop Offer
报文。
- 设置一个初始等待定时器 (
- 作用: 避免在网络启动或大量Server同时上线时产生广播风暴。随机化初始延迟有助于错开服务器的宣告。
- 退出条件:
INITIAL_DELAY
超时 -> 进入REPETITION_PHASE
。- 接收到匹配的
Find
入口(可选,通常在WAIT
后进入REPETITION
宣告)。 - 应用层请求停止服务 -> 进入
STOPPED
(此时可能需要发送Stop Offer
,但WAIT
期间服务还未宣告过)。
REPETITION_PHASE
(重复阶段 - 主动宣告)- 进入条件: 通常来自
WAIT
的超时。 - 行为:
- 开始周期性地(以较短间隔)发送
Offer
入口 (ENTRY
) 报文,宣告本服务可用。 - 设置的定时器周期称为
REPETITION_BASE_DELAY
(重复基本延迟)。 - 每次发送后,等待间隔会以指数方式增长(倍数因子
REPETITION_MAX
),直到达到CYCLIC_OFFER_DELAY
(周期宣告延迟)。 - 这个阶段发送的
Offer
报文中通常会包含较短的TTL
(生存时间)。 - Server 在这个阶段对收到的与其提供的服务匹配的
Find
报文不作特殊响应(因为它已经在主动宣告了)。
- 开始周期性地(以较短间隔)发送
- 作用:
- 快速、积极地在网络中宣告服务的上线/可用性。
- 使用指数退避策略,在宣告初期快速覆盖网络,避免持续高速宣告造成的流量浪费。
- 退出条件:
- 宣告间隔增长到
CYCLIC_OFFER_DELAY
-> 进入MAIN_PHASE
。 - 应用层请求停止服务 -> 进入
STOPPED
(并在停止前发送Stop Offer
)。
- 宣告间隔增长到
- 进入条件: 通常来自
MAIN_PHASE
(主阶段 - 维护宣告)- 进入条件: 来自
REPETITION_PHASE
的间隔增长超时(达到CYCLIC_OFFER_DELAY
)。 - 行为:
- 以稳定的、长间隔的时间 (
CYCLIC_OFFER_DELAY
) 周期性地发送Offer
入口 (ENTRY
) 报文,宣告服务持续可用。 - 在报文中设置一个相对长的
TTL
(通常大于CYCLIC_OFFER_DELAY
)。例如,TTL = CYCLIC_OFFER_DELAY * 3
。 - 对收到的与其提供的服务匹配的
Find
报文进行响应:收到Find
后,Server 会立即发送一个Offer
入口报文(包含该服务),并重置其宣告定时器(即紧接着的周期性宣告会延迟CYCLIC_OFFER_DELAY
后再次发送)。
- 以稳定的、长间隔的时间 (
- 作用:
- 以较低的持续开销维护服务在线信息。客户端可以通过周期性的 Offer 刷新其 TTL 定时器。
- 对客户端
Find
的快速响应:当有新客户端加入或原有客户端遗漏了之前的 Offer 时,它们发送Find
会立刻得到响应,加速服务发现过程。 - 节省流量:稳定后,网络中的主要流量是周期性的 Offer 报文(速率慢)和对新 Find 的即时响应。
- 退出条件:
- 应用层请求停止服务 -> 进入
STOPPED
。
- 应用层请求停止服务 -> 进入
- 进入条件: 来自
Down
(停止)- 进入条件: 应用层明确请求停止提供的服务或 ECU 准备下线时。
- 行为:
- 发送一个
Stop Offer
(类型为STOP_OFFER_ENTRY
) 入口报文,宣告服务下线。通常会发送多次(例如,REPETITION_MAX
次,使用快速的REPETITION_BASE_DELAY
)。 - 停止所有周期性宣告的定时器。
- 清理内部该服务的宣告状态。
- 发送一个
- 作用: 显式地通知网络中的所有潜在客户端,该服务已不可用,避免客户端在 TTL 超时前持续尝试连接失败。
- 关键点: 发送
Stop Offer
是强制的,是服务优雅下线的重要组成部分。它允许客户端立即移除服务条目,而不是等待 TTL 超时。
某项目典型配置参数如下:
3 在车载控制器中的应用示例
场景1:车窗控制服务:
Server-SD(车窗ECU):
- 上电后进入
Available
状态,周期性广播OfferService
(Service ID=0x1234)。 - 广播周期
T_offer=1s
,TTL=3(持续3个周期)。 - 休眠时发送
StopOffer
进入NotAvailable
。
- 上电后进入
Client-SD(车身控制器):
- 需控制车窗时,从
InitialWait
(T_initial=100ms)进入Repetition
。 - 发送
FIND(0x1234)
,进入WaitResponse
。 - 收到Offer后进入
Main
状态,调用SOMEIP控制接口。 - 若3次重试未响应,进入
Down
并触发诊断报警。
- 需控制车窗时,从
通信流程:
流程图说明:
初始延迟阶段
Client-SD
首先发送一个100ms的初始延迟信号T_initial
服务发现阶段
客户端发起服务发现请求FIND
,查找特定服务ID(0x1234)应用通信阶段
通过SOME/IP协议传输应用层数据WindMove()
终止状态
客户端最终进入停止状态(Down),未显示服务端响应
关键设计要点:
- 动态服务发现:支持ECU热插拔(如传感器模块更换)。
- 心跳机制:
TTL
控制服务有效期,客户端需刷新订阅。 - 多播优化:SD报文使用UDP多播(e.g., 224.224.224.245),减少网络负载。
- 安全扩展:AUTOSAR SecOC可对SD报文签名,防止恶意节点注入。
在AUTOSAR中的实现:
// Server-SD示例代码(AUTOSAR AP)
Sd_ServerServiceType WindowService = {
.serviceId = 0x1234,
.instanceId = 0x01,
.stateHandler = Sd_ServiceStateChanged // 状态切换回调
};
// 注册服务
Sd_OfferService(
WindowService,
SD_TTL_3_CYCLES,
SD_MULTICAST_OFFER
);
// Client-SD订阅
Sd_SubscribeEvent(0x1234, 0x01, SD_EVENT_GROUP_1);
Sd_SetEventGroupHandler(My_WindowStatusHandler); // 事件回调
场景2:车灯控制系统:
- Server端:车灯控制器(提供
SetLightBrightness
服务) - Client端:仪表盘控制器(需控制车灯亮度)
通信流程:
关键状态解释:
状态 | 触发条件 | 行为 |
---|---|---|
Server REPETITION | 服务启动 | 每秒广播1次Offer(指数退避) |
Client REPETITION | 未收到Offer | 重发FindService(最多3次) |
MAIN | 收到Offer/订阅成功 | 正常通信状态 |
Down | 主动取消订阅/服务不可用 | 停止服务请求 |
工程实践注意事项
- TTL管理:Offer消息中的
TTL
字段决定服务有效期(默认3s),客户端需在失效前刷新订阅。 - 多播地址:SD报文使用专用多播地址(例如:224.224.224.245)
- 容错机制:
- 客户端连续3次收不到Offer则判定服务下线
- 服务端需处理重复订阅请求(幂等设计)
车载其他场景示例:当车辆进入隧道时,环境光传感器(Client)通过SD协议动态发现车灯控制器(Server),触发自动大灯服务。若控制器节点重启,SD协议确保服务在500ms内恢复。