vsomeip使用模板

文章详细介绍了VSOMEIP框架中的request、respond、notify、subscribe等服务操作模板,涉及服务注册、请求、事件处理和序列化反序列化的示例,以及解决网络发现、版本兼容性等问题的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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文件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

伴君者

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

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

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

打赏作者

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

抵扣说明:

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

余额充值