前  言

本文檔主要介紹Linux-RT實時內核的性能測試方法,以及使用Linux-RT內核進行系統開發和應用開發的使用説明。

開發環境

Windows開發環境:Windows10 64bit

Linux開發環境:VMware16.2.5、Ubuntu22.04.4 64bit

LinuxSDK開發包:LinuxSDK-[版本號](基於SDK_2025.1)

交叉編譯工具鏈:

應用開發:gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu

U-Boot、內核開發:gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu

評估板系統版本:U-Boot-2021.01、Linux-6.1.111、Buildroot-2022.02

備註:本文基於8GByte eMMC、1GByte DDR配置核心板進行演示。

術語表

為便於閲讀,下表對文檔出現的關鍵術語進行解釋;對於廣泛認同釋義的術語,在此不做註釋。

 

基於 DR1M90 的 Linux-RT 內核開發:從編譯配置到 GPIO / 按鍵應用實現(1)_硬件開發

 

注意事項

我司默認使用的是Linux內核,同時提供了Linux-RT內核,位於產品資料“4-軟件資料\Linux\Kernel\image\linux-6.1.111-[版本號]-[Git系列號]\”目錄下。請按照《Linux系統開發手冊》替換Kernel鏡像章節中的方法替換Linux-RT內核。

 

Linux-RT介紹

我司提供的Linux-RT內核應用了開源的RT PREEMPT機制進行補丁。PREEMPT_RT補丁的關鍵是最小化不可搶佔的內核代碼量,同時最小化必須更改的代碼量,以便提供這種附加的可搶佔性。Linux-RT內核增加PREEMPT_RT補丁後,增加了系統響應的確定性和實時性,但是代價是CPU性能降低。

Linux-RT內核與普通Linux內核相比,幾個主要的相同之處是:

(1)具有相同的開發生態系統,包括相同工具鏈、文件系統和安裝方法,以及相同的POSIX API等。

(2)仍然存在內核空間和用户空間的劃分。

(3)Linux應用程序在用户空間中運行。

Linux-RT內核與普通Linux內核在常規編程方式上的幾個主要不同之處是:

(1)調度策略。

(2)優先級和內存控制。

(3)基於Linux-RT內核的應用程序使用了調度策略後,系統將根據調度策略對其進行調優。


Linux系統實時性測試

本章節主要介紹使用Cyclictest延遲檢測工具測試Linux系統實時性的方法。Cyclictest是rt-tests測試套件下的一個測試工具,也是rt-tests下使用最廣泛的測試工具,一般主要用來測試內核的延遲,從而判斷內核的實時性。

Cyclictest常用於實時系統的基準測試,是評估實時系統相對性能的最常用工具之一。Cyclictest反覆測量並精確統計線程的實際喚醒時間,以提供有關係統的延遲信息。它可測量由硬件、固件和操作系統引起的實時系統的延遲。

為了測量延遲,Cyclictest運行一個非實時主線程(調度類SCHED_OTHER),該線程以定義的實時優先級(調度類SCHED_FIFO)啓動定義數量的測量線程。測量線程週期性地被一個到期的計時器(循環報警)所定義的間隔喚醒,隨後計算有效喚醒時間,並通過共享內存將其傳遞給主線程。主線程統計延遲值並打印最小、最大和平均延遲時間。


Linux、Linux-RT實時性對比

本次測試結合Iperf和Cyclictest工具,對比測試基於Linux-RT-6.1.111內核和Linux-6.1.111內核的系統實時性能。此處使用Iperf工具不斷觸發系統中斷,提高中斷處理負載,以便更好測試系統實時特性。

在Ubuntu執行如下命令查看IP地址,並以服務器模式啓動Iperf測試。

Host# ifconfig

Host# iperf3 -s

 

基於 DR1M90 的 Linux-RT 內核開發:從編譯配置到 GPIO / 按鍵應用實現(1)_開發板_02

圖 1

 

分別使用Linux-RT-6.1.111內核和Linux-6.1.111內核啓動評估板進行測試。執行如下命令以客户端模式啓動Iperf,並連接至服務器端(Ubuntu系統)。"192.168.13.81"為Ubuntu的IP地址,"-t3600"設置測試時間為3600秒,"&"表示讓程序在後台運行。

Target# iperf3 -c 192.168.13.81 -d -t3600 > /dev/null 2>&1 &

 

基於 DR1M90 的 Linux-RT 內核開發:從編譯配置到 GPIO / 按鍵應用實現(1)_硬件開發_03

圖 2

 

評估板文件系統默認已提供Cyclictest工具,進入評估板文件系統,執行如下命令使用Cyclictest工具測試系統實時性。

Target# cyclictest -t5 -p98 -m -D10m

 

基於 DR1M90 的 Linux-RT 內核開發:從編譯配置到 GPIO / 按鍵應用實現(1)_開發板_04

圖 3 Linux-RT-6.1.111內核測試結果

 

基於 DR1M90 的 Linux-RT 內核開發:從編譯配置到 GPIO / 按鍵應用實現(1)_工業控制_05

圖 4 Linux-6.1.111內核測試結果

 

基於 DR1M90 的 Linux-RT 內核開發:從編譯配置到 GPIO / 按鍵應用實現(1)_工業控制_06

 

對比測試數據,可看到基於Linux-RT-6.1.111內核的系統的延遲更加穩定,平均延遲、最大延遲更低,系統實時性更佳。

Cyclictest命令參數解析可執行"cyclictest --help"查看,如下圖所示。

 

基於 DR1M90 的 Linux-RT 內核開發:從編譯配置到 GPIO / 按鍵應用實現(1)_工業控制_07

圖 5

 

基於 DR1M90 的 Linux-RT 內核開發:從編譯配置到 GPIO / 按鍵應用實現(1)_硬件開發_08

圖 6

 

Linux-RT性能測試

本次測試分別在CPU空載、滿負荷(運行stress壓力測試工具)、隔離CPU核心的情況下,對比評估Linux-RT內核的系統實時性。

CPU空載狀態

評估板上電啓動,進入評估板文件系統,執行如下命令修改內核printk日誌等級,避免內核打印信息影響實時測試。

Target# echo 1 > /proc/sys/kernel/printk

 

基於 DR1M90 的 Linux-RT 內核開發:從編譯配置到 GPIO / 按鍵應用實現(1)_硬件開發_09

圖 7

 

調整內存分配策略為"2",禁用內存過度使用。避免出現OOM(Out-of-Memory) Killer終止某些進程而產生延遲,影響測試結果。

Target# echo 2 > /proc/sys/vm/overcommit_memory

 

基於 DR1M90 的 Linux-RT 內核開發:從編譯配置到 GPIO / 按鍵應用實現(1)_開發板_10

圖 8

 

執行如下命令,基於CPU空載狀況下測試系統的實時性。測試指令需運行12小時,請保持評估板長時間穩定工作,測試完成後將生成統計結果no_load_output文件。

Target# cyclictest -m -Sp99 -i1000 -h800 -D12h -q > no_load_output

 

基於 DR1M90 的 Linux-RT 內核開發:從編譯配置到 GPIO / 按鍵應用實現(1)_硬件開發_11

圖 9

 

參數解析:

-m:鎖定當前和將來的內存分配;

-S:採用標準SMP測試;

-p:設置線程優先級;

-i:設置線程的基本間隔;

-h:運行後將延遲直方圖轉儲至標準輸出,亦可指定要跟蹤的最大延時時間(以微秒為單位);

-D:指定測試運行時長,附加m(分鐘)、h(小時)、d(天)指定;

-q:運行時不打印相關信息;

CPU滿負荷狀態

評估板上電啓動,進入評估板文件系統執行如下命令,修改內核printk日誌等級,避免內核打印信息影響實時測試。

Target# echo 1 > /proc/sys/kernel/printk

 

基於 DR1M90 的 Linux-RT 內核開發:從編譯配置到 GPIO / 按鍵應用實現(1)_嵌入式開發_12

圖 10

 

調整內存分配策略為"2",禁用內存過度使用。避免出現OOM(Out-of-Memory) Killer攻擊某些進程而產生延遲,影響測試結果。

Target# echo 2 > /proc/sys/vm/overcommit_memory

 

基於 DR1M90 的 Linux-RT 內核開發:從編譯配置到 GPIO / 按鍵應用實現(1)_開發板_13

圖 11

 

執行如下命令,運行stress壓力測試工具,使得CPU處於滿負荷狀態。

Target# stress-ng --cpu 2 --cpu-method=all --io 2 --vm 2 --vm-bytes 32M --timeout 43200s &

 

基於 DR1M90 的 Linux-RT 內核開發:從編譯配置到 GPIO / 按鍵應用實現(1)_硬件開發_14

圖 12

 

參數解析:

--cpu:指定壓力測試的進程個數;

--cpu-method:指定CPU壓力測試的方式;

--io:指定I/O測試的進程個數;

--vm:指定內存測試的進程個數;

--vm-bytes:指定每個內存測試進程中分配內存的大小;

--timeout:指定測試時長;

使用cyclictest工具測試CPU滿負荷狀態下的系統實時性能。測試指令需運行12小時,請保持評估板長時間穩定工作,測試完成後將生成統計結果overload_output文件。

Target# cyclictest -m -Sp99 -i1000 -h800 -D12h -q > overload_output

 

基於 DR1M90 的 Linux-RT 內核開發:從編譯配置到 GPIO / 按鍵應用實現(1)_嵌入式開發_15

圖 13

 

隔離CPU核心狀態

本次測試以隔離CPU1核心為例,通過降低系統上所運行的其他進程對隔離CPU1產生的延遲影響,確保CPU1進程的正常運行,進而評估Linux-RT內核的系統實時性。

評估板上電啓動後,在U-Boot倒計時結束之前長按"Ctrl + C"進入U-Boot命令行模式,執行如下命令,修改環境變量,隔離CPU1核心。

U-Boot# setenv mmc_boot 'if mmc dev ${devnum}; then devtype=mmc; if test ${devnum} -eq 0; then setenv bootargs '"'"'cnotallow=ttyS1,115200n8 earlycnotallow=uart,mmio32,0xf8401000 loglevel=8 root=/dev/mmcblk0p2 rw rootfstype=ext4 rootwait isolcpus=1'"'"'; fi; if test ${devnum} -eq 1; then setenv bootargs '"'"'cnotallow=ttyS1,115200n8 earlycnotallow=uart,mmio32,0xf8401000 loglevel=8 root=/dev/mmcblk1p2 rw rootfstype=ext4 rootwait isolcpus=1'"'"'; fi; ext4load mmc ${devnum}:2 ${kernel_addr_r} ${bootdir}/${kernel_image}; ext4load mmc ${devnum}:2 ${fdt_addr_r} ${bootdir}/${devicetree_image}; bootm ${kernel_addr_r} - ${fdt_addr_r}; run scan_dev_for_boot_part2; fi'

U-Boot# saveenv

U-Boot# reset

 

基於 DR1M90 的 Linux-RT 內核開發:從編譯配置到 GPIO / 按鍵應用實現(1)_工業控制_16

圖 14

 

如需恢復U-Boot環境變量,在U-Boot命令行模式執行以下命令。

U-Boot# env default -a -f

U-Boot# saveenv

U-Boot# reset

 

基於 DR1M90 的 Linux-RT 內核開發:從編譯配置到 GPIO / 按鍵應用實現(1)_硬件開發_17

圖 15

 

進入評估板文件系統,執行如下命令,查看環境變量是否設置成功。

Target# cat /proc/cmdline

 

基於 DR1M90 的 Linux-RT 內核開發:從編譯配置到 GPIO / 按鍵應用實現(1)_嵌入式開發_18

圖 16

 

執行如下命令,修改內核printk日誌等級,避免內核打印信息影響實時測試。

Target# echo 1 > /proc/sys/kernel/printk

 

基於 DR1M90 的 Linux-RT 內核開發:從編譯配置到 GPIO / 按鍵應用實現(1)_嵌入式開發_19

圖 17

 

調整內存分配策略為"2",禁用內存過度使用。避免出現OOM(Out-of-Memory) Killer攻擊某些進程而產生延遲,影響測試結果。

Target# echo 2 > /proc/sys/vm/overcommit_memory

 

基於 DR1M90 的 Linux-RT 內核開發:從編譯配置到 GPIO / 按鍵應用實現(1)_嵌入式開發_20

圖 18

 

執行如下命令,運行stress壓力測試工具,使得CPU處於滿負荷狀態。

Target# stress-ng --cpu 2 --cpu-method=all --io 2 --vm 2 --vm-bytes 32M --timeout 43200s &

 

基於 DR1M90 的 Linux-RT 內核開發:從編譯配置到 GPIO / 按鍵應用實現(1)_工業控制_21

圖 19

 

因CPU1核心被隔離,程序默認不會在CPU1上運行,需使用taskset工具將cyclictest測試程序運行在所有核心上,測試cyclictest在滿負荷狀態的CPU0和被隔離的CPU1的實時性能。測試指令需運行12小時,請保持評估板長時間穩定工作,測試完成後將生成統計結果iso_overload_output文件。

Target# taskset -c 0-1 cyclictest -m -Sp99 -i1000 -h800 -D12h -q > iso_overload_output

 

基於 DR1M90 的 Linux-RT 內核開發:從編譯配置到 GPIO / 按鍵應用實現(1)_開發板_22

圖 20

 

統計結果分析

我司已提供腳本文件get_histogram.sh用於繪製統計結果直方圖,位於產品資料“4-軟件資料\Demo\linux-rt-demos\cyclictest\bin\”目錄下,請將該腳本文件拷貝至Ubuntu工作目錄下。

 

基於 DR1M90 的 Linux-RT 內核開發:從編譯配置到 GPIO / 按鍵應用實現(1)_開發板_23

圖 21

 

在Ubuntu系統執行如下命令,安裝gnuplot工具。

Host# sudo apt-get install gnuplot

 

基於 DR1M90 的 Linux-RT 內核開發:從編譯配置到 GPIO / 按鍵應用實現(1)_嵌入式開發_24

圖 22

 

(1)CPU空載狀態

請將CPU空載狀態下的統計結果no_load_output文件拷貝至Windows工作目錄,使用Windows文本工具打開該文件並拖動至文件末尾,可查看Linux系統每個核心CPU0~CPU1的最小延遲(Min Latencies)、平均延遲(Avg Latencies)、最大延遲(Max Latencies)統計結果。

 

基於 DR1M90 的 Linux-RT 內核開發:從編譯配置到 GPIO / 按鍵應用實現(1)_工業控制_25

圖 23

 

請將CPU空載狀態下的統計結果no_load_output文件拷貝至Ubuntu,存放在get_histogram.sh同一目錄下。拷貝no_load_output文件為output文件。執行如下命令生成直方圖文件plot.png,請將其拷貝至Windows下並打開。

Host# cp no_load_output output

Host# ./get_histogram.sh

 

基於 DR1M90 的 Linux-RT 內核開發:從編譯配置到 GPIO / 按鍵應用實現(1)_開發板_26

圖 24

 

基於 DR1M90 的 Linux-RT 內核開發:從編譯配置到 GPIO / 按鍵應用實現(1)_開發板_27

圖 25

 

根據測試結果output文件數據以及結合直方圖,可得主要數據如下表。本次測試中,CPU1核心Max Latencies值最大,為44us,CPU0核心的Max Latencies值最小,為42us。

備註:測試數據與實際測試環境有關,僅供參考。

基於 DR1M90 的 Linux-RT 內核開發:從編譯配置到 GPIO / 按鍵應用實現(1)_開發板_28

 

(2)CPU滿負荷狀態

參考如上方法,分析CPU滿負荷狀態下的統計結果如下所示。本次測試中,CPU1核心Max Latencies值最大,為100us,CPU0核心的Max Latencies值最小,為78us。

 

基於 DR1M90 的 Linux-RT 內核開發:從編譯配置到 GPIO / 按鍵應用實現(1)_硬件開發_29

圖 26

 

基於 DR1M90 的 Linux-RT 內核開發:從編譯配置到 GPIO / 按鍵應用實現(1)_硬件開發_30

 

(3)隔離CPU核心狀態

參考如上方法,分析隔離CPU核心狀態下的統計結果如下所示。本次測試中,CPU0核心Max Latencies值最大,為42us,隔離CPU1核心的Max Latencies值最小,為28us。

 

基於 DR1M90 的 Linux-RT 內核開發:從編譯配置到 GPIO / 按鍵應用實現(1)_嵌入式開發_31

 

基於 DR1M90 的 Linux-RT 內核開發:從編譯配置到 GPIO / 按鍵應用實現(1)_工業控制_32

 

根據CPU空載、CPU滿負荷、隔離CPU核心三種狀態的測試結果可知:當程序指定至隔離的CPU1核心上運行時,Linux系統延遲最低,可有效提高系統實時性。故推薦對實時性要求較高的程序(功能)指定至隔離的CPU核心運行。

外設使用説明

我司提供的Linux-RT內核與普通Linux內核測試方法一致,請參考《評估板測試手冊》進行測試即可。Linux-RT內核支持的外設接口及測試結果彙總如下表所示

 

基於 DR1M90 的 Linux-RT 內核開發:從編譯配置到 GPIO / 按鍵應用實現(1)_開發板_33

 

系統使用説明

Linux-RT內核與普通Linux內核在系統使用上保持一致,具體操作方法請參考《Linux系統使用手冊》。