vsomeip使用模板

request&respond

response模版

    //创建应用,xxx是应用名称可以为空从服务中获取
    app = vsomeip::runtime::get()->create_application("XXXX");
    //初始化
    app->init();
    //注册服务处理函数
    app->register_message_handler(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_METHOD_ID, on_message);
    //提供服务
    app->offer_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID);
    //启动服务
    app->start();

request模版

    //创建应用,xxx是应用名称可以为空从服务中获取
    app = vsomeip::runtime::get()->create_application("XXXX");
    //初始化
    app->init();
    //注册服务有效性回调
    app->register_availability_handler(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, on_availability);
    //请求服务
    app->request_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID);
    //启动服务
    app->start();

发送函数
void send() {

    std::shared_ptr< vsomeip::message > request;
    request = vsomeip::runtime::get()->create_request();
    request->set_service(SAMPLE_SERVICE_ID);
    request->set_instance(SAMPLE_INSTANCE_ID);
    request->set_method(SAMPLE_METHOD_ID);
    std::shared_ptr< vsomeip::payload > its_payload = vsomeip::runtime::get()->create_payload();
    std::vector< vsomeip::byte_t > its_payload_data;
    for (vsomeip::byte_t i=0; i<10; i++) {
        its_payload_data.push_back(i % 256);
    }
    its_payload->set_data(its_payload_data);
    request->set_payload(its_payload);
    app->send(request);

}

notify & subscribe

notify模版


    //创建应用,xxx是应用名称可以为空从服务中获取
    app = vsomeip::runtime::get()->create_application("XXXX");
    //初始化
    app->init();
    //提供服务
    app->offer_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID);
    //加入事件组
    std::set<vsomeip::eventgroup_t> its_groups;
    its_groups.insert(SAMPLE_EVENTGROUP_ID);
    app->offer_event(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENT_ID, its_groups);
    //开始应用
    app->start();

subscribe模版

    //创建应用,xxx是应用名称可以为空从服务中获取
    app = vsomeip::runtime::get()->create_application("XXXX");
    //初始化
    app->init();
    //检查服务有效性
    app->register_availability_handler(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, on_availability);
    //请求服务
    app->request_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID);
    //注册消息处理
    app->register_message_handler(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENT_ID, on_message);
    std::set<vsomeip::eventgroup_t> its_groups;

    its_groups.insert(SAMPLE_EVENTGROUP_ID);

    app->request_event(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENT_ID, its_groups);

    app->subscribe(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENTGROUP_ID);
    //启动应用
    app->start();

field Get & field Set

SERVICE参考

    创建应用
    app_ = vsomeip::runtime::get()->create_application();
    初始化
    app_->init()
    //field
    注册服务
    app_->register_message_handler(
            SAMPLE_SERVICE_ID,
            SAMPLE_INSTANCE_ID,
            SAMPLE_GET_METHOD_ID,
            field_get);

    app_->register_message_handler(
            SAMPLE_SERVICE_ID,
            SAMPLE_INSTANCE_ID,
            SAMPLE_SET_METHOD_ID,
            field_set);
    //注册事件
    std::set<vsomeip::eventgroup_t> its_groups;
    its_groups.insert(SAMPLE_EVENTGROUP_ID);
    app_->offer_event(
            SAMPLE_SERVICE_ID,
            SAMPLE_INSTANCE_ID,
            SAMPLE_FIELD_EVENT_ID,
            its_groups);
    app_->offer_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, 1, 0);
    app_->start();

client参考

    //创建应用
    app_ = vsomeip::runtime::get()->create_application();
    //初始化
    app_->init()

    app_->register_state_handler(on_state);
    //field
    app_->register_message_handler(
            SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_GET_METHOD_ID,
            on_message);

    app_->register_message_handler(
            SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_SET_METHOD_ID,
            on_message);
    
    app_->register_availability_handler(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID,
            on_availability);
    app_->register_message_handler(
            SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_FIELD_EVENT_ID,
            on_message);
    std::set<vsomeip::eventgroup_t> its_groups;
    its_groups.insert(SAMPLE_EVENTGROUP_ID);
    app_->request_event(
            SAMPLE_SERVICE_ID,
            SAMPLE_INSTANCE_ID,
            SAMPLE_FIELD_EVENT_ID,
            its_groups,
            vsomeip::event_type_e::ET_FIELD,
            vsomeip::reliability_type_e::RT_BOTH);

    app_->subscribe(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENTGROUP_ID);

    app_->request_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID);
    app_->start();     

序列化与反序列化

序列化


std::shared_ptr< vsomeip::payload > its_payload = vsomeip::runtime::get()->create_payload();
std::vector< vsomeip::byte_t > its_payload_data;
const uint8_t a = 100;
const uint16_t b = 59;
const uint32_t c = 48;
const uint8_t arr[] = {1,2,3,4,5};
const std::string hello("1234455");

vsomeip_v3::serializer ser(0);
ser.serialize(a);
ser.serialize(b);
ser.serialize(c);
ser.serialize(arr, 5);
ser.serialize((const uint8_t*)hello.c_str(), (uint32_t)hello.size());

// for (std::size_t i = 0; i < 10; ++i)
//     its_payload_data.push_back(vsomeip::byte_t(i % 256));
its_payload->set_data(ser.get_data(), ser.get_size());
request_->set_payload(its_payload);
app_->send(request_);    

反序列化

std::shared_ptr<vsomeip::payload> its_payload = _request->get_payload();
//uint8_t *data = its_payload->get_data();
vsomeip_v3::deserializer des(its_payload->get_data(),its_payload->get_length(), 0);
uint8_t a ;
uint16_t b ;
uint32_t c ;
uint8_t arr[5];
std::string hello;
des.deserialize(a);
des.deserialize(b);
des.deserialize(c);
des.deserialize(arr, 5);
des.deserialize(hello, 7);

常见问题

1、在同一个局域网内,两方无法相互发现;

原理:运行的someip应用需要借助于各自的someipd服务来彼此发现对方;

而someipd实现的someip sd协议是借助于udp的广播来发布或收集网络中的其他someip应用的相关信息的;

所以要想两方能够彼此发现,首先要将someip sd的服务设置为同一广播地址以及服务端口号;

这个信息可以在vsomeip程序加载的vsomeip-tcp-server.json等配置文件中进行修改;

理想情况下,将两方的配置修改成一样就可以正常发现彼此;

2、将someip sd的广播地址以及服务端口号配置成一样,双方仍然是无法发现彼此;

这个首先要借助网络工具来抓包进行确认,是否可以在网络上抓取到相应的udp数据包,来检查是不是由于网络设置的原因造成的;

如果抓包工具可以确认在网络上有影响的udp广播包;

那么就要对someip的版本号配置进行确认;

在我使用vsomeip 2.10版本时发现,vsomeip 代码中的默认主版本号信息为0x00;而vector autasar的someip版本号信息不特意更改的话是0x01;

由于双方版本号不一致,虽然彼此可以收到对方发出的sd udp广播包,但在软件中彼此仍然无法相互识别。并且在vsomeip中会频繁输出warning信息;

将双方的版本号信息设置为一致时,就相互就可以识别了;

3、sd 广播地址服务端口号以及版本号都配置成一致;但彼此仍然无法发现;

这个就需要排查网络设置问题;

(1)双方是否可以彼此ping通;

(2)路由表以及gateway是否配置正确;

我就遇到双方可以ping通,但由于路由表以及gateway信息缺失使得双方无法彼此发现的问题;

4、双方可以彼此发现,但客户端一订阅或者发送request底层tcp链接就断开的情况;

这个问题,也是由于服务版本号的问题(interface version);

由于某些特殊的原因,将autosar someip的主版本号设置为255可以与vsomeip 的0版本号相互发现;

但是当进行交互时,在代码中会对interface version配置进行验证。如果双方的interface version不一致,那么就会出现一通信底层tcp的链接就会断开情况;

这个需要注意检查;

5、当vsomeip作为服务器,autosar someip作为客户端。vsomeip发送的event,autosar someip的客户端无法接收到的情况;

首先要对someip传输类型进行确认(使用的是tcp或者udp);

假如使用tcp进行传输;则需要将vsomeip 配置文件中event配置添加is_reliable为true的字段;

否则autasar someip tcp的客户端无法正常接收;

6、主机不能发送someip 消息

添加广播路由

ip route add 224.224.224.0/24 via 172.20.4.3 dev enp0s31f6.4

7、tbox不能与主机通信

tbox网络带有vlan id, 主机需要配置相同vlan id

调试工具

tcpdump 和 wireshark

tcpdump -i <网卡名称> -w <输出文件名.cap>

然后用wireshark分析cap文件

  • 20
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
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 语言支持异步调用和事件通知等高级特性,可以根据具体需求进行适当的扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

伴君者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值