前言
在CP ?Autosar開發(fā)中,客戶使用的接口以及這個(gè)接口的行為,雖然可以通過RTE定義清楚,但是RTE接口本身需要供應(yīng)商和客戶雙方約定好。
然而,到了SoC端開發(fā)AP Autosar,情況就變得不一樣了。很多名詞我們經(jīng)常會(huì)提到,這個(gè)代碼是跨平臺(tái)的,這個(gè)代碼符合POSIX標(biāo)準(zhǔn),這個(gè)代碼能在Like-Unix系統(tǒng)上正常運(yùn)行,這個(gè)代碼可以兼容安卓內(nèi)核。
我們不經(jīng)疑惑,在汽車電子中,AP該如何去寫代碼?在ADAS控制器領(lǐng)域,真正去使用的操作系統(tǒng)有打過RT patch的Linux系統(tǒng)和商業(yè)版本的QNX系統(tǒng)。安卓和mac更多的應(yīng)用在車機(jī)系統(tǒng)。
對于QNX系統(tǒng)和Linux系統(tǒng)的內(nèi)核差異,我們拋開宏內(nèi)核、微內(nèi)核之類的爭議不談。單純從開發(fā)應(yīng)用的角度而言,QNX和Linux系統(tǒng)的差異到底有多大,在開發(fā)的時(shí)候需要注意哪些細(xì)節(jié)問題?本文將嘗試盤點(diǎn)接口/應(yīng)用層級的差異。
作者前前后后花了幾個(gè)月時(shí)間嘗試去研究QNX系統(tǒng)下的編程與調(diào)試,在這邊做個(gè)總結(jié),也給大家做個(gè)匯報(bào)。
QNX與Linux基礎(chǔ)差異對比
QNX是微內(nèi)核、Linux是宏內(nèi)核
QNX是硬實(shí)時(shí)操作系統(tǒng)、Linux是軟實(shí)時(shí)操作系統(tǒng)
QNX和Linux均是類Unix操作系統(tǒng)
QNX支持POSIX PSE54標(biāo)準(zhǔn),Linux支持POSIX標(biāo)準(zhǔn),但不一定支持PSE54標(biāo)準(zhǔn)。
就調(diào)度策略而言,Linux支持Fifo,RR,other,deadline,batch策略。而QNX支持Sporadic、RR、FIFO策略。兩者有差異。
就IPC通訊機(jī)制(Socket、Signal、MessageQueue、Pipe、Shared Memory、信號量)而言,Linux支持POSIX相關(guān)標(biāo)準(zhǔn)之外,還額外支持System V相關(guān)接口。QNX支持POSIX標(biāo)準(zhǔn),也有獨(dú)有的Message Passing機(jī)制。總的來說,從功能角度來講,大差不差。
就性能優(yōu)化而言,各有各的特點(diǎn),如果做到性能的極致,同時(shí)還要兼顧跨平臺(tái),需要對Linux、QNX做一些抽象。
文件系統(tǒng)兩者不一樣。
QNX與Linux應(yīng)用差異對比
根目錄下的差異
QNX和Linux在根目錄這個(gè)層級上是有差異的,在Linux系統(tǒng)根目錄有如下差異:
bin、dev、home、lib、opt、sbin、sys、usr、data、etc、lib、proc、tmp、var等文件夾。重要的命令行程序存放于bin目錄下,庫文件存放于lib目錄下,系統(tǒng)庫的索引環(huán)境變量為lib和usr/lib。tmp目錄每次重啟均會(huì)清零,etc目錄會(huì)存放配置文件。proc目錄存放程序運(yùn)行的相關(guān)信息。dev目錄會(huì)將內(nèi)核相關(guān)的設(shè)備以文件的形式映射出來。
QNX系統(tǒng)根目錄下有debug、dev、etc、lib、opt、proc、bin、sbin、tmp、usr、var目錄。命令行相關(guān)程序存放于debug文件夾內(nèi),同時(shí)相關(guān)庫也會(huì)存放在debug文件夾中。QNX系統(tǒng)中的proc文件夾內(nèi)容與Linux系統(tǒng)中的內(nèi)容相差較大,QNX內(nèi)容更少,如果有軟件是基于proc目錄做策略的話,需要特別注意。QNX系統(tǒng)其他目錄對比Linux系統(tǒng),相差不大。
命令行的差異
在嵌入式系統(tǒng)中,我們會(huì)裁剪QNX和Linux系統(tǒng),因此很多命令不一定會(huì)全部支持。對于我們經(jīng)常需要用到的命令,例如ls,top等等,是否會(huì)有區(qū)別呢?就系統(tǒng)而言,兩邊到底有多大差距呢?這個(gè)問題值得我們?nèi)ニ伎肌N覀儚奈募僮鳌⑿阅苷{(diào)試、網(wǎng)絡(luò)分析三個(gè)角度來對比兩個(gè)系統(tǒng)的差異。
文件/文件系統(tǒng)操作命令:
ls,pwd,cd,cp,rm并無多大區(qū)別。
df -h查看文件分區(qū)情況兩者并無區(qū)別。
mount/umount命令有區(qū)別,在QNX系統(tǒng)中,采用mount /dev/xxx ?/yyy的形式掛載文件系統(tǒng)。umount ?-f ?xxx取消掛載。
性能分析相關(guān)的命令:
top命令可以查看程序的狀態(tài),然后展示的內(nèi)容有些許區(qū)別,命令的使用也有蠻大的區(qū)別。
QNX系統(tǒng)專有的hogs,pidin、ps命令對程序進(jìn)行分析。
QNX系統(tǒng)無法使用strace命令來獲取程序的系統(tǒng)調(diào)用,但是有tracelogger、traceprinter工具抓取相關(guān)信息,當(dāng)然也可以抓取kernel event trace,而Linux系統(tǒng)可以直接使用strace、perf工具實(shí)現(xiàn)更多的功能。
QNX系統(tǒng)可以使用Valgrind進(jìn)行內(nèi)存相關(guān)的分析,而Linux系統(tǒng)需要額外按照這個(gè)命令。
QNX系統(tǒng)可以使用類似gdb的方式進(jìn)行遠(yuǎn)程調(diào)試,也可以生成coredump文件,這個(gè)機(jī)制與Linux系統(tǒng)上有差異,但是功能上類似的。QNX系統(tǒng)還支持優(yōu)先級反轉(zhuǎn)的檢測,Linux系統(tǒng)上沒遇見過相關(guān)的成熟方案。
代碼覆蓋率相關(guān)的功能,應(yīng)用的方式感覺大差不差,需要額外確認(rèn)gtest是不是支持QNX系統(tǒng),以便于完成工具鏈的閉環(huán)。
網(wǎng)絡(luò)分析:
首先,QNX系統(tǒng)沒有tcpdump工具(文檔中是有的,實(shí)際在環(huán)境中并沒有),真是非常可惜,Linux系統(tǒng)支持tcpdump,支持libpcap庫所提供的相關(guān)特性。Linux系統(tǒng)常用的網(wǎng)絡(luò)工具:tcpdump、iperf,ss,netstat、ifconfig、ping、ip、lsof、arp等等。一般網(wǎng)路工具需要覆蓋1.網(wǎng)卡診斷查看相關(guān)功能 2.網(wǎng)卡性能檢測 3.網(wǎng)絡(luò)抓包 4.端口查看 5.網(wǎng)絡(luò)連接查看 6.流量分析等等。
QNX系統(tǒng)上網(wǎng)絡(luò)分析工具比較缺乏。Ifconfig、ping功能是類似的,sockstat是list所有socket信息含UDS相關(guān)的socket。netstat命令可以查看網(wǎng)絡(luò)狀態(tài),可以看到丟包相關(guān)的數(shù)據(jù)。iperf3工具也可以正常使用。arp命令可以正常查看路由表。
就工具而言,QNX系統(tǒng)有一點(diǎn)讓我無法容忍,響應(yīng)一個(gè)命令需要半天、半天、半天、重要的事情說三遍!!!!!!
系統(tǒng)編程的差異
本節(jié)從創(chuàng)建進(jìn)程、創(chuàng)建線程、鎖、共享內(nèi)存、網(wǎng)絡(luò)編程、定時(shí)器、信號幾個(gè)角度來確認(rèn)兩者的差異。
創(chuàng)建進(jìn)程:
Linux系統(tǒng)常用fork+execv函數(shù)族,QNX系統(tǒng) 不支持fork,須采用posix_spawn函數(shù)族,Linux系統(tǒng)也支持這個(gè)posix_spawn函數(shù)族,但是很多代碼并不會(huì)調(diào)用這個(gè)函數(shù)。
創(chuàng)建線程:
QNX系統(tǒng)和Linux系統(tǒng)均采用pthread_xxx函數(shù)族,但是有一點(diǎn)必須特別注意,親測QNX系統(tǒng)中pthread_setname_np接口并不起作用,但是程序可以正常運(yùn)行,Linux系統(tǒng)中這個(gè)接口調(diào)用是正常的,也可能是我對QNX系統(tǒng)理解的不到位。
鎖創(chuàng)建:
sem_xxx POSIX標(biāo)準(zhǔn)的函數(shù)族,QNX系統(tǒng)和Linux系統(tǒng)均支持,System V接口在QNX系統(tǒng)中不支持。
共享內(nèi)存創(chuàng)建:
Shm_xxx函數(shù)族POSIX標(biāo)準(zhǔn)的函數(shù)族,QNX系統(tǒng)和Linux系統(tǒng)均支持。但是這兩者還是有差異的,QNX系統(tǒng)會(huì)在/dev/shmem目錄下生成相關(guān)的共享內(nèi)存文件,而Linux系統(tǒng)會(huì)在/dev/shm目錄下生成相關(guān)的文件。此外,親測當(dāng)設(shè)置文件名時(shí),文件名帶不帶路徑,例如“a/shm1.shm”在兩個(gè)系統(tǒng)中的實(shí)際效果不一致,但是程序會(huì)正常運(yùn)行。
網(wǎng)絡(luò)編程:
Linux支持很多特殊的特性:bpf、libpcap、netfilter機(jī)制等等。QNX系統(tǒng)沒有bpf、沒有l(wèi)ibpcap、沒有netfilter。Linux可以對socket本身設(shè)置優(yōu)先級,QNX系統(tǒng)不支持。因此像開源時(shí)間同步代碼linuxptp大概率在QNX系統(tǒng)上無法正常編譯(沒試過,但是用了linuxptp用了一些bpf的機(jī)制)。如果是普通的UDP、TCP開發(fā),接口還是兼容的,但是對raw socket開發(fā)或者需要利用kernel機(jī)制的一些優(yōu)化,則無法兼容。
總的來說,網(wǎng)絡(luò)編程這塊,QNX系統(tǒng)和Linux系統(tǒng)還是蠻大的,雖然POSIX接口是統(tǒng)一的,但是很多特殊的操作系統(tǒng)設(shè)計(jì)特性真是不兼容。尤其是用到setsockopt這個(gè)接口時(shí),需要特殊特別特意的關(guān)注!!!!!!
定時(shí)器創(chuàng)建:
Linux系統(tǒng)的定時(shí)器有很多方式:alarm、timer_create/ timer_settime函數(shù)族、setitimer接口等等。QNX系統(tǒng)的教程說是支持這幾個(gè)接口,并沒有實(shí)際應(yīng)用過,暫定兼容的。
信號的創(chuàng)建:
signal接口兩者是兼容的,更高級的用法沒試過。
編譯的差異對比
對Linux系統(tǒng)交叉編譯時(shí),不需要顯示的指定glibc庫,也不需要顯示的初始化編譯器的環(huán)境。
而對QNX系統(tǒng)交叉編譯時(shí),首先需要調(diào)用qnxxxx_env腳本初始化環(huán)境,必須要顯示的用-l c指定c庫的鏈接,同時(shí)需要指定std的語言,同時(shí)QNX系統(tǒng)支持qcc和gcc兩套編譯器,親測均可生成在QNX系統(tǒng)上運(yùn)行的可執(zhí)行文件。C++程序需要指定std變量并使用-lc++鏈接c++庫。QNX系統(tǒng)若需要支持gnu特性,需要顯示的指明gnu++11標(biāo)準(zhǔn)。對于socket編程,需要使用-lsocket指令顯示鏈接相關(guān)庫。
總而言之,qnx系統(tǒng)的交叉編譯還是有很多注意點(diǎn)的。
審核編輯:發(fā)貨
?
評論
查看更多