• [MICROSAR Adaptive] --- Communication Management


    0 引言

    本期会介绍communicationmanagement通信管理,首先介绍它的特点使用方式,然后介绍模型中的相关元素和c++代码中的相关API,最后我们实现一个应用程序,他有两个Executable组成,一个是提供服务的provider,另一个是使用这个服务的consumer。
    在这里插入图片描述

    1 communication management通信管理的特点使用方式

    从一个adaptive application的视角来看,它能利用的接口可以分为三类,第一类是posix 51和c++标准库中的API;第二类是adaptive platform上的可以直接使用的API,如果要用到这类app 那么链接相应的库即可;第三类是要通过communication management即ara::com来间接使用的API。在adaptive platform 上,应用程序应当使用ara::com来通信并使用服务。服务可能是由用户的另一个应用程序提供的,也可能是由adaptive platform提供的。
    在这里插入图片描述

    1.1 ara::com简介

    提到通信,我们知道在物联网/机器人等领域,已经有多种通信API了,如DDS等。为什么在autoser adaptive platform上我们又要制定一个通信API的规范呢? ara::com有什么特点吗?
    首先,在API的设计,ara::com与底层通信协议解耦,他对some-ip协议有很好的支持,同时也有使用其他协议的灵活性;其次,他对事件驱动和轮循这两种风格都有良好的支持;另外,ara::com支持静态的和动态的服务 实例选择。在ara::com的设计中还考虑到了端到端保护等安全方面的需求。

    ara::com采用经典的Proxy/Skeleton模式,首先用某种IDL(接口描述语言)来描述一个服务,然后从这个描述生成service Skeleton和service Proxy。
    Skeleton在服务端使用,它是一个c++抽象类,我们继承这个类,使用它的成员函数,实现它里面的纯虚函数。
    Proxy在客户端使用,它是一个普通的c++类,我们组合这个类的对象,使用它的成员函数。

    1.2 port简介

    在建模的时候,想让software component和外界通信,我们就在他身上添加port。
    主要有两种port:pport和rport,分别用来提供服务和使用服务。在这里P代表provided,R代表required。就像编程语言中的变量有类型一样,port也有类型 称为PortInterface。PortInterface 是抽象的,我们实际上使用一些具体的类型。例如ServiceInterface/PersistencyInterface等等。

    PortInterface 就是对服务的接口的定义,不难看出这类元素起的就是IDL(接口描述语言)的作用,PortInterface有namespace,用于避免名字冲突。

    1.3 servicientface

    接下来我们看一种具体的portantface,也就是servicientface,一个servicentface就定义了一个service,也就是服务,他可以有一些Method/Event/Field, 也就是方法/事件/字段组成。
    在这里插入图片描述

    • method就是可以被远程调用的函数,和通常的rpc远程过程调用是一样的;
    • event是一种从服务端向客户端传递信息的机制,和通常的发布订阅模式是一样的;
    • field代表一个持续存在的值,客户端可以get/set这个值,或者subscribe这个值的变化 ,一个被配置为有getter setter和notify的field,其实就相当于两个method加上一个event。

    field在任意时刻都应当有具体的值,所以 显然field必须要有初始值,而event就没有初始值。我们用servicinterface定义了一个服务之后,可以有多个服务实例都提供这个服务。显然,每个服务实例应当具有某种特殊的id,让我们能区分他们,能精确的找到某个服务实例,这个id就是instanceidentify。在各种具体的通信中间件中都有这个概念。例如,some-ip使用一个16位无符号整数来区分服务的实例,而DDS则使用一个字符串来区分服务的实例。在代码中我们将服务实例id的细节封装在ara::com::instanceidentifier 类中,它里面包含的数据基本上就相当于一个字符串,使用的具体中间件不同,这个字符串的格式不同。

    在AUTOSRA adaptive Platform的方法论中,应用程序的开发者不应当关心instanceidentifier里的内容。因为使用哪种具体的中间件,是在部署阶段确定的。应用程序的开发者不应当对instanceidentifier的内容和格式做任何假设。应用开发者应当使用ara::com::instanceidentifier这个类,在本期我们很快就会在代码中接触到它。

    2 建模

    接下来开始建模,首先对数据类型进行建模,在的Davinci Developer Adaptive中创建一个新项目时,我们可以在选择导入文件的这一步,勾选copy autosar standard types into project。
    在这里插入图片描述
    这样一来,标准的c++基础数据类型就会被导入项目中,可以直接使用。这包括bool, float, double以及一些固定宽度的整数类型。在dashboard中找到data type editor,我们可以在这里对各种数据类型进行建模,例如,array,vector,struct, enum 等等。

    创建好需要的数据类型后,就可以创建service interface来描述一个服务。我们想创建如下图的一个服务
    在这里插入图片描述

    接下来创建excuteable, software component和port。对于服务的provider和consumer 我们分别创建以下元素。在本期中我们选择使用some-ip来进行实际的通信。在计算机网络的tcp-ip模型中,它位于传输层之上,它本身使用tcp或udp协议,它的具体内容是autosa标准的一部分,请参阅相关文档。
    在microsaradaptive的实现中,每个machine上应当有一个专门的soem-ip守护进程,来负责实现some-ip通信,所以我们需要为此建模。 例如,我们可以手动创建相应的excuteable, software component,process元素。在Davinci Develop Adaptive中,我们也可以在使用application design center时,自动生成与some-ip守护进程相关的这些元素。

    接下来对我们machine-design进行建模
    在上一集中我们创建machine的时候,就已经创建过我们machine-design,但是还没有在里面做过任何配置,它里面主要包含网络相关的配置信息,这些配置通常是从一些意义架构设计工具里导出的。具体而言,在machine-design中含有EthernetCommunicationConnector, 它描述machine的网络连接情况。例如,它含有指向networkEndPoint的引用,而一个networkEndPoint就表示一个网络地址,例如 ip地址,在networkEndPoint中,我们可以进行ipv4/ipv6地址的配置,以ipv4地址为例 我们可以配置它的地址,子网掩码,获取地址的方法等等。例如 fixed表示固定地址(也就是要手动分配),dhcpv4表示通过dhcp协议获取地址。

    networkEndPoint本身并不能独立存在,它被包含在一层EhternetPhysicalChannel中,而一个EhternetPhysicalChannel在逻辑上就表示一个VLan。 接下来我们利用appication design center来完成建模工作,并生成一个c++项目。

    首先进入appication design center这里的前三个子界面,Data Types editor, excitabl editor和service editor。因为这部分配置已经完成,所以我们直接进入第四个界面application configuration。
    在application configuration中,首先给我们的Adaptive Application起个名字,然后添加其包含的excutable。例如,添加my_provider_executable和my_consumer_executable。
    在这里插入图片描述

    然后配置port之间的连接,在左侧选择服务消费者使用的port,在右侧选择对应的服务提供者使用的port,然后点击中间的箭头按钮 就建立了两个port之间的连接。
    在这里插入图片描述
    接下来在modelbuild中生成模型,在本教程的第一集 hello adaptive world 我们已经介绍过这部分的相关内容,和当时不同的是,这次我们需要勾选generate for some-ip deployment,还需要配置这台们适应的ip地址,子网掩码,多播地址。

    在这里插入图片描述

    在machine properties这里可以配置一些start value,例如 将tcp port的start value设为3500,那么在待会生成的模型里,服务使用的tcb端口号就会是3501,3502等等。
    在这里插入图片描述

    在loging properties这里,可以分别配置服务的provider和consumer在输出日志时使用的appication id。
    在这里插入图片描述

    配置好这些信息后,点击build model按钮,模型就生成好了。

    3 根据模型编写应用代码

    3.1 SOME/IP接口简介

    SOME/IP服务接口有3种:Event、Method、Field。其中,Field相当于Method(Get,Set) + Event,具体使用有细微差别。
    在这里插入图片描述

    3.2 SOME/IP server端xml与应用代码解析

    下面以一个具体的例子进行说明,该例中配置一个PPort接口

    3.2.1 ServiceInterface.arxml分析

    在这里插入图片描述

    InterfaceName : SomeipAdapterServiceInterface
    Namespace : ADCU::someipAdapterNamespace
    event1: SomeipAdapterEvent1
    type : uint16_t
    event2: SomeipAdapterEvent2
    type: uint16_t
    method : int32_t someipServerMethod(int32_t inArrg1, int32_t inAurg)

    这段serviceinterfa ce配置会生成一个adcu::someipadapternamespace::skeleton::SomeipAdapterServiceInterfaceSkeleton类。
    在这里插入图片描述

    这个类定义在someipadapterserviceinterface_skeleton.h中,与xml对应生成的接口截图如下:
    在这里插入图片描述

    我们自己在编写AP应用代码实现somei/ip或者ipc通信时,就是要继承这个类,去实现对应的method和event方法即可。

    3.2.2 根据生成的代码接口手写应用代码

    1 serviceInterface 头文件解析
    在这里插入图片描述

    1> method接口说明
    因为在skeleton类中,SomeipServerMethod接口是纯虚函数,在继承skeleton类之后,我们需要实现method方法。
    2> event接口说明
    event方法已经在skeleton类或者skeleton的基类中已经实现,我们不必去重写,只是在需要的地方去调用event方法即可。
    2 serviceInterface cpp文件解析
    在这里插入图片描述

    在server端,event方法和method如何使用?
    event和method与ROS中的通信方式对比
    在这里插入图片描述

    所以在server端,event方法需要主动调用,一直往外发送;method方法不需要做任何处理,等待client端调用即可

    3.2.3 SOME/IP client端xml与应用代码解析

    1 ServiceInterface.arxml分析
    1> 在swc中配置RPort,引用上面配置的PPort接口
    在这里插入图片描述

    2> 配置一个RequiredSomeipServiceInstance 实例,并且把这个实例mapping到RPort端口
    3> 对应生成的代码如下:
    在这里插入图片描述

    2 根据生成的代码接口手写应用代码
    1> serviceInterface 头文件解析
    在这里插入图片描述

    2> serviceInterface cpp文件解析
    实现头文件相应的函数即可
    3> 在client端,event方法和method如何使用?
    在这里插入图片描述

    Note:一个executable中可以配置多个PPort和多个RPort,一个PPort中可以配置多个event和多个method

    4 client与server调试

    通过someip方式通信的client与server,在通信时,需要启动someip_deamon.

    1.设置多播

    sudo route add -net 224.0.0.0 netmask 240.0.0.0 dev etho
    sudo ip link set lo multicast on
    sudo ip route add ff01::0/16 dev lo
    
    • 1
    • 2
    • 3

    2.关闭json文件完整性校验,因为在调试的时候经常需要更改json文件

    export AMSR_DISABLE_INTEGRITY_CHECK=1
    
    • 1

    3.运行someip daemon
    1> someip daemon不需要自己配置模型,编写应用代码去编译,直接从install/opt/someipd_posix拷贝即可
    2> 修改someipd_poxis/etc/someip_posix.json文件

    {
        "applications" : [
            "../SomeipClientExec/etc/someip_config.json",
            "../SomeipServerExec/etc/someip_config.json"
        ]
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    3> ./bin/someipx_posix -c ./etc/someipd_posix.json

    4.运行someip_server
    1> 修改./etc/someip_config,将这个文件中所有的ip地址修改为本机ip地址
    2> 运行程序

    ./bin/SomeipServer
    
    • 1

    3> 修改logging_config.json,其中有这么一个字段

    "file" : {
    "file-path": "./log/log_server.txt"
    }
    
    • 1
    • 2
    • 3

    这时候一定要在etc bin的同级创建log目录,不然它自己是不会创建log目录的,跑起来就会报错

    5.运行someip_client
    1> 修改./etc/someip_config,将这个文件中所有的ip地址修改为本机ip地址
    2> 运行程序

    ./bin/SomeipClient
    
    • 1

    5 SOMEIP与IPC区别

    区别一:IPC Binding主要用于ECU内进程间的数据通信,SOME/IP 主要用于多个ECU之间通信,也可以用于ECU之间通信
    在这里插入图片描述
    在这里插入图片描述

    区别二:使用IPC Binding,数据传输不用通过SOMEIP daemon,SOMEIP 下必须起SOMEIP daemon应用才能实现数据交互。PS: IPC Binding虽然可以不用通过daemon进行通信,但是其传输协议仍然复用了someip protocal
    在同一ECU之间通信,理论上IPC Binding数据传输会比SOME/IPBinding快,因为数据不用经过daemon,而是在server-client之间直接通信。

  • 相关阅读:
    如何使用JavaScript实现多语言处理
    JVM 访问对象的两种方式
    IDEA常用插件
    Mozilla 紧急修补 Firefox 和 Thunderbird 中的 WebP 严重零日漏洞
    测评补单:Temu卖家的市场攻略,轻松吸引更多流量和转化!
    python经典百题之打印素数
    最炫表白网站html5源码_七夕程序员的十款表白源码_html+css+js
    [面试篇]Mysql 索引 BTree 与 B+Tree 的区别
    TypeError: lineplot() takes from 0 to 1 positional arguments but 2 were given
    基于redisson实现注解式分布式锁
  • 原文地址:https://blog.csdn.net/weixin_42445727/article/details/134232365