分享

车载以太网最少必要知识之SOME/IP

 Neal199 2024-03-30 发布于安徽

这是《车载以太网最少必要知识》系列之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。将其折叠,我们大致可以拿到七个方面的信息。其中,

  • · Clusters定义了以太网的基本信息,如波特率100M/s、最大数据位长度1500bytes;

  • · ECUs定义了网络结构里包含的ECU,并给出了每个ECU的基本信息,如IP地址、端口号、SD参数;

  • · Service Interfaces里定义了网络里可见的服务,并给出了每个服务(Service)具体的信息,如服务的名称、服务的ID、服务里所包含的Methods、Events、Fields、Eventgroups等;

  • · Datatypes里定义了通用的和自定义的数据类型,比如Uint8、Struct;

  • · Codings里定义了数据的映射关系,即不同数值所对应的含义,比如1表示start,0表示stop。

图片

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,它的身份并不是固定的。也许在某个服务里,它是生产者,但是在另一个服务里它就变成了消费者。

生产者和消费者的交互方式,可以用以下三种情况来表示。即,

  1. 1. 消费者向生产者发出请求(Request),生产者未发出响应(Response);

  2. 2. 消费者向生产者发出请求,生产者向消费者发出响应;

  3. 3. 生产者主动向消费者发出请求(也可以理解成在没有请求时自发的响应)。

图片


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(通知)。

回到官方协议里对服务的定义:服务由若干个方法、若干个事件和若干个字段构成,于是我们可以画出下边这张图。

A logical combination of zero or more methods, zero or more events, and zero or more fields.

图片

另外事件和Notifier又可以组合成事件组(Eventgroup),以便发布(Publish)和订阅(Subscribe)。

A logical grouping of events and notification events of fields inside a service in order to allow subscription.

最后,实现服务的是具体的实例(Service Instance),同一个服务可以对应多个实例。

Software implementation of the service interface, which can exist more than once in the vehicle and more than once on an ECU.

不难看出,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的信息格式,如下图所示。其中,

图片

  • · Message ID指明了服务和服务里具体的元素(Service Elements),元素包括Methods和Events。官方推荐对他们分开编号,不过在本示例中并没有按照这个方式来。

图片

  • · Length指明了从Request ID开始直至末尾的总长度。

  • · Request ID用来区分针对Methods(包含Getter和Setter)的并行调用。不同的消费者以Client ID来区分;同一个消费者不同时序的调用以Session ID来区分。其中Session ID从1开始计数,直到超过最大值2^16-1时复位为1。不难看出,Request ID不适用于Events(包含Notifier)。

  • 图片

  • · Protocol ID指明SOME/IP Header format的版本,默认是1。

  • · Interface Version指明了该服务接口(Service Interface)的大版本(Major Version)。服务接口指的是记录所有服务的规格书,它的版本由大版本和小版本(Minor Version)构成。

    Service Interface: the formal specification of the service including its methods, events, and fields.
  • · Message Type指明该SOME/IP Message是什么类型,有以下几种:

    • · 0x00, Request, 与Response构成一对;

    • · 0x80, Response;

    • · 0x01, Request_No_Return, 即Fire&Forget;

    • · 0x02, Notification, 涵盖了Notifier和Event,无需Response的Request

    • · 0x81, Error, 携带错误信息的Response。

  • · Return Code,用来给对应的Request做反馈。不难理解,Response里才需要填写Return Code。不过为了统一格式,所有Request——包括Request、Fire&Forget和Notification,都把Return Code默认设置为0x00。更多关于Return Code的选项及解释,请参考官方文档【1】。

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就会变更位置。


  // Property: CurrentPosition
  mstimer     tPosition;
  const dword kPositionCycle = 1300// update cycle for changing position  
}

on timer tPosition
{
  $Position::longitude += 10;
  $Position::latitude += 100;
  $Position::altitude = $Position::altitude - 1 + random(3);

  setTimer(tPosition, kPositionCycle);
}

因此我们预期每隔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 ArrayOption Array。这里我们跳过对Flag的解释,直接介绍Entry和Option这两个概念。

5.1.1 Entry Array

Entry又细分为两大类,Service EntryEventgroup Entry。顾名思义,Service Entry专门负责处理服务,Eventgroup Entry专门负责处理事件(需要注意的是,事件其实也是服务的一部分)。不同的Entry采用不同的格式,且支持不同的功能。

5.1.1.1 Service Entry

Service Entry的格式如下,其中,

图片

  • · Type指定了Entry的功能类型,如:

    • · 0x00, 寻找服务(Find Service),当状态机里没有可用的服务时发出该信息(比如因为服务超时,或者生产者未提供该服务);

    • · 0x01, 提供服务(Offer Service),当生产者准备好了某项服务时发出该信息,并指定服务的有效期TTL,比如3s;

    • · 0x01, 停止服务(Stop Service),当生产者不再提供某项服务时,发出该信息,指定TTL=0表示停服。

5.1.1.2 Eventgroup Entry

Eventgroup Entry的格式如下,其中,

图片

  • · Type指定了Entry的功能类型,如:

    • · 0x06, 订阅事件(Subscribe Eventgroup),只要某个消费者保持对某项服务的热情,那当它看到该服务的发布消息时,就会持续订阅;

      as long as the client is still interested in receiving the notifications/events of this eventgroup.
    • · 0x06, 停止订阅(Stop Subscribe Eventgroup),其中TTL需要设置为0,进而与订阅事件进行区分;

    • · 0x07, 订阅成功应答(SubscribeAck),表示订阅成功;

    • · 0x07, 订阅失败应答(SubscribeEventgroupNACK), 表示订阅失败,其中TTL需要设置为0,进而与订阅成功应答进行区分。

5.1.2 Option Array

Options是对Entry的补充,提供额外的信息。

Options are used to transport additional information to the entries.

官方协议里【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,那么下边这张图的含义是:

  1. 1. Entry 1、2、3共用了一条Option,该Option在Option Array的位置是0,即OptionArray[0];

  2. 2. Entry 1还有1条Option,对应OptionArray[1]

  3. 3. Entry 2还有2条Option,对应OptionArray[2]和OptionArray[3]

  4. 4. Entry 3还有1条Option,对应OptionArray[4]。

图片

5.2 服务场景

了解了SOME/IP-SD Message的格式,我们再来具体看看服务的场景和报文。

5.2.1 寻找服务

刚启动完毕,Head Unit广播寻找服务。该信息里包含了3条Find Service Entry,把3条放在一起主要是为了提高效率。

The service discovery shall support multiple entries that are combined in one service discovery message.

图片


等到服务的生产者都准备就绪,且向外持续广播自己的服务,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】。在基于信号的方式里,但凡信号更新或者变化,该信号就会被传递;但在基于服务的方式里,只有当消费者需要时,生产者才会传递。更重要的是,在面向服务的通讯架构里,新的软件单元可以很容易就被集成进来,而不造成兼容性问题。

Powered by Ethernet and SOME/IP, SOA models the entire system as service interfaces. New software can be easily added to the system without worrying about the compatibility with others.

以上便是本篇文章的全部内容,更多细节诸如数据系列化(Data Serialization)、数据结构(Datatypes)和SD状态机(State Machines)等请参看官方协议。

[1]https://www./fileadmin/standards/R22-11/FO/AUTOSAR_PRS_SOMEIPProtocol.pdf 
[2]https://www.autosar.org/fileadmin/standards/R22-11/FO/AUTOSAR_PRS_SOMEIPServiceDiscoveryProtocol.pdf
[3]https://www./blog/embedded-blog/how-some-ip-enables-service-oriented-architecture-in-ecu-network 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多