本文基于AutoSar官方文档整理,文档下载:AutoSar SOME/IP标准协议

SOME/IP 协议

缩略词SOME/IP基础协议SOME/IP-SD协议SOME/IP-SD协议格式报文头服务实体事件组实体配置项

通信行为流程启动阶段行为关机行为行为时序

总结

SOME/IP是一个应用于汽车或者嵌入式系统的通信中间件解决方案,该协议是一个基于IP的,且面向服务的应用层网络通信协议,具备可伸缩和可扩展,以及可应用在不同的操作系统中用于各类设备之间的通信等特性。通俗一点来说,SOME/IP它是一个协议,这个跟我们平时开发外设自己定义的那种TLV包的格式差不多,有包头,有报文长度,有报文内容, 多个设备间基于IP网络来进行包的收发,SOME/IP协议还定义了一些通信的动作以及具体场景下端与端之间的行为。

缩略词

在介绍具体协议内容之前可以先了解一下一些后面具体的名词定义,后续不管是协议还是协议栈中,都大量出现了相关的名词应用

Method : SOME/IP实现端存在的方法,类似于一个函数,或者子程序。RR请求 : Request/Response,请求端调用目标端的method,并且有返回内容,可以理解为我们日常写程序过程中的调用一个带返回值的函数FF请求 : Fire And Forget,请求端调用目标端的method, 没有返回参数。可以理解为我们日常写程序过程中调用了一个返回值为void的函数。Event : 顾名思义就是一个事件,event事件在SOME/IP中是单向的,你可以理解成触发一个回调函数,通知函数监听方。Field : 顾名思义是一个属性,属性自带setter与getter方法,并且支持RPC调用,且还包含了一个notification,这个notification实际也是一个event,当属性值变化时通知监听对象。Service: 上面说过SOME/IP是面向服务开发的,Service是由一个个的Field,Event, Method组成的逻辑体。Eventgroup:事件组,event或者field notification组成的结合体,主要用来允许事件订阅

SOME/IP基础协议

基础协议包的定义如上: MessageID: 占了4个byte共32位,前16位代表Service ID, 中间一位类型符用来表示后面的ID是Method ID(flag = 0)还是Event ID(flag = 1), 后15位代表Method ID或者Event ID. 格式如下:

Service ID(16bit) ------ 0(1bit) ------ MethodID(15bit)

Service ID(16bit) ------ 1 (1bit) ------ ClientID (15bit)

Length: 报文从RequestID开始到报文最后一个字节的长度 RequestID: 请求ID用来区分消息的来源,RequestID由ClientID与SessionID组成,Session ID的有效范围是0x1-0xFFFF, 当到达0xFFFF后,值重置为0x1 Protocol Version: 协议版本号 Interface Version :服务接口版本号 Message Type : 消息类型,类型如下图 Return Code : 返回值类型,用来表示请求消息是否成功处理。该值只有在消息类型为Response/Error中才有代表意义,其他报文类型中,该值为0. 具体的错误码对照如下表。 Payload : 有效的数据负载,UDP传输时最大传输字节数为1400,TCP传输无限制

SOME/IP-SD协议

SOME/IP-SD协议是基于SOME/IP基础协议上制定的一系列通信业务协议,全称(Scalable service-Oriented MiddlewarE over IP - Service Discover),主要用于SOME/IP服务实例的定位,状态检测,以及SOME/IP服务发布/订阅机制的实现。我们可以这么理解,假设有这么一个场景,王者荣耀有个聊天室,很多人在里面发各种消息(有吹水的,有发红包的,有拉人的等等),我们就可以把这些消息当作一个个的SOME/IP消息包,这时候我们准备搞个5排,但是少了一个人,于是我们也往这个聊天室发了一个组队消息,告诉别人,我们现在有一个车队,全是王者以上的,你们可以来玩,有人想玩高端局的话,他就点击进去了,然后你们就跟这个人一起玩了一把(建立交流),这个发布组队的包的消息就可以理解为SD协议的其中一个功能。SOME/IP基础协议的通讯支持TCP/UDP两种方式,而SOME/IP-SD协议仅支持UDP通讯。通信层级模型如下所示

知识总图:

SOME/IP-SD协议格式

SOME/IP-SD协议报文格式如下图所示

报文头

SOME/IP-SD协议的报文头格式与基础协议一致,区别就是MessageID为固定的0xFFFF8100, 其中ServiceID为0xFFFF, MethodID为0x8100。其余值分别定义如下: Protocol Version = 0x1 Interface Version = 0x1 Message Type = 0x2 Return Code = 0x0

基础协议这部分的内容介绍完成后,接下来是SOME/IP-SD的报文内容,SD的报文属于payload这部分.首个字节是Flags, Flags标记位占一个字节的长度,bit0代表客户端重启的flag, bit1代表当前SD是否使用单播方式通信(这个值已经废弃,只是为了兼容之前的版本所以保留),bit2代表当前ECU是否支持显式的初始化数据控制.

Flags后的三个字节用来预留。

Length of Entries Array:占4个字节的长度,用来表示实体数组的字节数。

SOME/IP-SD Entry: SD报文实体,主要用来同步服务实例的状态以及发布/订阅的实现,实体类型分为两种,服务实体(Service Entry)与事件组实体(Eventgroup Entry),

服务实体

主要用来传输ECU所包括的服务信息,在报文中的格式如下所示 Type分三种,分别为FindService(0x00), OfferService(0x01), StopOfferService(0x01) Index 1st options: 首配置项的下标(对应Options Array数组中的下标) Index 2nd options: 第二配置项的下标(对应Options Array数组中的下标) Number of Options 1: 首位配置项数 Number of Options 2: 第二配置项数 Service ID: 关联的服务ID Instance ID : 关联的实例ID Major Version: 服务的主版本号 TTL:实体的生命周期,单位是秒 Minor Version: 服务的小版本号

对照Wireshark中的报文结构看更加清晰,如下是ECU发送一条OfferService的SD报文

SOME/IP 报文头

SOME/IP-SD报文

事件组实体

事件组实体的SD报文格式与服务的实体报文格式有一定的区别,事件组的报文格式如下: 事件组实体的Type分为订阅Subscribe(0x6), 停止订阅StopSubscribeEventgroup(0x6), 订阅成功ack SubscribeACK(0x7), 以及订阅异常的NACK(0x7) Index 1st options, Index 2nd options, # of opt 1, # of opt 2, Service ID, , InstanceID, Major Version, TTL 如上的值代表的意义同服务实体中的意义是一样的。

Initial Data Requested Flag : 该值如果为1,则表示服务端在客户端订阅成功的时候需要触发一次事件发布。 Counter : 用于区分同一订阅服务器的相同订阅事件组。如果未使用,则设置为0x0 Eventgroup ID : 事件组ID

配置项

配置项的主要作用是用来传输一些实体的额外信息,如IP地址,通信端口号,通信协议等。主要有如下几类配置项: Configuration Option: 可以理解为配置类的配置项,数据的格式类似DNS TXT或者DNS-SD。 Load Balancing Option: 负载均衡配置,这个配置项配置服务的优先级,权重等信息,客户端可以根据这个配置来选择与对应的服务交互。 IPv4 Endpoint Option: IPv4通讯配置,这个配置项包含了通信所需的IP地址,通讯方式(UDP/TCP),以及发送方的端口号。 IPv6 Endpoint Option: IPv6通讯配置,这个配置项包含了通信所需的IP地址,传输层协议(UDP/TCP),以及发送方的端口号。 IPv4 Multicast Option: IPv4组播配置项 IPv6 Multicast Option: IPv6组播配置项 IPv4 SD Endpoint Option: IPv4 SD网络端点配置

IPv6 SD Endpoint Option: IPv6 SD网络端点配置

通信行为流程

启动阶段行为

每个SOME/IP应用都具备如下四个阶段:

Not Ready (未就绪)

Ready

Initial Wait Phase (已就绪初始化阶段)

Repetition Phase (已就绪重复阶段)

Main Phase (已就绪主阶段)

Not Ready:

客户端状态为此阶段服务未被应用,或者IP地址对应的网卡未就绪。服务端状态为Service不可用,或者无法提供Service实例,或者IP地址对应的网卡未就绪。

Ready in Initial Wait Phase: 初始化等待阶段是为了优化启动时多个ECU同时启动发送SD报文引起的流量高峰问题,以及允许各个ECU收集SD报文中的多个实体,此时的行为动作对应如下:

客户端等待INITIAL_DELAY的时间片段之后,发送首个Find Service SD报文服务端等待INITIAL_DELAY的时间片段之后,发送首个Offer Service SD报文

INITIAL_DELAY是一个随机值,协议栈需要定义一个范围,INITIAL_DELAY_MIN到INITIAL_DELAY_MAX,每次进入初始阶段的等待时间都是从这个范围内取的随机值

报文发送完成之后进入重复阶段。

Ready in Repetition Phase: 重复阶段设计的目的主要是为了快速同步客户端与服务端的状态。因为车上的ECU不可能事同时启动,肯定有先后,重复阶段的目的就是加快两者之间互相发现的效率。并且重复阶段以指数级增加的方式去增加消息发送的间隔时间,以避免过载情况使系统无法同步。重复阶段对应的动作如下:

客户端重复发送FindService报文,间隔时间为2^(REPETITIONS_MAX - 1) * REPETITIONS_BASE_DEDAY,发送最大次数为REPETITIONS_MAX,如果在重复阶段有收到Offer Service报文,立即进入Main Phase 服务端重复发送OfferService报文,间隔时间为2^(REPETITIONS_MAX - 1) * REPETITIONS_BASE_DEDAY,发送最大次数为REPETITIONS_MAX,如果收到客户端的FindService报文,则延迟一定时间(REQUEST_RESPONSE_DELAY)后,发送单播OfferService给客户端

Ready in Main Phase: 主阶段SOME/IP-SD尝试进入稳定状态,各类包的发送频率都有大幅减少

客户端停止周期性发送FindService报文,在收到OfferService事,发送subscribeEventgroup报文服务端将以CYCLIC_OFFER_DELAY定义的值来周期性发送OfferService报文

关机行为

服务端服务实例在重复阶段或者主阶段停止时,需要发送StopOfferService实体报文任意阶段检测到网络链路不可用时,进入Not Ready阶段任意阶段检测到网络链路状态变化时,如果链路可用并且服务依旧是有效状态,则服务端对应进入初始化等待阶段。任意阶段检测到网络链路状态变化时,如果链路可用并且服务依旧已被请求,则客户端对应进入初始化等待阶段。服务端发送StopOfferService实体报文后,所有服务实例中的相关事件订阅需要全部删除。客户端收到StopOfferService报文后,所有该服务实例相关的订阅需要全部删除。客户端收到StopOfferService报文后,不再发送Find Service实体。当处于主阶段的客户端服务实例停止后,SD模块需要发送StopSubscribeEventgroup实体报文。当ECU关机时,需要发送StopOfferService与StopSubscribeEventgroup报文。

行为时序

客户端网络链路状态变更时发布/订阅流程 双Client端订阅/发布时序 服务端网络链路状态发生变更时的发布/订阅流程

总结

了解了SOME/IP的协议基础就相当于掌握了基本的内功,但是光有内功还是不行,还得有招式,就像张无忌学了九阳神功之后,打架还是菜鸟,九阳只是内功,真正打架的还是招式,SOME/IP应用的招式就是vsomeip, 这是一个GENIVI开源的协议栈

下一篇,我将修炼vsomeip中的招式来在车载以太网中打出自己的一招一拳。

文章链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: