浅谈SomeIP以及在AutoSAR中的运用

SomeIP的由来
(以下文章来源于Vehicle软件开发 ,作者Vehicle软件开发)
随着汽车智能化和网络化的发展,汽车自动驾驶、车载娱乐、远程诊断升级等新技术对车载通信提出了更高的要求。如何将现有的以太网技术运用到汽车领域是我们面临的一大挑战。而在汽车领域长期都是CAN通信占据主导地位,在汽车中如何找到一种像CAN、MOST一样通信方式,同时支持现有的TCP、UPD协议,又具有网络通信的单播协议,有限制的使用多播和广播通信,加强对以太网的重用性,充分利用以太网传输数据多,安全性高等特点,开发一种合适的中间来满足上面的要求是不容易的,而SomeIP的诞生成功的将以太网通信作为一种中间件成功运用到了车载通信领域。

SomeIP 简介

SomeIP (Scalable service-Oriented Middlewareover IP) 是车载以太网的一种通信协议。对于熟悉CAN通信的开发者而言,CAN通信一般属于周期或者触发的形式在总线上传输的,而SOMEIP则不同,它是在接收方有需求的时候才发送,他是一种以服务为导向的数据通信方式。

SomeIP通信协议基于以太网通信协议传输,在一帧以太网数据中的位置如下所示
在这里插入图片描述
SomeIP数据包主要包括两大部分,分别是Header和Data。在传输的过程中可以通过TCP和UDP两种通信数据协议进行传输。SomeIP定义的通信方式主要包括四大类。分别是:

  1. Methods:Methods包含了请求后有应答的Method,和请求后没有应答的Method(Fire&Forget)。

  2. Event:当某种事情发生后,服务端向客户端发送的Message。

  3. Field:Get/Set/Notifier某种属性或者状态。

  4. EventGroup:用来进行publish/subscribe处理Eventsand Fields的通信的逻辑组。

其中SomeIP中与数据通信相关的几个术语如下:

  1. Request/Response:客户端向服务端请求特定的报文,然后服务端将相应的数据报文返回给客户端。

  2. Fire&Forget:客户端调用服务端方法的报文,通过请求完成方法远程调用;

  3. Notification:对应Event接口类型,类似CAN报文,在特定的事件触发下,服务端会发给客户端一个notification报文主要包括Cyclic事件、数据Changed等

  4. Publish/Subscribe概念:主要用于SomeIP的SD(服务发现),客户端首先订阅相关的服务,只有订阅成功后,才允许进行Notification通信。

  5. Field:一个可被远程访问的属性。主要包含三种类型的数据通信Getter、Setter和Notifier。其中Getter读取属性值,请求报文的payload为空,响应报文中含有当前属性值;Setter设置属性值,将预设值置于请求报文的payload中,属性的设置结果放于响应报文中,Notifier类似于Event,Notifier在订阅完成后,会立即发送InitialEvent,通知当前值。

SomeIP面向服务的通信机制分两类:分别是请求应答类和提交订阅类。其中请求应答类型的数据主要包括 Fire&Forget通信,Method、Getter、Setter类型的数据通信;而提交订阅类通信主要包括Event和Field中的Notifier。

Method通信

分为有应答的通信Request&Response和无应答的Fire&Forget通信

Request&Response:
在这里插入图片描述
Fire&Forget:
在这里插入图片描述
Field通信

主要包括三种类型,Set、Get、Notifier。其中Set和Get是客户端向服务器发送的一种请求通信,而Notifier是订阅后,服务端的通知。

Set/Get:
在这里插入图片描述
Notifier:
在这里插入图片描述
事件通知

由client向server订阅服务内容,然后server向client自动发布服务内容。
在这里插入图片描述
Notification分为Event和Field两类,这两类通知都需要首先使用SoemIP-SD(ServiceDiscovery)来进行服务订阅,然后才能发布通知。区别在于,Event是仅仅是某个事件的发生,只是事件通知,Event没有初始值,同时Event的生命周期没有定义,而Field除了事件通知之外,还具有Getter和Setter的功能,即对信息进行读写的操作,同时带有初始化的事件仅仅在Field中。
在这里插入图片描述
SomeIP协议的Header主要包括Message ID (32bit)、Length(32bit)、RequestID(32bit)、ProtocolVersion(8bit)、InterfaceVesion(8bit)、MessageType(8bit)、ReturnCode(8bit)。其中Message ID类似CANID主要用于区分不同的服务和服务接口,其中分为16bit的ServiceID和16bit的MethodID,其中MethodID的最高位为0表示的是Method最高为为1表示的是Event或者Notifier。在SomeIP中由于可以支持多种不同的数据通信,因此可以通过MethodID的最高位来判断具体的通信方式。Length(32bit)表示Request ID至Payload的字节长度;RequestID(32bit)用来响应特定的数据请求和发送,主要包括Client ID用来区分特定的车载ECU的客户端,在整车系统中该值必须唯一,SessionID主要对于Request和Response类型的通信协议的多次调用,每调用一次,sessionID增加1,在其他类型的数据通信中可以根据需要进行选择性使用;ProtocolVersion,表明当前的SOMEIP协议版本信息,当前为0x01;InterfaceVersion表明服务接口主版本信息;Message Type表明具体的通信类型;ReturnCode: 主要用来指明通信中的相关错误的信息。

SomeIP数据域

SomeIP的数据部分,用来表明具体的传输数据,对于UDP协议而言:SomeIPHeader +payload ≤1416Byte,对于TCP而言分段传输下SomeIP Header +payload≤4095 而UDP TP Payload可达4G大小。

SomeIP的序列化

SomeIP的数据在通信的过程中都会放在对应的数据payload中,但是在数据协议中对于结构体、数据、联合体等不同类型的数据在SomeIP传输中必须按照一定的规则定义成相应的二进制数据流,这个就是SomeIP的序列化操作,在数据的接收端按照相应的规则将二进制的数据流按照同样的规则解析成与发送端一样的实际的数据类型,比如结构体、数组等这个过程就是反序列化操作。

序列化与反序列化的应用主要在AutoSAR中满足整个软件架构的定义。数据在AutoSAR的定义一般都是用PDU的形式存在的定义了一组大小可以配置的数据。典型的应用就是CAN通信,一般一个PDU代表了一帧报文,一般8个字节或者CANFD中64个字节。同样在以太网通信中数据从PDUR到COM层也是基于PDU来传输的。在COM层的数据也是以单个的信号进行数据传输的,因此在序列化过程中要在数据到COM层之前将SomeIP传输的复杂的数据类型通过序列化的操作解析成单个的数据信号,并按照定义的位置和大小映射到具体的PDU中特定的位置,此时在PDU上就是一个个的紧密排列的信号,而在COM层中直接对具体的信号操作便会在PDU中更新特定位置特定长度的信号。而接收的时候,PDU中的信号会在COM层更新到特定位置特定长度的对应的信号,然后在RTE层根据数据的反序列化操作经SomeIP传递的数据进行整合,在APP层实现对一个结构体、数据或者单独一个信号的操作,从而完成数据的传输。在AutoSAR中的传输示意图如下所示
在这里插入图片描述
SomeIP-SD为服务发现,可以被当作SomeIP的一种特殊服务,client可以远程调用Server提供的服务,或者订阅Server发布的内容,那么client是怎么知道Server提供哪些服务呢?就是通过SomeIP-SD来实现服务发现过程的。在SomeIP传输过程中主要用来提供和发现有效的服务,并提交和订阅特定的服务实例,实现SomeIP数据的传输。下面是SomeIP的数据帧定义
在这里插入图片描述
SomeIP SD主要是通过UDP进行数据传输的,对于特定的SomeIP的Header,SD有明确的定义,其中MessageID固定为0xFFFF8100;ClientID一般固定为0x0000;InterfaceVersion为0x01;Message type固定为0x02;SessionID在初始化配置为0x0001,在没发送一次数据后便加1;ProtocolVersion为0x01;Flag主要包括RebootFlag和UnicastFlag,用于向全局服务发现信息发送信号,其中包括最近一次Reboot的当前状态以及接收单播消息的能力,同时基于单播传输可以检测Reboot,UnicastFlag设置为1可以接收UnicastMessage。Reserved field为空,当前不需要考虑;EntriesArray分为两类,分别是Service和EventGroup。其中ServiceEntry主要是用于Find或者Offer特定的服务包括Find、Offer、StopService三种类型的操作,EventGroup Entry主要用来提交或者订阅特定的服务事件。其中ServiceEntry三种服务支持多播传输,OfferSevice也可以单播传输,EventGroupEntry只支持单播传输。Option类型主要是Entry的附属信息,主要包括:1.配置信息,可以用来配置服务的名称等;2.在Offer服务中定义服务的优先级;3.声明服务实例(offer引用,Request的目的地址,表明使用它所服务的终端地址)或者订阅端(SubscribeEventgroup引用,Request的源地址)的IP、端口号、传输协议等;4.声明服务端发送多播协议数据传达的终端的IP、端口号等,只能被SubscribeEventgroupAckEntry引用;5.声明发送SD信息的IP、端口号、传输协议,接收端使用该地址代替源地址等。

SD的数据通信一般分为发现服务、订阅事件组、接收事件,其中发现服务和订阅事件组需要SD完成,接收或者通知事件由SomeIP直接完成。主要的通信流程如下所示

在这里插入图片描述

AutoSAR中SomeIP的实现

SomeIP在AutoSAR中的实现主要包括与SD相关的配置和数据通信协议相关模块的配置。在SD中相互关联的模块主要是SoAd、SD、BSWM三个主要模块,而SoAd下层的模块基本与Eth的通用配置一样,根据需要定义相关的UPD和TCP协议即可。如果采用了像Preevision等SomeIP数据描述文件相关的工具定义好系统描述文件导入到AutoSAR工程中就可以,该部分与CAN的DBC导入原理类似,导入相应的系统描述文件会生成相应的模块,然后根据需要修改即可。对于SD而言,导入相应的SomeIP系统描述文件会生成相应的PDU以及跟SD相关的Service、EventGroup、Method等。对于SD而言根据导入的文件修改相关的配置即可。而对于数据通信相关的配置,由于本人没有做过导入现在还没有查看具体的内容。下面主要介绍下在没有系统描述文件过程中自己对SomeIPSD的实现。

SD模块配置

在SD模块中主要定义该节点是作为Client还是Server端使用,在SD中主要的定义的配置选项如下所示

在这里插入图片描述

其中General的配置主要包括了定义一些SD的主函数的周期,以及部分API的使能,在使用的时候根据需要选择即可。SdInstanceUnicastRxPdu定义了接收单播PDU的参考,SdInstanceMulticastRxPdu定义了接收多播的PDU、SdInstanceTxPdu定义了发送数据的PDU参考,对于定义的这三个全局的PDU需要且在SoAd模块将该PDU与特定的Socket进行关联,建立起PDU与特定的IP和Port之间的交互,实现Socket数据与PDU数据的关联。

SdProvidedMethods中主要用于定义SdServerServiceActivationRef,关联到特定的SoAdroutingGroup在Server端来控制**或者禁用相应的Method。

SdConsumedMethods中主要用于定义 SdClientServiceActivationRef关联到特定的SoAdroutingGroup在Client端来控制**或者禁用相应的Method。

Config中主要定义如下所示,主要是下边标记的一般主要考虑,用于在订阅EventGroup没有ACK下继续尝试订阅的次数和每次的间隔。

在这里插入图片描述

SD 如果作为Server使用的时候,配置的参数主要如下所示,其中SdServerTimerd定义了在SD通信过程中相关的时间参数,主要包括了OfferServer的周期时间、Server的存活时间等。TCP/UDPRef在SD层要将相应的服务关联到SoAd定义的数据Connection中,用来获得数据通信的TCP、UPD协议,建立起LocalIP与EndPoint的绑定。其中有两个主要的ID需要区分,SdServerServiceHandleId用于BswM控制相关的状态变换,而SdServerServiceInstanceId指明了特定的服务ID,用来提供相应的服务。

在这里插入图片描述

SD Client的定义与Server基本相似,这里就不做介绍,具体的配置内容可以参考相应的AutoSAR标准。

在这里插入图片描述

SD定义了相应的EventGroup,只有在服务端定义的服务可以被客户端消费,每次客户端使用相应的服务的时候必须进行订阅特定的EventGroup,订阅成功后,服务端才会提供特定的Event供客户端使用。具体的配置参数如下,其中SdConsumedEventGroupHandleId用作BswM进行控制,而SdConsumedEventGroupId表明特定的ID,用来区分订阅和提供不同的实例,每个SdConsumedEventGroupId包含了多个不同的Event,一旦订阅成功,内部的Event可以通知。对于相关的TCP/UDPRef同样是关联到SoAd中定义的RoutingGroup用来**接收相应的Event,同时也会用于得到对应的IP地址和Port用于绑定Subscribe EventGroup Entry中的Endpoint。

在这里插入图片描述

SD EventHandler作为一个服务实体的EventGroup存在。其中SdEventHandlerEventGroupId 用来标识特定的EventGroup,也就是提供给订阅者使用的特定事件组,而SdEventHandlerHandleId主要用于被BswM模块进行状态控制使用。对于SdEventActivationRef关联到SoAdRoutingGroup用来控制**与否,**后在订阅后,才可以提供特定的Event。SdEventTriggeringRef用于触发事件的发送。SdMulticastEventSoConRef主要将其关联到特定的组播连接中,将特定的PDU数据与多播的Socket进行连接。

在这里插入图片描述

在SD中主要配置所用的Instance以及对应的EventGroup和Method。同时SD与BSWM建立了对应的控制逻辑。通过BSWM定义相关的参考,APP通过BSWM的接口可以控制SD中的Instanc、EventGroup的Request和Release。根据需要先定义Instance也就是一个特定的服务,然后定义该服务内部的EventGroup,剩下的就是根据相应的SD数据头定义相关的参数即可。其中在SD通信过程中有相关的状态变换的时间参数,根据实际的需要定义即可。在SD中主要定义三个传输数据用的PDU用于和SoAd模块进行数据的交互,其中一个Tx、一个UnicastRx、一个MulticastRx,所有这些PDU都用于SD和SoAd之间的数据交互,用于SomeIPSD端数据的接收和发送,根据SD数据通信中Offer/Find/StopService以及Supscribe/Provice EventGroup等进行具体的选择,同时在SD层要将相应的服务关联到SoAd定义的数据Connection中,用来获得数据通信的TCP、UPD协议,建立起LocalIP与EndPoint的绑定。一旦发现服务,订阅EventGroup成功后,客户端便可以接收服务端发来的事件通知。

SoAd配置

SoAd主要将以太网传输的Socket与PDU进行关联。在SomeIP的配置中主要有以下参数
在这里插入图片描述

SoAdBswModules用来指定SoAd对于UL(Upper Layer)层的模块,对于SD相关的Socket与PDU的交互UL主要是SD模块,而对于普通的不需要SD介入的SomeIP操作只需要定义为PDUR就可以可,在PDUR层将数据传输到COM层,这一点与CAN基本一致。SoAdSocketConnectionGroup定义特定的连接,将本地IP、Port与远端的IP和Port关联在一起。每一个Connection都关联到有特定的TCP、UDP中,一方面用来控制以太网通信中TCP、UDP连接的打开还是关闭,另一方面定义了TCP、UDP数据如何被接收和发送。SoAdSocketRoute定义了Socket的路由Socket来源,并关联到SocketConnection中,SoAdSocketRouteDest定义了Socket UL层的PDU的目的地址,将UL层的PDU与Socket进行关联,实现了将Socket数据解析成PDU数据,实现了数据的接收。SoAdPduRoute定义了UL层的PDU来源,SoAdPduRouteDest定义了UL层的PDU的目的地址,并且关联到了Socket Connection和RoutingGroup 中,实现了UL层PDU与Socket的关联,实现了PDU数据的发送。SoAdRoutingGroup包含了多个PDU,可以实现对PDU的使能和禁用,同时实现了UL层PDU到TCP/UDP Socket的数据传递。

SomeIP数据通信

对于SomeIP中非SD相关的数据操作,在SoAd中将接收和发送的PDU关联到PDUR中即可,通过在PDUR中将SoAd参考的PDU通过PDUR关联到COM层,从而实现以太网数据在COM层的解析。如果采用相关的配置工具配置SomeIP的数据通信矩阵,导入到AutoSAR工具中,根据配置手册对SoAd以及PDUR、COM等模块的修改,达到对SomeIP数据通信的要求即可。除了前面提到的Event和Field中的Notifier外,其它的数据通信方式都可以不需要SD。但是在使用中要注意SomeIP的序列化和反序列化操作即可。如果没有相关的工具来配置SomeIP的数据通信矩阵也是可以实现的,但是比较麻烦,本人在测试中就模仿了CAN的数据通信,自己定义了以太网的数据PDU,定义信号在PDU的位置和长度,可以直接在APP解析以太网的数据,但是这样问题比较多,实现起来遇到复杂的逻辑很难处理,最好定义好SomeIP的通信矩阵,然后导入到工具中使用比较好。