?前言
本文適用開發環境如下:
Windows開發環境:Windows 7 64bit、Windows 10 64bit
虛擬機:VMware15.5.5
Linux開發環境:Ubuntu18.04.464bit
LinuxSDK:T113_Tina5.0-V1.0(Linux)
Kernel:Linux-RT-5.4.61
我司提供的Linux-RT內核應用了開源的RT PREEMPT機制進行補丁。PREEMPT_RT補丁的關鍵是最小化不可搶占的內核代碼量,同時最小化必須更改的代碼量,以便提供這種附加的可搶占性。PREEMPT_RT補丁利用Linux內核的SMP功能來添加這種額外的搶占性,而不需要完整的內核重寫。Linux-RT內核增加PREEMPT_RT補丁后,增加了系統響應的確定性和實時性,但是代價是CPU性能降低。
Linux-RT內核與普通Linux內核相比,幾個主要的相同之處是:
具有相同的開發生態系統,包括相同工具鏈、文件系統和安裝方法,以及相同的POSIX API等。
仍然存在內核空間和用戶空間的劃分。
Linux應用程序在用戶空間中運行。
Linux-RT內核與普通Linux內核在常規編程方式上的幾個主要不同之處是:
調度策略。
優先級和內存控制。
基于Linux-RT內核的應用程序使用了調度策略后,系統將根據調度策略對其進行調優。
Linux系統實時性測試
本章節主要介紹使用Cyclictest延遲檢測工具測試Linux系統實時性的方法。Cyclictest是rt-tests測試套件下的一個測試工具,也是rt-tests下使用最廣泛的測試工具,一般主要用來測試內核的延遲,從而判斷內核的實時性。
我司默認使用是的Linux內核,同時提供了Linux-RT內核位于產品資料“4-軟件資料LinuxKernelimagelinux-5.4-[版本號]-[Git系列號]nand”目錄下,請按照如下方法替換為Linux-RT內核。
將Linux-RT內核鏡像boot-rt.fex和Linux-RT內核配套的內核模塊目錄modules-rt拷貝至Ubuntu工作目錄下,執行如下命令,進入modules-rt目錄下將Linux-RT內核模塊壓縮包解壓。
Host# cd modules-rt/
Host# tar -zxf 5.4.61-rt37-gb1bd4aa.tar.gz
圖 1
將內核鏡像和解壓后的內核模塊拷貝至評估板文件系統任意目錄下。執行如下命令,分別替換內核鏡像和內核模塊至Linux系統啟動卡,評估板重啟生效。
備注:若使用eMMC配置評估板,請使用emmc目錄下的Linux-RT內核鏡像和Linux-RT內核模塊,并修改Linux系統啟動卡對應設備節點為"/dev/mmcblk1p4"。
Target# dd if=boot-rt.fexof=/dev/mmcblk0p4
Target# rm /lib/modules/* -rf
Target# cp 5.4.61-rt37-gb1bd4aa/ /lib/modules/ -r
Target# sync
Target# reboot
圖 2
圖 3Linux-RT內核
Cyclictest工具簡介
Cyclictest常用于實時系統的基準測試,是評估實時系統相對性能的最常用工具之一。Cyclictest反復測量并精確統計線程的實際喚醒時間,以提供有關系統的延遲信息。它可測量由硬件、固件和操作系統引起的實時系統的延遲。
為了測量延遲,Cyclictest運行一個非實時主線程(調度類SCHED_OTHER),該線程以定義的實時優先級(調度類SCHED_FIFO)啟動定義數量的測量線程。測量線程周期性地被一個到期的計時器(循環報警)所定義的間隔喚醒,隨后計算有效喚醒時間,并通過共享內存將其傳遞給主線程。主線程統計延遲值并打印最小、最大和平均延遲時間。
參考鏈接:https://wiki.linuxfoundation.org/realtime/documentation/howto/tools/cyclictest/start?s[]=cyclictest。
使用Cyclictest測試系統實時性
本次測試對比基于Linux-RT-5.4.61內核和Linux-5.4.61內核的Linux系統實時性。參照如下步驟,結合Iperf和Cyclictest工具測試系統的實時性。此處使用Iperf工具不斷觸發系統中斷,提高中斷處理負載,以便更好測試系統實時特性。
在Ubuntu執行如下命令查看IP地址,并以服務器模式啟動Iperf測試。
Host# ifconfig
Host# iperf-s
圖 4
分別使用Linux-RT-5.4.61內核和Linux-5.4.61內核啟動評估板,執行如下命令以客戶端模式啟動Iperf,并連接至服務器端(Ubuntu系統)。"192.168.1.209"為Ubuntu的IP地址,"-t3600"指定測試時間為3600秒,"&"表示讓程序在后臺運行。
Target# iperf -c 192.168.1.209 -d -t3600 > /dev/null 2>&1 &
圖 5
執行如下命令使用Cyclictest程序測試系統實時性。
Target# cyclictest -t5 -p98 -m -n -D10m

圖 7Linux-5.4.61內核測試結果
表 1Cyclictest測試結果說明
對比測試數據,可看到基于Linux-RT-5.4.61內核的系統的延遲更加穩定,平均延遲、最大延遲更低,系統實時性更佳。
Cyclictest命令參數解析可執行"cyclictest --help"查看,如下圖所示。
圖 8
圖 9
Linux-RT性能測試
本次測試分別在CPU空載、滿負荷(運行stress壓力測試工具)、隔離CPU核心的情況下,對比評估Linux-RT內核的系統實時性。
CPU空載狀態
評估板上電啟動,進入評估板文件系統執行如下命令,修改內核printk日志等級,避免內核打印信息影響實時測試。
Target# echo 1 > /proc/sys/kernel/printk
調整內存分配策略為“2”,禁用內存過度使用。避免出現OOM(Out-of-Memory) Killer攻擊某些進程而產生延遲,影響測試結果。
Target# echo 2 > /proc/sys/vm/overcommit_memory
圖 10
執行如下命令,基于CPU空載狀況下測試系統的實時性。測試指令需運行12小時,請保持評估板長時間穩定工作,測試完成后將生成統計結果output文件。
Target# cyclictest -m -n -Sp99 -i1000 -h800 -D12h -q > output
圖 11
參數解析:
-m:鎖定當前和將來的內存分配;
-n:使用clock_nanosleep;
-S:采用標準SMP測試;
-p:設置線程優先級;
-i:設置線程的基本間隔;
-h:運行后將延遲直方圖轉儲至標準輸出,亦可指定要跟蹤的最大延時時間(以微秒為單位);
-D:指定測試運行時長,附加m(分鐘)、h(小時)、d(天)指定;
-q:運行時不打印相關信息;
CPU滿負荷狀態
評估板上電啟動,進入評估板文件系統執行如下命令,修改內核printk日志等級,避免內核打印信息影響實時測試。
Target# echo 1 > /proc/sys/kernel/printk
調整內存分配策略為“2”,禁用內存過度使用。避免出現OOM(Out-of-Memory) Killer攻擊某些進程而產生延遲,影響測試結果。
Target# echo 2 > /proc/sys/vm/overcommit_memory
圖 12
執行如下命令,運行stress壓力測試工具,使得CPU處于滿負荷狀態。再使用cyclictest工具測試CPU滿負荷狀態下的系統實時性能。測試指令需運行12小時,請保持評估板長時間穩定工作,測試完成后將生成統計結果output文件。
Target# stress --cpu 2--io 2--vm 2--vm-bytes 32M --timeout43200s &
Target# cyclictest -m -n -Sp99 -i1000 -h800 -D12h -q > output
圖 13
參數解析:
--cpu:指定壓力測試的進程個數;
--io:指定I/O測試的進程個數;
--vm:指定內存測試的進程個數;
--vm-bytes:指定每個內存測試進程中分配內存的大小;
--timeout:指定測試時長;
隔離CPU核心狀態
本次測試以隔離CPU1核心為例,通過降低系統上所運行的其他進程對隔離CPU1產生的延遲影響,確保CPU1進程的正常運行,進而評估Linux-RT內核的系統實時性。
評估板上電啟動后,在U-Boot倒計時結束之前按下空格鍵進入U-Boot命令行模式,執行如下命令,修改環境變量,隔離CPU1核心。
U-Boot# setenv setargs_sd setenv bootargs clk_ignore_unused initcall_debug=${initcall_debug} console=${console} loglevel=${loglevel} root=${sd_root} init=${init} partitions=${partitions} cma=${cma} snum=${snum} mac_addr=${mac} wifi_mac=${wifi_mac} bt_mac=${bt_mac} specialstr=${specialstr} gpt=1 isolcpus=1
U-Boot# setenv setargs_nand_ubi setenv bootargs ubi.mtd=${mtd_name} clk_ignore_unused initcall_debug=${initcall_debug} console=${console} loglevel=${loglevel} root=${nand_root} rootfstype=${rootfstype} init=${init} partitions=${partitions} cma=${cma} snum=${snum} mac_addr=${mac} wifi_mac=${wifi_mac} bt_mac=${bt_mac} specialstr=${specialstr} gpt=1 isolcpus=1
U-Boot# saveenv
U-Boot# reset
圖 14
備注:若為eMMC配置評估板,請執行如下命令,修改環境變量,隔離CPU1核心。
U-Boot# setenv setargs_emmc setenv bootargs clk_ignore_unused initcall_debug=${initcall_debug} console=${console} loglevel=${loglevel} root=${emmc_root} init=${init} partitions=${partitions} cma=${cma} snum=${snum} mac_addr=${mac} wifi_mac=${wifi_mac} bt_mac=${bt_mac} specialstr=${specialstr} gpt=1 isolcpus=1
U-Boot# setenv setargs_sd setenv bootargs clk_ignore_unused initcall_debug=${initcall_debug} console=${console} loglevel=${loglevel} root=${sd_root} init=${init} partitions=${partitions} cma=${cma} snum=${snum} mac_addr=${mac} wifi_mac=${wifi_mac} bt_mac=${bt_mac} specialstr=${specialstr} gpt=1 isolcpus=1
U-Boot# saveenv
U-Boot# reset
進入評估板文件系統,執行如下命令,修改內核printk日志等級,避免內核打印信息影響實時測試。
Target# echo 1 > /proc/sys/kernel/printk
調整內存分配策略為“2”,禁用內存過度使用。避免出現OOM(Out-of-Memory) Killer攻擊某些進程而產生延遲,影響測試結果。
Target# echo 2 > /proc/sys/vm/overcommit_memory
圖 15
執行如下命令,運行stress壓力測試工具,使得CPU處于滿負荷狀態。再使用taskset工具將cyclictest測試程序運行在CPU1核心,測試CPU1核心滿負荷狀態下的系統實時性能。測試指令需運行12小時,請保持評估板長時間穩定工作,測試完成后將生成統計結果output文件。
Target# stress --cpu 2 --io 2 --vm 2 --vm-bytes 32M --timeout 43200s &
Target# taskset -c 0,1 cyclictest -m -n -Sp99 -i1000 -h800 -D12h -q > output
圖 16
統計結果分析
我司已提供腳本文件get_histogram.sh用于繪制統計結果直方圖,位于產品資料“4-軟件資料Demolinux-rt-demosCyclictestbin”目錄下,請將該腳本文件拷貝至Ubuntu工作目錄下。
圖 17
在Ubuntu系統執行如下命令,安裝gnuplot工具。
Host# sudo apt-get install gnuplot
圖 18
CPU空載狀態
請將CPU空載狀態下的統計結果output文件拷貝至Windows工作目錄,使用Windows文本工具打開該文件并拖動至文件末尾,可查看Linux系統每個核心(CPU0~CPU1)的最小延遲(MinLatencies)、平均延遲(AvgLatencies)、最大延遲(MaxLatencies)統計結果。
圖 19
請將CPU空載狀態下的統計結果output文件拷貝至Ubuntu,存放在get_histogram.sh同一目錄下。執行如下命令生成直方圖文件plot.png,請將其拷貝至Windows下并打開。
Host# ./get_histogram.sh
圖 20
圖 21
根據測試結果output文件數據以及結合直方圖,可得主要數據如下表。本次測試中,CPU1核心Max Latencies值最大,為59us,CPU0核心的Max Latencies值最小,為52us。
備注:測試數據與實際測試環境有關,僅供參考。
表 2
CPU滿負荷狀態
參考如上方法,分析CPU滿負荷狀態下的統計結果如下所示。本次測試中,CPU0核心Max Latencies值最大,為91us,CPU1核心的Max Latencies值最小,為75us。
圖 22
表 3
隔離CPU核心狀態
參考如上方法,分析隔離CPU核心狀態下的統計結果如下所示。本次測試中,CPU0核心Max Latencies值最大,為61us,隔離CPU1核心的Max Latencies值最小,為55us。
圖 23
表 4
根據CPU空載、CPU滿負荷、隔離CPU核心三種狀態的測試結果可知:當程序指定至隔離的CPU1核心上運行時,Linux系統延遲最低,可有效提高系統實時性。故推薦對實時性要求較高的程序(功能)指定至隔離的CPU核心運行。
rt_gpio_ctrl案例
案例說明
通過創建一個基本的實時線程,在線程內觸發LED的電平翻轉,同時程序統計實時線程的調度延時,并通過示波器測出LED電平兩次翻轉的時間間隔。由于程序默認以最高優先級運行,為避免CPU資源被程序完全占用,導致系統被掛起,因此在程序中增加100us的延時。程序原理大致如下:
(1)在Linux-RT內核上創建、使用實時線程。
(2)實時線程中,計算出觸發LED電平翻轉的系統調度延時。
案例測試
本小節測試以隔離CPU1核心為例,通過降低系統上所運行的其他進程對隔離CPU1產生的延遲影響,確保CPU1進程的正常運行,進而評估Linux-RT內核的系統實時性。
評估板上電啟動后,在U-Boot倒計時結束之前按下空格鍵進入U-Boot命令行模式,執行如下命令,修改環境變量,隔離CPU1核心。
U-Boot# setenv setargs_sd setenv bootargs clk_ignore_unused initcall_debug=${initcall_debug} console=${console} loglevel=${loglevel} root=${sd_root} init=${init} partitions=${partitions} cma=${cma} snum=${snum} mac_addr=${mac} wifi_mac=${wifi_mac} bt_mac=${bt_mac} specialstr=${specialstr} gpt=1 isolcpus=1
U-Boot# setenv setargs_nand_ubi setenv bootargs ubi.mtd=${mtd_name} clk_ignore_unused initcall_debug=${initcall_debug} console=${console} loglevel=${loglevel} root=${nand_root} rootfstype=${rootfstype} init=${init} partitions=${partitions} cma=${cma} snum=${snum} mac_addr=${mac} wifi_mac=${wifi_mac} bt_mac=${bt_mac} specialstr=${specialstr} gpt=1 isolcpus=1
U-Boot# saveenv
U-Boot# reset
圖 24
將案例bin目錄下的可執行文件拷貝至評估板文件系統,并執行如下命令運行測試程序,再按"Ctrl + C"退出測試,串口終端將打印程序統計的延遲數據,如下圖所示。
Target# sysctl kernel.sched_rt_runtime_us=-1
Target# taskset -c 1 ./rt_gpio_ctrl -t 10 -d 100
圖 25
同時使用示波器捕捉LED兩次電平翻轉之間的間隔就對應上線程調度的延遲,測試點為R46電阻一端。
圖 26
算出電平兩次翻轉的時間間隔為?x=104us,如下圖所示。由于程序中增加了100us的時間延時,因此實際延時時應為:104us– 100us= 4us,與程序統計打印的Latency results平均值5us相近。
圖 27
案例編譯
將產品資料“4-軟件資料Demolinux-rt-demosrt_gpio_ctrlsrc”案例源碼拷貝至Ubuntu。進入案例源碼目錄,執行如下命令,編譯案例生成可執行文件。
Host# CC=/home/tronlong/T113/tina5.0_v1.0/out/t113_i/tlt113-evm-nand/buildroot/buildroot/host/usr/bin/arm-linux-gnueabi-gccCXX=/home/tronlong/T113/tina5.0_v1.0/out/t113_i/tlt113-evm-nand/buildroot/buildroot/host/usr/bin/arm-linux-gnueabi-g++ make
備注:若使用eMMC配置評估板,請將命令中的"tlt113-evm-nand"改為"tlt113-evm-emmc"。
圖 28
關鍵代碼說明
(1)創建一個基于PREEMPT_RT的實時任務,具體操作包括內存鎖定、線程堆棧內存設置、調度策略和優先級配置等。
圖 29
(2)在線程中打開LED文件節點,并對LED狀態進行翻轉。
圖 30
(3)統計調度時間延時情況。
圖 31
?
審核編輯 黃宇
-
Linux
+關注
關注
88文章
11788瀏覽量
219347 -
開發板
+關注
關注
26文章
6358瀏覽量
119625
發布評論請先 登錄
【米爾-全志T113-i開發板試用】米爾-全志T113-i開發環境搭建
G2D圖像處理硬件調用和測試-基于米爾-全志T113-i開發板
國產!全志T113-i 雙核Cortex-A7@1.2GHz 工業開發板—DSP案例開發手冊
國產!全志T113-i 雙核Cortex-A7@1.2GHz 工業開發板—ARM + DSP、RISC-V核間通信開發案例
國產!全志T113-i 雙核Cortex-A7@1.2GHz 工業開發板—Linux系統使用手冊(二)
國產!全志T113-i 雙核Cortex-A7@1.2GHz 工業開發板—Linux系統使用手冊(三)
國產!全志T113-i 雙核Cortex-A7@1.2GHz 工業開發板—Linux-RT應用開發案例
評論