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

### 关于 AUTOSAR 中间件的 C++ 实现 AUTOSAR (Automotive Open System Architecture) 是一种标准化的汽车软件架构,旨在提高开发效率并简化复杂电子系统的集成。对于基于 C++ 的中间件实现而言,通常会涉及到使用标准模板库(STL)、智能指针以及多线程编程来构建高效可靠的通信机制。 #### 使用 STL 和智能指针管理资源 为了确保内存安全性和减少潜在错误,在现代 C++ 编码实践中推荐广泛采用 `std::shared_ptr` 来处理动态分配的对象生命周期控制。这可以从如下代码片段看出: ```cpp // 获取运行环境实例 std::shared_ptr<CommonAPI::Runtime> runtime = CommonAPI::Runtime::get(); ``` 这段代码展示了如何通过调用静态成员函数 `get()` 创建一个指向 `CommonAPI::Runtime` 对象的共享所有权智能指针[^1]。 #### 构建应用程序对象 当创建具体的应用程序逻辑实体时,同样可以利用类似的模式来进行初始化操作: ```cpp std::shared_ptr<vsomeip::application> app; app.reset(new vsomeip::application()); ``` 这里定义了一个名为 `app` 的变量用于存储对 `vsomeip::application` 类型对象的引用,并通过重置其内部持有的裸指针完成实际对象的新建工作[^2]。 #### 配置项目结构与编译设置 为了让上述组件能够正常运作起来还需要编写合适的CMakeLists.txt 文件指定源文件路径、链接所需的第三方库以及其他必要的配置选项。一个简单的例子可能看起来像这样[^5]: ```cmake project(AutosarMiddlewareExample) find_package(CommonAPI REQUIRED) find_package(vsomeip REQUIRED) add_executable(${PROJECT_NAME} main.cpp) target_link_libraries(${PROJECT_NAME} PRIVATE CommonAPI::CommonAPI vsomeip::vsomeip ) ``` 此部分描述了怎样在一个典型的 C++ 工程中引入依赖项并通过命令行工具链将其组合成可执行二进制文件。 #### 探索更多学习材料和技术文档 除了官方发布的规范指南之外,还可以参考开源社区贡献的各种教程和案例研究加深理解。例如,针对特定硬件平台如树莓派上的机器人控制系统设计,Adlink 提供了一套完整的解决方案集涵盖了从小型教育级产品到工业级应用的不同需求层次[^4];而对于实时操作系统内核层面的知识,则建议查阅相关书籍或在线课程进一步巩固基础概念。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

伴君者

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

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

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

打赏作者

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

抵扣说明:

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

余额充值