这是《车载以太网最少必要知识》系列之SOME/IP。SOME/IP的全称是Service-Oriented Middleware over IP,它是基于IP通讯的,为面向服务的通讯架构(SOA)而设计的中间件。 阅读该篇文章,我们将对SOME/IP的网络结构、通讯方式、Service Discovery机制建立最少且必要的了解。 1. 参考资料本篇文章用到的参考资料主要有三个。其中AUTOSAR_PRS_SOMEIPProtocol.pdf【1】和AUTOSAR_PRS_SOMEIPServiceDiscoveryProtocol.pdf【2】可以从AUTOSAR官网下载。第三个是CANoe仿真SOMEIPSimMultimedia,安装CANoe程序后,在Sample Configuration里可以找到。后续的介绍中,我们将基于该仿真,来逐步解析上述两份协议文档里的新概念。 之所以把参考资料写在前面,是为了方便有条件的读者提前翻阅,进而更好地使用本篇文章。 2. SOME/IP网络结构示例不管是什么样的通讯方式,它最终都是为了让ECU互相之间能够传递信息。在CAN网络里,CAN Matrix定义了CAN的网络结构;类似地,在SOME/IP里,XML文件定义了它的网络结构。 2.1 XML配置文件从仿真的Database文件夹里,我们找到了配置文件FBX4_VECTOR_SOME_IP_MM.xml。将其折叠,我们大致可以拿到七个方面的信息。其中,
2.2 服务表尽管XML配置文件里的信息非常完备,但理解它并不直观。为此,我们将它转化成了下面这张服务表(这是笔者自己的叫法,非官方)。不难看出,一个交换机连接了四个ECU,分别是:Head Unit——汽车里的中控、CD Changer——播放CD的卡盒、GPS Unit——车载GPS和TVReceiver——电视节目接收器。 进一步,这四个ECU都标注了NEP和AEP。NEP(Network Endpoint)其实是ECU的IP地址,比如192.168.1.10;而AEP(Application Endpoint)其实是Socket地址,比如192.168.1.10:30500。 再进一步,每个ECU都声明了自己所提供的服务(Provided Service)以及该服务的ID(Service ID),比如CD Changer提供名为CD Player的服务,它的ID是10。 最后,每个服务里又包含了子服务,分为Methods、Fields、Events和Eventgroups。其中有些子服务被标记为了x,表示该服务里不提供该子服务(子服务,和x的标记方式也是笔者自己的方法,非官方)。 有了这张服务表,我们便可以清楚地知道谁提供了什么样的服务。在接下来的介绍中,我们需要时不时地回到这张表进行查看。需要注意的是,这其实是一张简化了的服务表,比如Head Unit并没有提供任何服务。真实的车载网络里肯定要比这个复杂的多的多。 3. SOME/IP基础概念解析上述服务表里涉及了很多的新概念,接下来我们逐一解释下。 3.1 生产者和消费者所有的商品都对应着一个制造它的人和消费它的人,类似地,所有的服务都有生产者(Producer)和消费者(Consumer)。有时候我们也把生产者称之为服务端(Server)或者提供者(Provider),把消费者称之为客户端(Client)或者订阅者(Subscriber)。本篇文章里我们统一使用生产者和消费者的说法。对于每个ECU,它的身份并不是固定的。也许在某个服务里,它是生产者,但是在另一个服务里它就变成了消费者。 生产者和消费者的交互方式,可以用以下三种情况来表示。即,
3.2 概念释义交互的方式有且仅有以上三种,因此,在SOME/IP的官方协议里,方法(Methods)被定义为可被调用的(can be invoked/called)对象,包含Request和Request/Response两种方式。只不过,Request有一个更高级的名字Fire and Forget;Request/Response也有一个更高级的名字RPC(Remote Procedure Call)。而事件(Events)被定义为从生产者向消费者的单向传输。 有时候交互不涉及修改状态(Status),它更像指令,比如Head Unit告诉TVReceiver开启电视信号。但有时候修改状态却是必不可少的,比如Head Unit告诉CD Changer播放第四首歌曲,这里的第几首歌曲就是一种状态。类似这种涉及状态的交互,在SOME/IP里被称为字段(Fields)。字段与前述交互方式二相结合,就得到了Getter(获取状态),Setter(设置状态);与交互方式三相结合,就得到了Notifier(通知)。 回到官方协议里对服务的定义:服务由若干个方法、若干个事件和若干个字段构成,于是我们可以画出下边这张图。
另外事件和Notifier又可以组合成事件组(Eventgroup),以便发布(Publish)和订阅(Subscribe)。
最后,实现服务的是具体的实例(Service Instance),同一个服务可以对应多个实例。
不难看出,Getter和Setter实际上是从属于Methods的,而Notifier是Events的子类。不过为了与官方协议保持统一,对于具体的子服务,本文也将使用Method、Getter、Setter、Event、Notifier和Eventgroup等叫法。 4. 场景示例与SOME/IP信息格式了解了SOME/IP里的基础概念,以及这些概念之间的关系,我们便可以回到具体的功能场景里。仿真的场景即可以加深对这些概念的理解,也可以帮助理解SOME/IP的信息格式(SOME/IP Message Format)。 4.1 SOME/IP信息格式介绍具体的功能场景之前,我们先大致了解下SOME/IP的信息格式,如下图所示。其中,
4.2 场景-Method查看2.2章节里的服务表,我们知道TVReceiver支持两个子服务,开始和停止电视节目,它们都不涉及修改状态。 借用仿真工程,模拟Head Unit请求开启电视节目,截取报文如下。Head Unit从AEP 192.168.1.10:30500向TVReceiver的AEP 192.168.1.13:30502发送Start请求。该Start请求旨在调用编号为21的Method,它归属于Service TVReceiver,Service的ID是12。 收到请求后,TVReceiver做出了正反馈,报文如下。 4.3 场景-Getter在CD Changer提供的服务里,有一个字段AudioDiskInfo支持Getter方法。它的功能是查看唱片机里的磁带(disk)信息,比如有哪几首歌曲,排序是怎么样的。这些信息不可更改,且没有必要实时查看,故设定为Getter最合适。 借用仿真工程,我们模拟Head Unit请求磁带信息,截取报文如下。Head Unit从AEP 192.168.1.10:30500向CD Changer的AEP 192.168.1.11:30501发送Getter请求,并指定了服务ID为10,Method ID为31(对应Fields里的AuidioDiskInfo)。 收到请求后,CD Changer做出响应,报文如下。该响应包含了所有唱片的信息,且采用了结构体(Struct)的数据类型(Datatypes)。 4.4 场景-Setter同样是在CD Changer提供的服务里,我们还可以找到Setter,比如字段Active Disk。当然,除Setter方法外,该字段也支持Notifier。使用Setter,Head Unit就可以指定当前播放的曲目;而基于Notifier,曲目跳转的信息也会通知到Head Unit。 于是我们通过仿真工程,来触发Head Unit设定当前播放的曲目,截取报文如下。在步骤A里,我们设定当前曲目为第六首,在步骤B里我们又改为第二首。 对应步骤A里,唱片机的响应如下所示。 4.5 场景-Event在GPS Unit提供的服务里,我们仅找到了Event,名叫Position。为了能够实时获取GPS信息,Head Unit需要提前订阅GPS Unit的服务。订阅的过程我们放到5.2.3章节里展开。在这里,我们仅需知道,每当GPS信息有更新,GPS Unit就会把新的位置信息发送给Head Unit。 在GPS Unit节点的CAPL代码里, 可以看到GPS每隔1.3s就会变更位置。 { 因此我们预期每隔1.3s就会有Event信息发送给Head Unit。对比真实的报文,从A至E的确如此。再次提醒,Event没有相应的Response。 4.6 场景-Notifier回到CD Changer提供的服务里,我们可以找到很多Notifier。同Event一样,当信息发生变更时,生产者就会通知到订阅了这些事件的消费者。你可能会问,“为啥不把Fileds里单纯是Notifier的类型定义为Event呢”?我当前的理解是,也许将来这些Fields需要被扩展Getter或Setter。 仿真场景的报文如下。 5. SOME/IP-SD第四章节我们讲述了SOME/IP信息交互的场景,以及信息的格式。但有一个问题:ECU之间是怎么知道哪些服务可用的呢? 为了解决这个问题,SOME/IP额外补充了SOME/IP-SD,它的全称是Service-Oriented Middleware over IP - Service Discovery【2】。该协议定义了寻找服务(Find Service)、提供服务(Offer Service)、发布(Publish)和订阅(Subscribe)服务等过程。 SOME/IP Message与SOME/IP-SD Message最明显的区别在于,信息交互时使用的端口号(Port)不一样。下图中1指代SOME/IP-SD,不管是单播还是组播,用到的端口号都是30490。该端口号通常与参数SD-PORT绑定,30490为默认值。换句话说,这个端口是专门用来探索服务的(service discovery)。而图中2指代的是SOME/IP Message,用到的都是应用程序所使用的端口号,无论是TCP还是UDP。 5.1 SOME/IP-SD信息格式介绍服务的发布和订阅之前,我们先来看看SOME/IP-SD Message的格式。它其实是SOME/IP Message的一个子集,也可以说是特例。 Header部分的格式与SOME/IP-SD Message一致,只不过红色字体所代表的属性是固定的。SD的部分由两个Flags开始,Reboot和Unicast,之后便是Entry Array和Option Array。这里我们跳过对Flag的解释,直接介绍Entry和Option这两个概念。 5.1.1 Entry ArrayEntry又细分为两大类,Service Entry和Eventgroup Entry。顾名思义,Service Entry专门负责处理服务,Eventgroup Entry专门负责处理事件(需要注意的是,事件其实也是服务的一部分)。不同的Entry采用不同的格式,且支持不同的功能。 5.1.1.1 Service EntryService Entry的格式如下,其中,
5.1.1.2 Eventgroup EntryEventgroup Entry的格式如下,其中,
5.1.2 Option ArrayOptions是对Entry的补充,提供额外的信息。
官方协议里【2】定义了很多Options,比如Configuration、IPV4 Multicast、Load Balancing。这里我们仅拿IPV4 Endpoint Option作为示例。它的格式如下,很明显,它补充说明了对该服务感兴趣的AEP。 如前所述,SOME/IP-SD的沟通都是在端口30490进行的。为此这部分补充显得非常必要。服务的生产者可以声明“哪个Socket提供了这个服务”,而服务的消费者可以声明“哪个Socket想要用到这个服务”。 示例中,该Option声明:在192.168.1.12:30002这个AEP,可以找到名为Navigation的服务。 5.1.3 Option Index在SOME/IP-SD的信息格式里,Type之后还有一个部分叫Index,它为每条Entry指定了2组Options。我们假定某条SOME/IP-SD Message里有3条Entry和5条Option,那么下边这张图的含义是:
5.2 服务场景了解了SOME/IP-SD Message的格式,我们再来具体看看服务的场景和报文。 5.2.1 寻找服务刚启动完毕,Head Unit广播寻找服务。该信息里包含了3条Find Service Entry,把3条放在一起主要是为了提高效率。
等到服务的生产者都准备就绪,且向外持续广播自己的服务,Head Unit就不再需要寻找服务了。 5.2.2 提供或发布服务提供服务和发布服务都叫Offer Service。只不过,发布服务是针对Eventgoup的,因为只有事件(组)可以被订阅。下边的报文里,3个生产者分别广播了自己的服务。 仔细看你会发现,这些生产者每隔1秒就会发出报文,提供新的服务(主要是Session ID发生变化)。这其实是因为配置文件里规定了ANNOUNCE-CYCLIC-DELAY为1秒。 5.2.3 订阅服务与成功应答订阅服务意味着消费者对于生产者提供的事件信息持续感兴趣。不难发现,订阅的行为是持续不间断的。但凡消费者对该服务依旧需要,只要新的发布服务的报文发出,消费者就会立即订阅。因为先前订阅的服务都是有时效性的,比如示例中都设定为了3秒。 订阅成功应答的报文如下。 5.2.5 停止订阅当消费者不在需要某些服务时,它会发出停止订阅的报文。在仿真工程里,我们可以通过关停Head Unit来模拟停止订阅的行为,报文如下。 6. Why SOME/IP至此我们对SOME/IP的机制已经有了非常全面的了解。问题是,我们为什么需要这样的通讯机制呢? 首先,相比于传统的通讯方式比如CAN,以太网支持更快的传输速率。其次,这是由基于信号的通讯方式(Signal-based Communication)向基于服务的通讯方式(Service-based Communication)的转变【3】。在基于信号的方式里,但凡信号更新或者变化,该信号就会被传递;但在基于服务的方式里,只有当消费者需要时,生产者才会传递。更重要的是,在面向服务的通讯架构里,新的软件单元可以很容易就被集成进来,而不造成兼容性问题。
以上便是本篇文章的全部内容,更多细节诸如数据系列化(Data Serialization)、数据结构(Datatypes)和SD状态机(State Machines)等请参看官方协议。 [1]https://www./fileadmin/standards/R22-11/FO/AUTOSAR_PRS_SOMEIPProtocol.pdf |
|