vsomeip-双机通信例子
参考
(https://github.com/COVESA/vsomeip/wiki/vsomeip-in-10-minutes#prep)
(http://www.voycn.com/article/guanyusomeipdelijie)
简介
someip是位于七层网络协议的会话层,其是车载以太网引入的一个协议.与CAN相比,其只有在接收方有需求时,server端才会给client发送消息,因此会减少总线上的负载率.
服务是SOME/IP的最核心概念。在一个服务中,定义了Server和Client两个角色:Server提供服务,Client调用服务。对于同一个服务,只能存在一个Server,但可以同时存在多个Client调用服务。server就是一个提供一组method/event/field的接口
- Method
其包含两种:
带response(request/response)(Request/Response methods allow calls with answers.)
不带response (fire&forget)(Fire&Forgetmethods do not have answer messages.)
event
是server向client发送的单向消息,其是server主动向订阅了相关event的client发送的消息.(Events are simple messages from Server to Client.)field
其包含3部分:
Getter : Request/Response
Setter: Request/Response
Notifier : Events
上面两种方式的组合,field可以被订阅,用于消息通知,还具有set和get的功能,对消息进行读写操作.(Fields are properties that may include a Getter, a Setter, and a Notification.)
Server端
1. 配置文件(vsomeip.json)(/system/etc)
{"unicast" : "本机的ip","logging" : {"level" : "trace","console" : "true","file" : {"enable" : "false"},"dlt" : "false"},"applications" : [{"name" : "World","id" : "0x3489"}],"services" : [{"service" : "0x1234","instance" : "0x5678","reliable" : {"port" : "40001","enable-magic-cookies" : "false"},"events" : [{"event" : "9001","is_field" : "true","update-cycle" : 2000},{"event" : "9002","is_field" : "true","update-cycle" : 2000 }],"eventgroups" : [{"eventgroup" : "0x5555","events" : ["9001","9002"]}]}],"routing" : "vsomeipd","service-discovery" : {"enable" : "true","mode" : "unicast","unicast" : ["要通信的ip1","要通信的ip2"],"multicast" : "224.224.224.245","port" : "30490","protocol" : "udp","initial_delay_min" : "10","initial_delay_max" : "100","cyclic_offer_delay":"10000","request_response_delay":"1500"}
}
2. 代码
其主要代码:
1)创建application(world)(vsomeip::runtime::get()->create_application(“World”)),并进行初始化()(app->init())
2)为特定的service,instance,method/event的消息注册callback(app->register_message_handler())
3)向路由注册application(world)提供的service(app->offer_service()),为了让其他的application可以发现该service.注:为了向外部网络提供服务,配置必须包含提供的服务实例的端口。如果没有提供这样的端口配置,服务在设备外部是不可见的.
4)向路由注册application(world)提供的event(app->offer_event()),允许其他application订阅event/field,以及获取和设置field值。
5)启动消息处理(app->start()),它将阻塞,直到使用stop方法或通过接收信号终止消息处理。它处理通过套接字接收到的消息,并使用注册的回调函数将它们传递给用户应用程序。
#include <condition_variable>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <thread>
#include <vsomeip/vsomeip.hpp>#define SAMPLE_SERVICE_ID 0x1234
#define SAMPLE_INSTANCE_ID 0x5678
#define SAMPLE_METHOD_ID 0x07
#define SAMPLE_EVENTGROUP_ID 0x5555
#define SAMPLE_EVENT_ID 9001
std::shared_ptr<vsomeip::application> app;
std::mutex mutex;
std::condition_variable condition;void on_filed_message(const std::shared_ptr<vsomeip::message>& _request) {std::shared_ptr<vsomeip::payload> its_payload = _request->get_payload();std::cout << "SERVICE:Received filed message: " << std::hex << _request->get_method()<< ". client: " << std::hex << _request->get_client() << ". data: " << std::hex<< its_payload->get_data() << std::endl;// send responsestd::shared_ptr<vsomeip::message> its_response =vsomeip::runtime::get()->create_response(_request);its_payload = vsomeip::runtime::get()->create_payload();const vsomeip::byte_t its_data[] = {0x11};its_payload = vsomeip::runtime::get()->create_payload();its_payload->set_data(its_data, sizeof(its_data));its_response->set_payload(its_payload);app->send(its_response, true);
}void on_message(const std::shared_ptr<vsomeip::message>& _request) {std::shared_ptr<vsomeip::payload> its_payload = _request->get_payload();vsomeip::length_t l = its_payload->get_length();// Get payloadstd::stringstream ss;for (vsomeip::length_t i = 0; i < l; i++) {ss << std::setw(2) << std::setfill('0') << std::hex << (int)*(its_payload->get_data() + i)<< " ";}std::cout << "SERVICE: Received message with Client/Session [" << std::setw(4)<< std::setfill('0') << std::hex << _request->get_client() << "/" << std::setw(4)<< std::setfill('0') << std::hex << _request->get_session() << "] " << ss.str()<< std::endl;// Send responsestd::shared_ptr<vsomeip::message> its_response =vsomeip::runtime::get()->create_response(_request);its_payload = vsomeip::runtime::get()->create_payload();std::vector<vsomeip::byte_t> its_payload_data;for (int i = 9; i >= 0; i--) {its_payload_data.push_back(i % 256);}its_payload->set_data(its_payload_data);its_response->set_payload(its_payload);app->send(its_response, true);// Notify eventconst vsomeip::byte_t its_data[] = {0x10};its_payload = vsomeip::runtime::get()->create_payload();its_payload->set_data(its_data, sizeof(its_data));app->notify(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENT_ID, its_payload);std::cout << "service: notify over!!" << std::endl;
}int main() {app = vsomeip::runtime::get()->create_application("World");std::set<vsomeip::eventgroup_t> its_groups;its_groups.insert(SAMPLE_EVENTGROUP_ID);app->init();//注册method的监听app->register_message_handler(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_METHOD_ID,on_message);//注册field的监听app->register_message_handler(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENT_ID,on_filed_message);app->offer_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID);app->offer_event(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENT_ID, its_groups, true);app->offer_event(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENT_ID + 1, its_groups, true);app->start();
}
Client端
1. 配置文件(vsomeip.json)(/system/etc)
{ "unicast":"本机的ip","logging":{ "level":"trace","console":"true","file":{ "enable":"false"},"dlt":"false"},"performance-measurement": {"enable":"true","client":"true","server":"false","interval":60},"applications" : [{"name" : "Hello","id" : "0x1210"}],"services" :[{"service" : "0x7788","instance" : "0x98","reliable" : {"port" : "40004","enable-magic-cookies" : "true"},"events" : [{"event" : "90","is_field" : "true"},{"event" : "91","is_field" : "true"}],"eventgroups" : [{"eventgroup" : "0x333","events" : ["90","91"]}]}],"routing" : "vsomeipd","service-discovery" : {"enable" : "true","mode" : "unicast","unicast" : ["要通信的ip1","要通信的ip2"],"multicast" : "224.224.224.245","port" : "30490","protocol" : "udp","initial_delay_min" : "10","initial_delay_max" : "100","cyclic_offer_delay":"10000","request_response_delay":"1500"}
}
2. 代码
其主要代码:
1)创建application(world)(vsomeip::runtime::get()->create_application(“Hello”)),并进行初始化()(app->init())
2)向路由中注册一个监听application(world)状态的callback (app->register_state_handler()).当其反馈在路由中注册成功后,去请求service(app->request_service())
3)注册一个要请求的service的状态的监听,当service出现或消失时会被调用(app->register_availability_handler()),当其反馈service可用时,可以创建request( vsomeip::runtime::get()->create_request(true))向service发送消息(app->send()),和向service注册某些event(app->request_event())的监听(app->subscribe())
4)为特定的service,instance,method/event的消息注册callback(app->register_message_handler())
5)开启一个发送消息的线程(std::thread sender(run))
6)启动消息处理(app->start())
#include <condition_variable>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <thread>
#include <vsomeip/vsomeip.hpp>#define SAMPLE_SERVICE_ID 0x1234
#define SAMPLE_INSTANCE_ID 0x5678
#define SAMPLE_METHOD_ID 0x07
#define SAMPLE_EVENTGROUP_ID 0x5555
#define SAMPLE_EVENT_ID 9001std::shared_ptr<vsomeip::application> app;
std::mutex mutex;
std::condition_variable condition;void run() {std::unique_lock<std::mutex> its_lock(mutex);condition.wait(its_lock);//注册监听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, true);app->request_event(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENT_ID + 1, its_groups, true);app->subscribe(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENTGROUP_ID);// Send Requeststd::shared_ptr<vsomeip::message> request;request = vsomeip::runtime::get()->create_request(true);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, true);std::this_thread::sleep_for(std::chrono::milliseconds(2000));// send field requeststd::shared_ptr<vsomeip::message> request_filed;request_filed = vsomeip::runtime::get()->create_request(true);request_filed->set_service(SAMPLE_SERVICE_ID);request_filed->set_instance(SAMPLE_INSTANCE_ID);request_filed->set_method(SAMPLE_EVENT_ID);std::shared_ptr<vsomeip::payload> filed_payload = vsomeip::runtime::get()->create_payload();const vsomeip::byte_t its_data[] = {0x12};filed_payload->set_data(its_data, sizeof(its_data));request_filed->set_payload(filed_payload);app->send(request_filed, true);
}void on_message(const std::shared_ptr<vsomeip::message>& _response) {std::stringstream its_message;its_message << "CLIENT: received a notification for event [" << std::setw(4)<< std::setfill('0') << std::hex << _response->get_service() << "." << std::setw(4)<< std::setfill('0') << std::hex << _response->get_instance() << "." << std::setw(4)<< std::setfill('0') << std::hex << _response->get_method()<< "message_type: " << std::hex << static_cast<int>(_response->get_message_type())<< "] to Client/Session [" << std::setw(4) << std::setfill('0') << std::hex<< _response->get_client() << "/" << std::setw(4) << std::setfill('0') << std::hex<< _response->get_session() << "] = ";std::shared_ptr<vsomeip::payload> its_payload = _response->get_payload();its_message << "(" << std::dec << its_payload->get_length() << ") ";for (uint32_t i = 0; i < its_payload->get_length(); ++i)its_message << std::hex << std::setw(2) << std::setfill('0')<< (int)its_payload->get_data()[i] << " ";std::cout << its_message.str() << std::endl;}void on_availability(vsomeip::service_t _service, vsomeip::instance_t _instance,bool _is_available) {std::cout << "CLIENT: Service [" << std::setw(4) << std::setfill('0') << std::hex << _service<< "." << _instance << "] is " << (_is_available ? "available." : "NOT available.")<< std::endl;if (_is_available) {condition.notify_one();}
}void on_state_cbk(vsomeip::state_type_e _state) {std::cout << "on_state_cbk, state: " << static_cast<int>(_state) << std::endl;if (_state == vsomeip::state_type_e::ST_REGISTERED) {//注册成功后请求service,然后等待on_availability的callback// we are registered at the runtime now we can request the service// and wait for the on_availability callback to be calledapp->request_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID);}
}int main() {app = vsomeip::runtime::get()->create_application("Hello");std::set<vsomeip::eventgroup_t> its_groups;its_groups.insert(SLAVE_EVENTGROUP_ID);app->init();//把这个application注册到路由管理器中,on_state_cbk:callback注册结果app->register_state_handler(on_state_cbk);app->register_availability_handler(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, on_availability);app->register_message_handler(vsomeip::ANY_SERVICE, vsomeip::ANY_INSTANCE, vsomeip::ANY_METHOD,on_message);std::thread sender(run);app->start();
}
android.mk
将上述两个代码编译成bin文件,push进设备中执行
cc_binary {name: "someipservice_test",proprietary: true,srcs: ["someip_test_service.cpp",],include_dirs: ["SomeIP/vsomeip/arm64/include","SomeIP/boost/arm64/include",],shared_libs: ["libbase","libvsomeip",],cflags: ["-Wall","-Wno-unused-parameter","-Werror","-Wunused-variable","-Wno-unused-variable","-Wformat","-Wc++11-narrowing",],
}cc_binary {name: "someipclient_test",proprietary: true,srcs: ["someip_test_client.cpp",],include_dirs: ["SomeIP/vsomeip/arm64/include","SomeIP/boost/arm64/include",],shared_libs: ["libbase","libvsomeip",],cflags: ["-Wall","-Wno-unused-parameter","-Werror","-Wunused-variable","-Wno-unused-variable","-Wformat","-Wc++11-narrowing",],
}
vsomeip-双机通信例子相关推荐
- VSOMEIP双机通信
VSOMEIP双机通信 介绍下demo怎么写的还有双机通信怎么实现 文章目录 VSOMEIP双机通信 编写配置环境 双机通信 代码详解 server.cpp client.cpp 总结 编写配置环境 ...
- 【STM32H7教程】第94章 STM32H7的SPI总线应用之双机通信(DMA方式)
完整教程下载地址:链接 第94章 STM32H7的SPI总线应用之双机通信(DMA方式) 本章节为大家讲解SPI DMA方式双机通信. 目录 94.1 初学者重要提示 94.2 SPI D ...
- 怎么用matlab建立双机系统,基于MATLAB的双机通信的实现
第 卷第 期< 年 月 华 东 交 通 大 学 学 报 」 飞 朗 而 , 文章编号 一 以刀 能 一 以巧 一 基 于 的双机通信 的实现 曹青松 , 周继 惠 , 熊国 良 华东交通大学 机 ...
- 计算机dos通讯,PC双机通信DOS
<PC双机通信DOS>由会员分享,可在线阅读,更多相关<PC双机通信DOS(64页珍藏版)>请在人人文库网上搜索. 1.1 第第9 9章章 串行通信接口串行通信接口 主要内容: ...
- 双机通信c语言程序,上传一个自己编写的I2C双机通信程序
本帖最后由 micro_听海 于 2012-11-24 19:58 编辑 这几天一直在搞AVR的twi(twi就是i2c)双机通信程序,使用的是两块arduino开发板.因为最总要这个通信程序最总是要 ...
- air android 通信,Android超声波通信例子
[实例简介] Android超声波通信例子,手机之间,手机与超声波设备间的超声波通信 [实例截图] [核心代码] ComAir5Demo_V1.0.3 └── ComAir5Demo_V1.0.3 ├ ...
- RS-232实现双机通信
目录 一. RS-232串行通信接口标准 二. USB转TTL实现双机通信 1. 接线操作 2. 使用串口调试助手进行双机通信 三. 总结 四. 参考来源 一. RS-232串行通信接口标准 串行数据 ...
- 51单片机实现的双机通信设计仿真
基于51单片机的双机通信仿真设计 目录 一.题目要求 二.硬件设计说明 三.功能说明 四.软件设计说明 附:[Proteus仿真+keil代码+分析文档.rar](https://download.c ...
- 【嵌入式】STM32实现SPI双机通信的一些细节(2)片选总结
[嵌入式]STM32实现SPI双机通信的一些细节(2)SPI软硬件片选总结 SPI片选总结 坑爹的手册示意图 理想中的硬件片选 主机软件片选就对了 从机硬件片选 从机软件片选 代码 主机软件片选SPI ...
- 在学习c51单片机实验七(双机通信及pcb设计)操作Keil uVision4和protus的时候遇到的两个坑
第一个问题,这个问题用keil编程经常遇到 特别是懒的时候,对于新手,每次用一个工程文件,因为创建不熟练,就容易出现这个问题 Build target 'Target 1' linking... ** ...
最新文章
- 每个java程序都至少有一个线程给主线程,java程序在主线程中判断各个子线程状态的操作,该如何解决...
- Ts + React + Mobx 实现移动端浏览器控制台
- 【LeetCode笔记】208. 实现Trie(前缀树)(Java、前缀树)
- 新来的大神用策略模式把if else给优化了,技术总监说:能不能想好了再改?...
- MySQL表、索引大小查询
- Facebook广告与Google广告有什么不同?
- 智能一代云平台(三十三):log4j日志研究
- lisp语言与python_5种语言混合编程:C++、JS、python、Lisp、汇编
- docker配置深度学习环境
- Emacs自带小游戏
- 吴恩达的机器学习,属实牛逼
- VC++ EasyPR车牌识别
- 计算机学院java男默女泪,最新网络用语学习笔记,看了后,男默女泪
- 如何落户北京?19年积分落户规模为6000人!
- java 控制随机概率_【功能实现】实现设置概率的随机数
- 关于计算机网络海明Hamming Code校验码, CRC及奇偶码校验
- 宜立方商城第二天心得
- 光端机连接示意图详细连接方式图解
- aspx repeater 用法_Repeater控件的详细用法
- 伦敦大学学院 机器人与计算机,伦敦大学学院医学机器人与人工智能