不知火舞的被虐|伊人天伊人天天综合网|博洛尼亚天气|任你懆这里只有精品4|久久美日韩精品久久|掌中之物漫画免费阅读观看|0丨d老妇
首頁
學院
直播
問答
懸賞
全部懸賞
發布懸賞
專家入駐
會議
社區
CAE工程師認證
CAE服務
搜索
發布
注冊
/
登錄
vsomeip porting 札記
駕駛哥
關注
2021年6月7日 09:32
瀏覽:2462
評論:1
來源 |
拖拉機日記
知圈 |
進“電子電氣群”請加微13636581676,備注架構
今天整理和分享一下把vsomeip分別porting到Android和QNX的過程,以及一些通過porting對vsomeip作的探索和基于vsomeip怎么實現架構的思考。
當需要移植一個開源庫到某個平臺時,我們首先會做的一件事情是什么?當然是熟練打開搜索網頁,輸入關鍵字“xxx”(庫的名稱)+“xxx”(目標平臺的名稱),按下回車,一頓操作猛如虎,總能搞出個七七八八。我一般也是這么干的,但最近發現吧,這個方法真是越來越不好使了,雖然我的問題并不罕見,事實上我經常搜到跟我有一樣問題的評論,但我想找的答案確實越來越難找了。比如我想要的是不僅僅把vsomeip移植到Android上,更想實現把vsomeip的C++接口封裝成Java接口。我找了很久也沒找到一個能直接用的示例。幸運的是,還是找到了兩個porting成功的HelloWorld,把它倆跑通了,至少可以解決把vsomeip和CommonAPI-SomeIP移植到Android上的問題。
但這兩個HelloWorld,其實沒有對vsomeip作任何JNI接口封裝,所以完全沒辦法給我什么參考。什么是我想做的?我的實現目標是封裝一個Jar包,提供vsomeip的Java接口,即調用這個Jar包的API,可以實現類似
快速上手 vsomeip
中服務端和客戶端之間的SOME/IP通信。把Github快翻了個底朝天,也沒找到一個vsomeip的JNI封裝例子,只好硬著頭皮自己做了。
實現從C++接口到Java接口,需要用到NDK相關技術。其實,這是我第一次做NDK開發。在我過去的認知中,其實不太喜歡JNI接口的長相,意想不到的是,如今較新版本的Android Studio,對C++和CMake的支持可以說是非常不錯了,NDK開發的體驗并不差,連JNI接口的顯示也優化了。整個JNI->Jar->Demo的開發過程,竟然比想象中順利很多。需要學習的一塊新知識是關于C++和Java之間相互調來調去時如何做數據轉換,C++回調Java時如何找類找方法,說白了就是如何調用JNI提供的一套API,而這些問題,基本上有一些普遍適用的解決方法,通過搜索關鍵字都能找到答案。除了這塊,C++還是C++,Java還是Java,該怎么開發還是怎么開發,并沒有什么特別。
開發Jar包的過程中,要對vsomeip的接口能力進行挖掘,以便能夠開放出vsomeip完整的功能。于是,我研究了vsomeip的源碼結構和其中application模塊的接口。下圖是vsomeip源碼的整體框架,可以看到,application模塊是vsomeip的核心所在,由它來調度vsomeip的各個模塊,如configuration(配置)、endpoints(端點,即網絡連接)、routing(消息路由)、message(消息封裝和解析)。事實也確實如此,回顧我們在寫代碼時第一步要做的,就是先拿到一個application的智能指針,接下來幾乎所有的操作不都是用它去調接口來實現的嘛。其實在當前版本(3.1.20,2020.12Release)的vsomeip里,除了圖中這些模塊,還有e2e_protection、security等新模塊,文檔沒有體現,開源項目多少會有點這樣的問題,文檔可能滯后于代碼。
vsomeip overview,摘自源碼Document目錄EA文檔
application模塊的類圖和源碼已經不怎么一致了,對照application.hpp,我畫了類圖,便于對比,官方文檔的類圖我也摘了出來,見下圖。如果不是畫了類圖,我也不會了解到實際源碼和文檔竟有這么大的差異,難怪vsomeip_v3和vsomeip要用不同的命名空間區分,頭文件和動態庫的名字也是區分開的。其實做兼容,不是全揉到一起才是好的設計,有時作為使用者是有必要知道自己正在使用的是哪個版本的接口吧,所謂對上層透明,與底層解耦,并不一定就顯得多么高級。只要你的應用場景和底層通信本身就有著千絲萬縷的聯系,那從某種程度來說,絕對的解耦是不現實的。
vsomeip_v3::application 類圖 (自制)
vsomeip::application 類圖,摘自官方EA文檔
一邊畫類圖,一邊看源碼里關于每個接口的注釋說明,我會想,為什么vsomeip_v3要加這幾個接口,要改那幾個接口,要設計得和原來不一樣,是原來的接口有什么缺欠嗎?這些改動和新增,意義是什么?我的Jar包怎么設計?如果我的Jar包還是封裝了原來那幾個主要的接口,是不是也就沒有發揮出vsomeip_v3的優勢?那么,所謂的優勢又是什么?是能解決什么更復雜的應用場景?還是性能方面表現得更好?還是說新增了什么可配置的安全策略?而這些優勢,是不是我的上層應用們正迫切需要的呢?對我的架構設計來說,是多此一舉,還是錦上添花?
寫這篇文章的時候,還沒有想好這些問題的答案,這關乎到我的Jar包最終會做成什么樣子。第一版提交,過于粗糙,幾乎談不上什么設計,只是實現了基礎需求,做了一個DemoApp驗證porting的結果。那么接下來,我希望可以設計和實現一些更高階的需求,比如接口具有通用性、可擴展性、同步調用機制、異步回調機制、消息隊列、異常捕獲等。我決定把這個Jar包的實現,作為一個開源項目放在Github上進行長期的開發和迭代,目標是實現一套基于vsomeip通用的Java接口封裝。為什么想做這個?
根據GENIVI官網的說法,應該不會再開發Java語言的vsomeip了,那就意味著Android中的應用也好,服務也罷,是無法直接調用vsomeip接口的。目前,多數車載娛樂系統采用的操作系統基本上是Android。如果用SOME/IP作為SOA通信協議。想象一下好了,如果對Android的某個服務或應用來說,要接入SOME/IP,看著就不太好弄的樣子,總要先了解SOME/IP協議和機制吧,然后還要研究vsomeip接口怎么用吧,最后再C++->Java跨語言開發一波,可想而知,讓每個服務都這么走一遍的阻力會有多大,在設計上也是不合理的,每個服務應該專注于實現自身的業務邏輯,而不是要花很大的力氣才能適配到某個平臺。這時我們還會想到另一個辦法,只做一個中間轉發服務不就行了嗎,讓它去和外部ECU以SOME/IP通信交互,別的服務和它之間只要做進程間的通信就行了,至于具體什么IPC方式,Android里的選擇那可太多了。
乍看,一點沒毛病,與其把所有服務都卷進來,不如就讓一個服務來承受這一切,萬一搞砸了,那也就一個服務的工作量白費,怎么看都是劃算的。所以現實中,我們其實經常看到這樣的解決方案。但是,這樣做帶來最主要的問題是什么?這個中轉服務,幾乎不可能在最初就把所有服務的所有接口都實現好,第一數量極其龐大,第二當下沒有需求驅動,第三容易導致負荷過大等問題,性能堪憂。這意味著,它能提供的服務能力和接口必然是有限的。如果在以前,需求變更不頻繁,確實沒什么問題,但是時代不同了,唯一不變的是變化,一旦出現了新需求,現有接口無法滿足,新增接口就是家常便飯,同時它的上下游也都要參與對接和聯調,整個過程所需要的各種耗費是不容忽視的。然而,所謂的“新接口”可能是某個服務原本早就具備的能力,只是它沒有開放出來,缺的是讓每個服務能夠把自身有價值的能力和接口很好地開放出來的平臺架構。這是理解為什么要服務化的關鍵。
我想從這個Jar包開始,首先實現Android域中SOME/IP底層通信的基礎設施,進而探索如何從技術層面去解決SOA服務化的難點。只有服務化做好了,SOA才可能發揮其優勢,不然就算每個ECU都通上了SOME/IP,也只是換個協議的事罷了。如果你了解有類似的開源項目,或者技術上的想法和建議,都歡迎在后臺留言給我~(有需要的加小編微信13636581676,幫你們對接交流)
如果說porting到Android的過程是意料之外的順利,那么porting到QNX的過程就是意料之中的艱辛。眾所周知,QNX是商業的操作系統,網上資料非常有限,很少有完美支持QNX的開源庫,porting任何一個稍許復雜點兒的開源庫都不會特別順利,有時不但需要修改編譯腳本,甚至要修改源碼才可以,比如vsomeip就是如此。在vsomeip的issue里搜到這樣一個問題:
得益于此,我找到了vsomeip2在QNX上成功porting的項目鏈接。感謝這位外國大牛的開源,把porting的步驟寫得這么詳細,我很快把vsomeip-2.5.2和vsomeip-2.6.1都編譯出來了。但畢竟2.6.1感覺還是稍舊了些。于是,我想試一試交叉編譯最新的3.1.20,我覺得這事兒一定不簡單,不然怎么到現在那個問題底下還沒點解答。我的思路是這樣的,既然vsomeip2能編成功,那么先研究一下vsomeip2都改了哪些地方,是怎么改的。用了“對比大法”,發現vsomeip2改了的地方,vsomeip3基本上也要改。endpoints是修改的重點模塊,主要做法是通過預編譯宏,剔除netlink和credentials相關的調用,因為QNX不支持像Linux一樣透出netlink接口,并且setsockopt不支持SO_PASSCRED這個選項。vsomeip3代碼明顯比vsomeip2多,要改的地方也多一些。改的時候要有耐心,注意別把不用改的地方也一起改了。endpoints模塊編過了以后,有幾個模塊不用改也可以直接編過,但到了routing模塊又開始作妖,分析原因在于uid_t和gid_t在QNX中的類型定義和Linux不同,導致各種右值引用、類型不匹配等錯誤,這是新的security模塊用到的,所以vsomeip2不會有此問題,最后我是通過在primitive_type.hpp中將其定義為uint32_t解決了問題。再后面的編譯也開始順暢了起來。
看我說得還挺輕巧,其實花了一整個周末的時間。反復搗鼓,報錯,查問題,改完了試。編譯成功了以后,又做了兩次復盤。第一次復盤時,發現改了不用改的地方,第二次力求只改必須改的。上面總結的幾個主要修改和問題原因,都是在第二次復盤時得出的,前面看問題還來不及,哪有心情去歸納。所以,學會復盤是非常重要的。其實還有很多可以去完善的地方,比如boost版本較老,直接用了大牛porting成功的1.55,為了控制變量嘛,如果兩個版本都升級了,出了問題兩個庫都要查,現在vsomeip編過了,可以再升級boost到較新版本;boost只編了靜態庫,這樣編出來的vsomeip動態庫會比較大,竟達到了55M,可以改成動態庫試試;圖省事,直接用了大牛的patch和.cmake,有時間還是要自己寫一下。我也fork了vsomeip,再把改好的放到了Github上,后面還可以持續改進,希望以后能作為那個issue的一個解答。
之前一直想找個時間好好研究一下vsomeip的源碼,回頭也寫個“深度剖析”系列什么的,像“libevent源碼深度剖析”一樣。后來覺得吧,vsomeip和libevent還是不太一樣的,它主要是基于boost實現的,應用的成分更多,深度剖析原理的價值可能沒有很高。以前覺得porting不就是解決一些編譯錯誤的過程,其實不一定的,對于vsomeip這種需要改到源碼的porting,實際上,順便也熟悉了一遍源碼,有的模塊甚至掃了不止一遍。有一個小點吧,諸如CMake的語法,Shell的語法,項目的構建等這些知識,通過看書學習,我反正覺得挺枯燥的,基本記不住,更談不上實際應用。但在cmake報錯時,就不得不去研究別人是怎么寫的,有一定代碼量的開源庫的編譯腳本,一般都會寫得非常有條理,各種條件的判斷和依賴等表達,都可以學到。模仿,對我這種庸人來說,真是性價比最高的學習方法了。
之所以沒有把一步步都怎么做的,寫得非常詳細,主要在當時,一門心思只想著怎么才能編譯成功,刷刷的報錯根本沒心情去想給寫公眾號留點素材啥的,然后還是那句話,絕知此事要躬行,自己做一遍和看別人做一遍,天差地別。所謂“札記”,分享思路為主哈,水平有限,如有錯誤,煩請指教。
提到的幾個開源項目,參考的和我寫的,回復“porting”,有本篇全部的鏈接。不是什么牛逼的代碼,僅作為分享和交流,極其簡陋,改善空間相當大,各路大牛大神們有什么絕妙代碼想提PR的熱烈歡迎,時刻準備著接受diss。
End
登錄后免費查看全文
立即登錄
推薦閱讀
轉子旋轉的周期性模型-水冷電機散熱仿真
技術鄰小李
¥100
有限元理論之等參單元教程
引垂思汀
¥20
基于workbench鋼板彈簧的有限元分析(強度與變形)
lz1234
¥80
HBM應變測量基礎
HBK測試與測量
免費
5G終端天線仿真設計方法及其應用
Ansys中國
免費
測量不確定度的應用實踐
HBK測試與測量
免費
混合動力市場及技術趨勢分析
陳開
免費
Adams Car 扭力梁懸架模型的搭建視頻
仿真分析
¥19.8
基于abaqus的部分鋼骨混凝土框架梁柱邊節點有限元分析
T10
¥150
噴嚏中的學問——病毒飛沫傳播方式的CFD 仿真
海克斯康設計與仿真
免費
0#塊箱梁托架法施工結構模擬
yudachuan1105
¥200
向量微積分理論基礎
引垂思汀
¥50
Abaqus接觸類分析(凹陷)一鍵建接觸(簡單的一筆)附demo
北斗七星仿真工作室
¥5
ABAQUS任意梁單元截面的實現
eFEA
¥100
基于OptiSturct的線性靜力學分析和尺寸優化
Leon_sun
¥10
hypermesh_dyna小車碰撞護欄(無聲)
吳文澤
¥18
轉矩波動測量和分析
HBK測試與測量
免費
Ansys射頻芯片(RFIC)電磁場仿真技術介紹
Ansys中國
免費
基于workbench的螺絲擰緊過程動力學分析,視頻免費無聲音,操作細致,建模過程(需購買)
兵荒馬亂
¥5
Cadence Fidelity 水泵水輪機CFD模擬解決方案和應用
Cadence楷登
免費
技術鄰APP
工程師
必備
項目客服
培訓客服
平臺客服
TOP
1