在說vsomeip之前,先介紹一下它的貢獻者——GENIVI,是一個非營利汽車行業聯盟。這個聯盟成立于2009年,已經成功地完成了最初的使命,提供了一個開放的、基于linux的車載信息娛樂(IVI)平臺,并擴大了其范圍,幫助汽車制造商及其供應商開發標準方法。
在汽車行業,GENIVI的項目被非常廣泛地應用,比如:vsomeip,CommonAPI C++,DLT…沒見用過的就不列出來了,感興趣可以到官網了解更多。
vsomeip是一個開源C++庫,它實現了SOME/IP協議棧。接下來,我們通過一個demo,感受一下SOME/IP的通信過程,以及如何使用vsomeip,廢話不多說,讓我們開始吧~
首先,需要搭建環境(這里以Ubuntu16.04為例),vsomeip依賴Boost(1.55以上版本),因此我們需要先編譯和安裝Boost:
接著,編譯和安裝vsomeip:
上面這個配色,著實讓人匪夷所思(還是我用的有問題?),總之,我不喜歡,所以以后不再插入bash代碼,環境配置相關內容盡可能寫進README里,放到Github上,關注公眾號,回復“演示代碼”,就可以看到全部文章里涉及到的工程地址啦~
官方的helloworld,稍微有點簡單,demo的思路是這樣的:
實現一個服務端,可以:1. 響應請求,內容為請求的反轉;2. 觸發事件
實現一個客戶端,可以:1. 發送請求;2. 訂閱、接收事件
首先,服務端和客戶端需要約定一些ID,包括:
對于服務端,主要代碼如下:
// 創建應用對象
app = vsomeip::runtime::get()->create_application("World");
// 創建事件組,并添加事件組SAMPLE_EVENTGROUP_ID
std::set
其中,請求消息的回調函數:
void on_message(const std::shared_ptr {
std::shared_ptr
對于客戶端,主要代碼如下:
// 同樣地,創建應用對象
app = vsomeip::runtime::get()->create_application("Hello");
// 初始化應用
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(vsomeip::ANY_SERVICE, vsomeip::ANY_INSTANCE, vsomeip::ANY_METHOD, on_message);
// 發送請求線程
std::thread sender(run);
// 啟動應用
app->start();
其中,監聽服務是否可用的回調函數:
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_message(const std::shared_ptr {
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() << "] 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
客戶端發送請求線程函數:
void run() {
std::unique_lock
編譯,運行結果如下:
通過打印出來的日志,我們可以比較清晰地看到整個通信的過程,并且實現了預期的效果。這個例子只能說明如何快速地上手vsomeip,其實,還有很多東西可以挖掘,比如vsomeip怎么配置,routing manager怎么配置,和dlt怎么聯動等等,真是學無止境呀,今天就先到這兒吧~
審核編輯:劉清
-
Boost
+關注
關注
5文章
370瀏覽量
48136 -
回調函數
+關注
關注
0文章
87瀏覽量
11575 -
Ubuntu系統
+關注
關注
0文章
91瀏覽量
3979
發布評論請先 登錄
相關推薦
評論