開(kāi)源項(xiàng)目 OpenHarmony 是每個(gè)人的 OpenHarmony
蔣衛(wèi)峰
深圳開(kāi)鴻數(shù)字產(chǎn)業(yè)發(fā)展有限公司
OS內(nèi)核開(kāi)發(fā)工程師
iperf3主要的功能是測(cè)試基于特定路徑的帶寬,在客戶端和服務(wù)器端建立連接(三次握手)后,客戶端發(fā)送一定大小的數(shù)據(jù)報(bào)并記下發(fā)送的時(shí)間,或者客戶端在一定的時(shí)間內(nèi)發(fā)送數(shù)據(jù)并記下發(fā)送的總數(shù)據(jù)。帶寬的大小等于發(fā)送的總數(shù)據(jù)除以發(fā)送的總時(shí)間。對(duì)服務(wù)器端來(lái)說(shuō),在連接建立時(shí)間內(nèi),接收的總數(shù)據(jù)除以所花時(shí)間即為服務(wù)器端所測(cè)得的帶寬。
iperf3測(cè)試UDP的性能時(shí),客戶端可以指定UDP數(shù)據(jù)流的速率??蛻舳税l(fā)送數(shù)據(jù)時(shí),將根據(jù)客戶提供的速率計(jì)算數(shù)據(jù)報(bào)發(fā)送之間的時(shí)延,客戶還可以指定發(fā)送數(shù)據(jù)報(bào)的大小。每個(gè)發(fā)送的數(shù)據(jù)報(bào)包含一個(gè)ID號(hào),用來(lái)唯一地標(biāo)識(shí)該報(bào)文。服務(wù)器端則根據(jù)該ID號(hào)來(lái)確定數(shù)據(jù)報(bào)丟失和亂序。當(dāng)把UDP報(bào)文大小設(shè)置可以將整個(gè)報(bào)文放入IP層的包(packet)內(nèi)時(shí),那么UDP所測(cè)得的報(bào)文丟失數(shù)據(jù)即為IP層包的丟失數(shù)據(jù)。這提供了一個(gè)有效的測(cè)試包丟失情況的方法。數(shù)據(jù)報(bào)傳輸延遲抖動(dòng)(Jitter)的測(cè)試由服務(wù)器端完成,客戶發(fā)送的報(bào)文數(shù)據(jù)包含有發(fā)送時(shí)間戳,服務(wù)器端根據(jù)該時(shí)間信息和接收到報(bào)文的時(shí)間戳來(lái)計(jì)算傳輸延遲抖動(dòng)。傳輸延遲抖動(dòng)反映傳輸過(guò)程中是否平滑。由于它是一個(gè)相對(duì)值,所以并不需要客戶端和服務(wù)器端時(shí)間同步。
由上介紹我們可以知道iperf3的功能增加了操作系統(tǒng)網(wǎng)絡(luò)度量的能力,而攜帶Liteos_A內(nèi)核的OpenAtom OpenHarmony(以下簡(jiǎn)稱“OpenHarmony”)操作系統(tǒng)目前還不支持這個(gè)功能,特此嘗試把iperf3移植到支持Liteos_A內(nèi)核的OpenHarmony操作系統(tǒng)中,并作此文分享一些心得。
二、iperf3移植過(guò)程
iperf3可以運(yùn)行在Linux和Windows平臺(tái)下,其使用了標(biāo)準(zhǔn)的POSIX接口,因此將iperf3移植到Liteos_A上,目前Liteos_A支持用戶態(tài)和內(nèi)核態(tài)的命令,這個(gè)也造成了移植的很大困難,所以以下將2種添加命令的方式都記錄下,供讀者參考。
1.確定庫(kù)的類型
OpenHarmony有如下幾種目標(biāo)類型:
executable: 生成可執(zhí)行文件,對(duì)于Liteos_A,在目錄/bin下可以找到可執(zhí)行文件
shared_library: 生成.dll或.so動(dòng)態(tài)鏈接庫(kù)、對(duì)于Liteos_A,在目錄/lib或者 /usr/lib下可以找到動(dòng)態(tài)庫(kù)
static_library: 生成.lib或.a靜態(tài)鏈接庫(kù)
group: 生成依賴關(guān)系組
根據(jù)以上幾種類型的描述可知,將iperf3移植成executable類型的組件最為合適。
2.添加庫(kù)到工程中
將源碼下載到Linux下并解壓,執(zhí)行./configure,生成iperf_config.h,將iperf3的源碼拷貝到OpenHarmony代碼庫(kù)中合適的位置,如下將iperf3添加到/third_party目錄下。 ? 需要注意的是非內(nèi)核態(tài)的庫(kù)不能添加到內(nèi)核的目錄下,不然編譯和調(diào)試過(guò)程中相關(guān)的頭文件可能找不到。在/vendor/廠商名/產(chǎn)品型號(hào)/config.json中的某一子系統(tǒng)下添加組件。 ?
? 在 /build/lite/components/子系統(tǒng)名.json中添加組件,如下: ?
? 3.編寫(xiě)配置BUILD.gn
? 移植的iperf3代碼目錄下需要提供一個(gè)gn文件,指明需要編譯的代碼。此文件可以通過(guò)import組件模板函數(shù)。一方面,很多引用到的頭文件需要逐個(gè)添加到系統(tǒng)BUILD.GN中去,import組件模板函數(shù)可以省去很多麻煩;另一方面,頭文件有多個(gè),最終還很難確定是哪一個(gè),使用系統(tǒng)配置好的組件模板函數(shù),可以自動(dòng)匹配。
4.程序啟動(dòng)入口:將三方庫(kù)添加到shell命令
1) 內(nèi)核態(tài)的shell功能不符合POSIX標(biāo)準(zhǔn),僅供調(diào)試使用,本文特記錄下其添加命令的方法,此方法分為靜態(tài)和動(dòng)態(tài)兩種方式,添加方式如下:
① 命令源代碼包含如下頭文件
#include "shell.h" #include "shcmd.h"
② 靜態(tài)注冊(cè)命令方式
第一步:調(diào)用SHELLCMD_ENTRY(l, cmdType, cmdKey, paraNum, cmdHook),在源文件最后增加這個(gè)調(diào)用即可。
第二步:在鏈接選項(xiàng)中添加鏈接該新增命令項(xiàng)參數(shù)。
即在kernel/liteos_a/tools/build/mk/liteos_tables_ldflags.mk中增加相應(yīng)選項(xiàng),SHELLCMD_ENTRY的第一個(gè)參數(shù)前加-u。
此方法添加的shell,在代碼編譯階段就已編譯進(jìn)去了,其實(shí)現(xiàn)原理是利用了編譯器的section特性(也是代碼模塊化的重要手段),將所有shell命令相關(guān)功能都放在一段連續(xù)的地址空間,將SHELLCMD_ENTRY宏一層層展開(kāi),即可得到下面原型。
LOS_HAL_TABLE_BEGIN(g_shellcmd, shellcmd); //段的起始tag LOS_HAL_TABLE_END(g_shellcmdEnd, shellcmd); //段的結(jié)束tag SHELLCMD_ENTRY(l,cmdType,cmdKey,paraNum,cmdHook)
如下是編譯后生成的map文件中shell段的部分,可以觀察到已經(jīng)通過(guò)此方法加入的shell命令。
③ 動(dòng)態(tài)注冊(cè)命令方式
此類方式是在代碼運(yùn)行階段動(dòng)態(tài)的注冊(cè),osCmdReg本身是一個(gè)函數(shù),在命令初始化的源代碼增加此函數(shù)調(diào)用。
UINT32 osCmdReg(CmdT ype cmdType, CHAR *cmdKey, UINT32 paraNum, CmdCallBackFunc cmdProc)函數(shù)原型在/kernel/liteos_a/shell/full/src/base/shcmd.c 可以找到,基本原理是將動(dòng)態(tài)注冊(cè)的shell命令加入到動(dòng)態(tài)shell命令鏈表空間。
2)用戶態(tài)的shell不用手動(dòng)添加
添加目標(biāo)的方式為executable,將程序下載到目標(biāo)板上,在/bin目錄下找到可執(zhí)行的文件,只要在串口助手中輸入 ./bin/可執(zhí)行文件名,內(nèi)核即可動(dòng)態(tài)加載可執(zhí)行的文件(或者輸入exec /bin/可執(zhí)行文件名)。
三、iperf3使用方式介紹
使用iperf3測(cè)試時(shí)必須將一臺(tái)主機(jī)設(shè)置為客戶端,一臺(tái)主機(jī)設(shè)置為服務(wù)器。在Linux環(huán)境或者Windows或者OpenHarmony shell交互窗口輸入iperf3 -h可以獲取iperf3的幫助信息。以下介紹幾種常見(jiàn)的使用方式:
1.iperf3測(cè)試TCP
在默認(rèn)的情況下,iperf3客戶端與指定的監(jiān)聽(tīng)5201端口的iperf3服務(wù)器建立一個(gè)TCP會(huì)話。
服務(wù)端:iperf3 -s 客戶端:iperf3 -c 服務(wù)器IP (默認(rèn)測(cè)試10秒),使用t來(lái)設(shè)置測(cè)試時(shí)間,單位是秒。 例如:iperf3 -c 192.168.99.74 -t 20運(yùn)行結(jié)果如下:


當(dāng)把UDP報(bào)文大小設(shè)置可以將整個(gè)報(bào)文放入IP層的包(packet)內(nèi)時(shí),那么UDP所測(cè)得的報(bào)文丟失數(shù)據(jù)即為IP層包的丟失數(shù)據(jù),這提供了一個(gè)有效的測(cè)試包丟失情況的方法。
數(shù)據(jù)報(bào)傳輸延遲抖動(dòng)(Jitter)的測(cè)試由服務(wù)器端完成,客戶發(fā)送的報(bào)文數(shù)據(jù)包含有發(fā)送時(shí)間戳,服務(wù)器端根據(jù)該時(shí)間信息和接收到報(bào)文的時(shí)間戳來(lái)計(jì)算傳輸延遲抖動(dòng)。傳輸延遲抖動(dòng)反映傳輸過(guò)程中是否平滑。由于它是一個(gè)相對(duì)值,所以并不需要客戶端和服務(wù)器端時(shí)間同步。測(cè)試過(guò)程如下:
服務(wù)端:iperf3 -s -p 6868 (設(shè)定服務(wù)端監(jiān)聽(tīng)6868端口) Liteos_A shell客戶端:./bin/iperf3 -c 172.17.5.159 -p 6868 -u -b 100M測(cè)試結(jié)果:


- 帶寬:通過(guò)TCP測(cè)試來(lái)量度
3.反向帶寬測(cè)試
服務(wù)端使用的命令不變,客戶端需要加上參數(shù)-R,在幫助信息中,可以看到-R的信息是run in reverse mode (server sends, client receives)
服務(wù)端:iperf3 -s -p 6868 客戶端:./bin/iperf3 -c 172.17.5.159 -p 6868 -u -b 100M -R測(cè)試結(jié)果如下:


服務(wù)端:iperf3 -s -p 6868 客戶端:./bin/iperf3 -c 172.17.5.159 -p 6868-u-b100M-bidir測(cè)試結(jié)果如下:


四、注意事項(xiàng)和遇到的問(wèn)題及解決方法
1. Hi3516有三種下載程序的方式:串口、USB、網(wǎng)口轉(zhuǎn)USB。推薦使用USB來(lái)下載程序,使用串口來(lái)調(diào)試程序。
2. DevEco Device Tool工具使用USB燒錄Hi3516DV300鏡像時(shí)失敗,怎么解決? ? 解決措施: 出現(xiàn)這個(gè)問(wèn)題,主要是因?yàn)殚_(kāi)發(fā)者將Device Tool工具安裝在系統(tǒng)盤(pán)符,在燒錄大文件時(shí)會(huì)因?yàn)闆](méi)有權(quán)限導(dǎo)致失敗,可以根據(jù)以下操作解決: ●在Windows平臺(tái)找到安裝目錄,如圖。鼠標(biāo)右鍵,選中屬性。 ●?依次操作,步驟5將紅框中兩個(gè)選項(xiàng)都勾選上。 ?
? 3. Hi3516如果攜帶操作系統(tǒng)是支持Linux內(nèi)核的OpenHarmony,第一次下載時(shí),需要格式化,下載完成后,系統(tǒng)啟動(dòng)到boot,就不會(huì)引導(dǎo)整個(gè)系統(tǒng)應(yīng)用程序,這時(shí)需要點(diǎn)擊如下菜單,然后重新拔插USB才能進(jìn)入整個(gè)系統(tǒng)。 ?
? 4. 在編寫(xiě).gn文件時(shí),如果三方組件為executable,那么第三方庫(kù)代碼中需要有唯一個(gè)入口main函數(shù),最終生成一個(gè)可執(zhí)行的命令。 5. iperf有大版本1,2,3,目前最新的是iperf3,不同的版本間命令參數(shù)不同,工作機(jī)制有所不同,所以在測(cè)試時(shí),服務(wù)端和客戶端要求使用相同的大版本。例如iperf3服務(wù)端不支持iperf的-u,-命令。 6. 在使用iperf3進(jìn)行測(cè)試過(guò)程中,需要關(guān)閉防火墻,不然可能不能進(jìn)行正常測(cè)試,可以提前使用ping測(cè)試一下網(wǎng)絡(luò)是否已通。 7. 公司網(wǎng)絡(luò)端的控制也會(huì)對(duì)測(cè)試造成影響,如果測(cè)試中發(fā)現(xiàn)發(fā)送和接收到的數(shù)據(jù)一直是0,則可能是網(wǎng)絡(luò)控制端進(jìn)行了控制,在拔掉外網(wǎng)絡(luò)的情況,測(cè)試出來(lái)的結(jié)果就會(huì)很穩(wěn)定。 8. Hi3516主板作為服務(wù)端,輸入iperf3 -s,然后在PC機(jī)上啟動(dòng)客戶端進(jìn)行測(cè)試,發(fā)現(xiàn)根本不能進(jìn)行正常測(cè)試,原因也是公司網(wǎng)絡(luò)控制導(dǎo)致,解決辦法是將要測(cè)試的兩個(gè)網(wǎng)絡(luò)接口,接到同一交換機(jī)下,然后拔掉外網(wǎng)的網(wǎng)線,可以進(jìn)行正常測(cè)試;或者需要IT開(kāi)發(fā)權(quán)限,當(dāng)然如果不是在公司特定網(wǎng)絡(luò)環(huán)境下,這個(gè)現(xiàn)象是不會(huì)出現(xiàn)的。 9. Hi3516需要設(shè)置網(wǎng)絡(luò)才能進(jìn)行測(cè)試,可以使用命令ifconfig來(lái)設(shè)置,例如: ifconfig eth0?172.17.5.253 netmask 255.255.254.0 gateway 172.17.4.1 10. MSS在OpenHarmony的底層LWIP不支持,在iperf_connect函數(shù)中調(diào)用getsockopt(test->ctrl_sck, IPPROTO_TCP, TCP_MAXSEG, &opt, &len),會(huì)通過(guò)系統(tǒng)調(diào)用到達(dá)kernel層中的/kernel/liteos_a/compat/posix/src/socket.c, 最終走到底層LWIP的lwip_getsockopt_impl接口,在level IPPROTO_TCP下,對(duì)于分支TCP_MAXSEG,沒(méi)有實(shí)現(xiàn),解決辦法是先屏蔽iperf3對(duì)此處的操作。同樣在調(diào)用setsockopt(s, SOL_SOCKET, SO_SNDBUF, &opt, sizeof(opt))時(shí),SO_SNDBUF分支在LWIP也未實(shí)現(xiàn),先屏蔽此處,將發(fā)送緩沖區(qū)設(shè)置成和接收緩沖區(qū)同樣的大小。 11. Liteos_A未實(shí)現(xiàn)延時(shí)刪除,所以調(diào)用unlink時(shí)會(huì)出錯(cuò),目前處理是先屏蔽此處。 12. Liteos_A對(duì)fprintf的實(shí)現(xiàn)也不如Linux,Windows好,所以對(duì)help命令輸出到stdout上,長(zhǎng)字串顯示不出來(lái),解決辦法是使用fputs替換fprintf。
五、總結(jié)
本文從iperf3的工作原理、移植過(guò)程、使用方式、注意事項(xiàng)四個(gè)方面介紹了將iperf3移植到支持Liteos_A內(nèi)核的OpenHarmony操作系統(tǒng)中的方法,希望本篇文章對(duì)開(kāi)發(fā)者有所幫助。 關(guān)于OpenHarmony內(nèi)核的內(nèi)容,之前我還介紹了內(nèi)核對(duì)象隊(duì)列的算法、OpenHarmony LiteOS-M內(nèi)核事件的運(yùn)作機(jī)制,以及內(nèi)核IPC機(jī)制數(shù)據(jù)結(jié)構(gòu),感興趣的讀者可以點(diǎn)擊閱讀:《OpenHarmony——內(nèi)核對(duì)象隊(duì)列之算法詳解(上)》、《OpenHarmony——內(nèi)核對(duì)象隊(duì)列之算法詳解(下)》、《OpenHarmony——內(nèi)核對(duì)象事件之源碼詳解》、《OpenHarmony——內(nèi)核IPC機(jī)制數(shù)據(jù)結(jié)構(gòu)解析》。
-
OpenHarmony
+關(guān)注
關(guān)注
29文章
3854瀏覽量
18639
原文標(biāo)題:OpenHarmony Liteos_A內(nèi)核之iperf3移植心得
文章出處:【微信號(hào):gh_e4f28cfa3159,微信公眾號(hào):OpenAtom OpenHarmony】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
評(píng)論