vsomeip使用手册-VsomeipUserGuide

本文详细介绍了vsomeip的构建步骤,包括一般构建、自定义路径安装、配置参数等。同时,讲解了vsomeip的环境变量、配置文件的内容及其各个元素的含义,如unicast、diagnosis、logging等。此外,还涵盖了vsomeip应用的启动和日志管理,以及如何通过配置文件定制服务行为。
摘要由CSDN通过智能技术生成

vsomeip

1.vsomeip概述

vsomeip的代码使用http://some-ip.com/[Scalable service-Oriented MiddlewarE over IP (SOME/IP)] protocol。源码包含:

  • 一个SOME/IP动态库(libvsomeip.so)
  • 还有一个动态库用于SOME/IP的服务发现(libvsomeip-sd.so)。在运行期间如果服务发现功能开启,该动态库就会被加载。

2.构建步骤

2.1构建前准备

  • 能够编译c++11编译器,比如5.2版本及以上的gcc
  • cmake构建工具
  • boost库,版本在1.55及以上
  • 如果使用Google的测试架构,你需要从https://code.google.com/p/googletest/[gtest]下载1.7.0及以上版本
  • 如果想要构建文档,你需要安装asciidoc, source-highlight, doxygen和 graphviz

2.2构建build

你需要进入到vsomeip的根目录:

2.2.1一般构建
#一般构建步骤
mkdir build
cd build
cmake ..
make
2.2.2自定义路径安装
#如果想要安装在自定义路径(比如 --prefix= ,前提是你需要熟悉autotools。autotools是一些列工具,用于生成makefile),你可以按照如下命令进行cmake
mkdir build
cd build
cmake -DCMAKE_INSTALL_PREFIX:PATH=$YOUR_PATH ..
make
make install
#默认路径会安装到 /usr/local/

#usr 指 Unix System Resource
#/usr:系统级的目录,可以理解为C:/Windows/,/usr/lib理解为C:/Windows/System32。
#/usr/local:用户级的程序目录,可以理解为C:/Progrem Files/。用户自己编译的软件默认会安装到这个目录下。
#/opt:用户级的程序目录,可以理解为D:/Software,opt有可选的意思,这里可以用于放置第三方大型软件(或游戏),当你不需要时,直接rm -rf掉即可。在硬盘容量不够时,也可将/opt单独挂载到其他磁盘上使用。

#源码放哪里?
#/usr/src:系统级的源码目录。
#/usr/local/src:用户级的源码目录

#很多应用都安装在/usr/local下面,那么,这些应用为什么选择这个目录呢?理解了最根源的原因后,也许对你理解linux组织文件的方式有更直观的理解。
#答案是:Automake工具定义了下面的一组变量:
#prefix  /usr/local 
#  exec_prefix   ${prefix}  
#    bindir  ${exec_prefix}/bin  
#    libdir  ${exec_prefix}/lib  
#  includedir    ${prefix}/include
#  datarootdir   ${prefix}/share 
#    datadir ${datarootdir}  
#    mandir  ${datarootdir}/man 
#    infodir ${datarootdir}/info 
#    docdir  ${datarootdir}/doc/${PACKAGE}  

#关于make install命令,可以参考https://zhuanlan.zhihu.com/p/77813702
2.2.3添加BasePath
#base path为生成的unix domain socket文件的路径
#可以使用cmake执行命令:
cmake -DBASE_PATH=<YOUR BASE PATH> ..
#默认的base path是/tmp
#对于socket是什么,可以参考https://blog.csdn.net/pashanhu6402/article/details/96428887
2.2.4使用unicast and/or diagnosis address进行编译
#预定义unicast,unicast是单播地址,默认为127.0.0.1
cmake -DUNICAST_ADDRESS=<YOUR IP ADDRESS> ..
#预定义diagnosis,diagnosis address只占一个字节,默认为0x01
cmake -DDIAGNOSIS_ADDRESS=<YOUR DIAGNOSIS ADDRESS> ..
2.2.5使用DEFAULT_CONFIGURATION_FOLDER
#默认使用的配置文件夹所在路径
cmake -DDEFAULT_CONFIGURATION_FOLDER=<DEFAULT CONFIGURATION FOLDER> ..
#默认的default configuration folder路径是/etc/vsomeip,
#但是本电脑实际位置是/usr/local/etc/vsomeip
2.2.6使用DEFAULT_CONFIGURATION_FILE
#默认使用的配置文件路径
cmake -DDEFAULT_CONFIGURATION_FILE=<DEFAULT CONFIGURATION FILE> ..
#默认的配置文件是/etc/vsomeip.json
2.2.7使用ENABLE_SIGNAL_HANDLING
#如果没有使用自定义去处理信号,可以使用vsomeip自带的信号处理
cmake -DENABLE_SIGNAL_HANDLING=1 ..
#该选项会通过定义宏VSOMEIP_ENABLE_SIGNAL_HANDLING,来启用vsomeip自己的信号处理代码
#对SIGINT等信号的理解,可以参考https://www.cnblogs.com/alexyuyu/articles/3853583.html
2.2.8使用ROUTING_READY_MESSAGE
#可以自定义一些log,当IP路由准备好发送和接收message,可以执行cmake
cmake -DROUTING_READY_MESSAGE=<YOUR MESSAGE> ..
2.2.9使用ENABLE_CONFIGURATION_OVERLAYS
#To compile vsomeip with configuration overlays enabled
cmake -DENABLE_CONFIGURATION_OVERLAYS=1 ..
2.2.10使用ENABLE_COMPAT
#To compile vsomeip with enabled vSomeIP 2 compatibility layer
cmake -DENABLE_COMPAT=1 ..

2.3编译examples

mkdir build
cd build
cmake ..
make examples

2.4编译tests

想要编译tests,首先把gtest解压到自定义路径。有一些测试需要在同一个网段中再加一个节点。有两个cmake变量可以用来自动更改json中的ip来适应当前工作的网络配置。

  • TEST_IP_MASTER: test master的ip地址
  • TEST_IP_SLAVE: test slave(另一个节点)的ip地址

任意一个变量没有被设置,那么测试只能在本地运行,无法进行跨物理机的测试。

当然你也可以设置ENABLE_SIGNAL_HANDLING,来使单元测试也能够处理信号。

完整的例子如下:

mkdir build
cd build
export GTEST_ROOT=<the path of googletest>
cmake -DENABLE_SIGNAL_HANDLING=1 -DTEST_IP_MASTER=10.0.3.1 -DTEST_IP_SLAVE=10.0.3.125 ..
2.4.1编译check

另有几个make targets可以在test使用

  • make build_tests,只编译tests
  • ctest,在build目录执行该命令可以没有冗余输出的执行tests
  • ctest -V -R $TESTNAME,运行单个测试,相当于ctest --verbose --tests-regex $TESTNAME
  • ctest -N,列出当前可执行的测试

更多有关测试的信息,可以参考tests目录下的readme.txt

还有两个变量(默认值都是OFF)用来控制是否json文件和测试脚本需要拷贝或者连接到build:

  • TEST_SYMLINK_CONFIG_FILES,控制是否json文件和测试脚本需要拷贝到build
  • TEST_SYMLINK_CONFIG_FILES_RELATIVE,控制是否json文件和测试脚本需要连接到build

如果只想编译测试的子集(用于快速的功能检查),可以使用cmake变量TESTS_BAT(默认值是OFF)

2.5编译vsomeip_ctrl

2.6生成文档

想要生成文档就需要按照<> 中描述执行cmake,之后再执行 make doc
这会生成:

  • The README file in html: $BUILDDIR/documentation/README.html
  • A doxygen documentation in $BUILDDIR/documentation/html/index.html

3.启动vsomeip应用和使用环境变量

vsomeip应用启动时以下的环境变量会被读取:

  • VSOMEIP_APPLICATION_NAME,赋予当前程序在vsomeip中使用的名字。vsomeip会通过改名字在配置文件中进行匹配查找。该名字与二进制可执行文件的名字是不一样的。
  • VSOMEIP_CONFIGURATION,vsomeip默认会使用配置文件 /etc/vsomeip.json或者包含配置文件的文件夹/etc/vsomeip。你可以通过该变量使vsomeip使用自定义的配置文件。
  • VSOMEIP_MANDATORY_CONFIGURATION_FILES,vsomeip允许使用mandatory配置文件来加快应用的启动速度(此时,除负责连接某些外部设别的程序之外,其他所有程序运行时都需要按照mandatory配置文件工作)。默认mandatory配置文件是:vsomeip_std.json, vsomeip_app.json和vsomeip_plc.json
  • VSOMEIP_CLIENTSIDELOGGING

注意:

  • 配置文件如果找不到,就会使用默认的配置文件
  • vsomeip会读取${VSOMEIP_CONFIGURATION}中所有的配置文件,但不会读取该路径下的文件夹。

4.配置文件的内容

4.1整体架构

vsomeip的配置文件有多个键值对和键值对数组构成。

一个完整的object,以{开始,以}结束,每一个键值对用:连接,多个键值对用,隔开。如果有array,以[开始,以]结束,多个[]用,隔开。

例如:

{
    "unicast" : "192.168.56.101",
    "logging" :
    {
        "level" : "debug",
        "console" : "true",
        "file" : { "enable" : "false", "path" : "/var/log/vsomeip.log" },
        "dlt" : "false"
    },
    "applications" : 
    [
        {
            "name" : "client-sample",
            "id" : "0x1343"
        },
        {
            "name" : "other-client-sample",
            "id" : "0x1344"
        },
        {
            "name" : "service-sample",
            "id" : "0x1277"
        }            
    ],
    "services" :
    [
        {
            "service" : "0x1234",
            "instance" : "0x5678",
            "reliable" : { "port" : "30509", "enable-magic-cookies" : "false" },
            "unreliable" : "31000"
        },
        {
            "service" : "0x1235",
            "instance" : "0x5678",
            "reliable" : { "port" : "30506", "enable-magic-cookies" : false },
            "unreliable" : "31000"
        }
    ],
    "routing" : "client-sample",
    "service-discovery" :
    {
        "enable" : "true",
        "multicast" : "224.244.224.245",
        "port" : "30490",
        "protocol" : "udp",
        "initial_delay_min" : "10",
        "initial_delay_max" : "100",
        "repetitions_base_delay" : "200",
        "repetitions_max" : "3",
        "ttl" : "3",
        "cyclic_offer_delay" : "2000",
        "request_response_delay" : "1500"
    }
}

4.2基本元素

4.2.1"unicast"

主机的IP地址。

4.2.2"netmask"

主机的子网掩玛。

4.2.3"device"

该参数可选。如果规定了,IP endpoints会绑定到该设备。endpoints应该是服务端和客户端的进行通信的地方。

4.2.4"diagnosis"

长度为一个字节长,用于构建客户端的标识符(即client ID)。如果没有其他规定(例如:自定义了client ID),diagnosis address会被用做client ID的高位字节。

4.2.5"diagnosis_mask"

长度为两个字节。用于控制一个ECU上最大可容纳vsomeip client数量,并规定了client ID的起始值。

例如,默认值0xFF00,表示:高位字节为diagnosis address预留,并且client ID的初始值为自定义的diagnosis address。最大的客户端数量是255,因为 Hamming weight of the inverted mask( Hamming weight:一串符号中非零符号个数。Hamming weight of the inverted mask就是一段字符中值为0的字符个数)是8(2^8-1=255,其中1是留给路由管理的)。生成的client IDs(例如diagnosis address是0x45)会从 0x4501到0x45ff。

当默认值是0xFE00时,clinet ID的数量为511,因为此时 Hamming weight of the inverted mask为9。当diagnosis address是0x45时,client ID的起始值时0x4401(0x4400作为路由器,因为从0x4500开始会超范围),到0x45ff。

4.2.6"network"

用于一个主机上有多个routing managers的情况。该参数可以更改/dev/shm中共享内存段的名字以及/tmp/下的 unix domain sockets名字。

默认情况该参数的值为”vsomeip“,则对应的共享内存被命名为/dev/shm/vsomeip,unix domain sockets被命名为/tmp/vsomeip-$CLIENTID

4.2.7"logging"
4.2.7.1"level"

明确日志的级别,可选的值有六个:trace, debug, info, warning,error, fatal

4.2.7.2"console"

明确log信息是否通过控制台输出,可选的值有:true, false

4.2.7.3"file"

“enable”,决定是否创建一个log文件,可选的值有:true, false

“path”,用于存放生成的日志文件的绝对路径

4.2.7.4"dlt"

决定是否使用Diagnostic Log and Trace (DLT),可选的值有:true, false

4.2.7.5version

vsomeip的版本

4.2.7.5.1’enable’

能否周期的查询vsomeip的版本,可选值有:true(默认值),false

4.2.7.5.2’interval’

周期记录vsomeip版本时的间隔时间,默认是两次记录的间隔为10s

4.2.7.6’memory_log_interval’

routing manager会周期性的记录其使用的内存状况,该参数表示两次记录的时间间隔,单位是秒。当设置参数之比0大时,该参数就会其作用。

4.2.7.7’status_log_interval’

routing manager会周期性的记录其当前状态,该参数表示两次记录的时间间隔,单位是秒。当设置参数之比0大时,该参数就会其作用。

4.3 全部参数配置示例

假设配置文件中使用所有配置参数,那么大概内容为如下所示:

{
    "unicast" : "10.0.2.15",
    "netmask" : "255.255.0.0",
    "device" : "eth0",
    "diagnosis" : "0x01",
    "diagnosis_mask" : "0xFF00",
    "network" : "vsomeip_example",
    "logging" :
    { 
        "level" : "debug",
        "console" : "true",
        "file" : { "enable" : "false", "path" : "/tmp/vsomeip.log" },
        "dlt" : "false",
        "version" : {"enable" : "false", "interval" : "20"},
        "memory_log_interval" : "2",
        "status_log_interval" : "2"
    },
    "tracing" : {
        "enable" : "true",
        "sd_enable" : "true",
        "channels" : [
            {
                "name" : "",
                "id" : "0"
            }
        ],
        "filters" : [
            {
                "channel" : "0",
                "matches" : "any",
                "type" : "positive"
            }
        ]
    },
    "applications" : 
    [
        {
            "name" : "service-sample",
            "id" : "0x1277",
            "max_dispatchers" : "12",
            "max_dispatch_time" : "100",
            "threads" : "2",
            "io_thread_nice" : "2",
            "request_debounce_time" : "10",
            "plugins" : [
                {
                    "name" : "",
                    "type" : "application_plugin"
                }
            ],
            "overlay" : "path_other_configuration",
        }
    ],
    "services" :
    [
        {
            "service" : "0x1234",
            "instance" : "0x5678",
            "protocol" :"someip",
            "unicast" : "10.0.2.15",
            "reliable" : {
                "port" : "30490",
                "enable-magic-cookies" : "true",
            },
            "unreliable" : "30509",
            "events" : 
            [
                {
                    "event" : "0x0777",
                    "is_field" : "true",
                    "is_reliable" : "true"
                }
            ],
            "eventgroups" :
            [
                {
                    "eventgroup" : "0x4455",
                    "events" : [ "0x777", "0x778" ],
                    "multicast" : 
                    { 
                        "address" : "224.225.226.233", 
                        "port" : "32344"
                    },
                    "threshold" : 0
                }
            ],
            "debounce-times" : {

            },
            "someip-tp" : {
                "service-to-client" : [

                ],
                "client-to-service" : [

                ]
            }
        }
    ],
    "clients" : [
        {
            "service" : "0x1234",
            "instance" : "0x5678",
            "reliable" : [

            ],
            "unreliable" : [

            ],
            "reliable_remote_ports" : "",
            "unreliable_remote_ports" : "",
            "reliable_client_ports" : "",
            "unreliable_client_ports" : "",
            "first" : "3333",
            "last" : "3335"
        }
    ],
    "payload-sizes" : [
        {
            "unicast" : "10.0.2.15",
            "ports" : {
                "port" : "30490",
                "max-payload-size" : 1000
            }
        }
    ],
    "max-payload-size-local" : 1000,
    "max-payload-size-reliable" : 1000,
    "max-payload-size-unreliable" : 1000,
    "endpoint-queue-limit-external" : 10,
    "endpoint-queue-limit-local" : 10,
    "buffer-shrink-threshold" : 100,
    "tcp-restart-aborts-max" : 10,
    "tcp-connect-time-max" : 10,
    "udp-receive-buffer-size" : 100,
    "internal_services" : [
        {
            "first": {
                "service" : 1111,
                "instance" : "0x5678"
            },
            "last" : {
                "service" : 1111,
                "instance" : "0x5678"
            }
        }
    ],
    "endpoint-queue-limits" : [
        {
            "unicast" : "10.0.2.15",
            "ports" : [
                {
                    "port" : "30490",
                    "queue-size-limit" : 12,
                }
            ]
        }
    ],
    "debounce" : [
        {
            "service" : "0x1234",
            "instance" : "0x5678",
            "events" : [
                {
                    "event" : "0x0777",
                    "on_change" : "true",
                    "ignore" : [
                        {
                            "index" : 1,
                            "mask" : 1
                        }
                    ],
                    "interval" : "20",
                    "on_change_resets_interval_" : "true"
                }
            ]
        }
    ],
    "routing" : "service-sample",
    "routing-credentials" : {
        "uid" : 111,
        "gid" : 111
    },
    "shutdown_timeout" : 5000,
    "warn_fill_level" : 67,
    "service-discovery" :
    {
        "enable" : "true",
        "multicast" : "224.244.224.245",
        "port" : "30490",
        "protocol" : "udp",
        "initial_delay_min" : "10",
        "initial_delay_max" : "100",
        "repetitions_base_delay" : "200",
        "repetitions_max" : "3",
        "ttl" : "3",
        "ttl_factor_offers" : [
            {
                "service" : "0x1234",
                "instance" : "0x5678",
                "ttl_factor" : 1
            }
        ],
        "ttl_factor_subscriptions" : [
            {
                "service" : "0x1234",
                "instance" : "0x5678",
                "ttl_factor" : 1
            }
        ],
        "cyclic_offer_delay" : "2000",
        "request_response_delay" : "1500",
        "offer_debounce_time" : 500
    },
    "watchdog" : {
        "enable" : "true",
        "timeout" : 5000,
        "allowed_missing_pongs" : 3,

    },
    "supports_selective_broadcasts" : [
        {
            "address" : "224.225.226.233"
        }
    ],
    "security" :
    {
        "policies" :
        [
            {
                "credentials" :
                {
                    "uid" : "44",
                    "gid" : "any"
                },
                "allow" :
                [
                    {
                        "requests" :
                        [
                            {
                                "service" : "0x6731",
                                "instance" : "0x0001"
                            }
                        ]
                    }
                ]
            },
            {
                "credentials" :
                {
                    "deny" :
                    [
                        {
                            "uid" : [ "1000", { "first" : "1002", "last" : "max" }],
                            "gid" : [ "0", { "first" : "100", "last" : "243" }, "300"]
                        },
                        {
                            "uid" : ["55"],
                            "gid" : ["55"]
                        }
                    ]
                },
                "allow" :
                [
                    {
                        "offers" :
                        [
                            {
                                "service" : "0x6728",
                                "instances" : [ "0x0001", { "first" : "0x0003", "last" : "0x0007" }, "0x0009"]
                            },
                            {
                                "service" : "0x6729",
                                "instances" : ["0x88"]
                            },
                            {
                                "service" : "0x6730",
                                "instance" : "any"
                            }
                        ],
                        "requests" :
                        [
                            {
                                "service" : "0x6732",
                                "instances" :
                                [
                                    {
                                        "ids" : [ "0x0001", { "first" : "0x0003", "last" : "0x0007" }],
                                        "methods" : [ "0x0001", "0x0003", { "first" : "0x8001", "last" : "0x8006" } ]
                                    },
                                    {
                                        "ids" : [ "0x0009" ],
                                        "methods" : "any"
                                    }
                                ]
                            },
                            {
                                "service" : "0x6733",
                                "instance" : "0x1"
                            },
                            {
                                "service" : "0x6733",
                                "instances" : [ "0x0002", { "first" : "0x0003", "last" : "0x0007" }, "0x0009"]
                            }
                        ]
                    }
                ]
            }
        ]
    }
}

  • 8
    点赞
  • 73
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
fidl (Fast Inter-process Communication Interface Definition Language) 是一种用于定义跨进程通信接口的语言,支持多种不同的编程语言和平台。vsomeip 库提供了对 fidl 语言的支持,可以使用 fidl 定义服务接口,并使用 vsomeip 实现跨进程通信。以下是一个简单的 vsomeip fidl 使用范例代码,用于实现一个简单的服务和客户端应用。这个例子是基于 C++ 的,使用了 vsomeip 库。 服务端代码: ```c++ #include <iostream> #include <vsomeip/vsomeip.hpp> #include "hello-service.fidl.h" class my_service : public fidl::hello_service { public: my_service() : fidl::hello_service("my_service") {} virtual std::string say_hello(const std::string& name) override { std::cout << "Received a request: " << name << std::endl; return "Hello, " + name + "!"; } }; int main() { vsomeip::runtime_impl my_runtime; my_service my_service_instance; my_runtime.add_service(my_service_instance); my_runtime.offer_service("fidl-hello"); my_runtime.start(); return 0; } ``` 客户端代码: ```c++ #include <iostream> #include <vsomeip/vsomeip.hpp> #include "hello-service.fidl.h" int main() { vsomeip::runtime_impl my_runtime; vsomeip::client my_client("my_client"); my_client.request_service("fidl-hello"); my_client.initialize(); fidl::hello_service_proxy my_service_proxy(my_client); auto response = my_service_proxy.say_hello("world"); std::cout << "Received a response: " << response << std::endl; my_client.release_service("fidl-hello"); my_client.deinitialize(); return 0; } ``` 这个例子实现了一个简单的服务和客户端应用,服务端使用 fidl 定义了一个名为 "say_hello" 的方法,客户端使用 fidl 代理来调用这个方法并打印出响应。需要注意的是,fidl 文件需要使用 fidl-cxx 工具生成相应的 C++ 代码,这个工具可以从 fidl-tools 项目中获取。另外,fidl 语言支持异步调用和事件通知等高级特性,可以根据具体需求进行适当的扩展。
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值