大家好,我們是中國科學技術大學操作系統原理與設計(H)課oooooS小組。這個項目是我們的課程大作業:參考RT-Thread架構,使用Rust搭建一個原生的嵌入式操作系統內核。初識Rust是因為xk老師的推薦,很快我們就被其極高的安全特性,強大的包管理系統和編譯器以及豐富的社區支持所折服。然后我們在調研時注意到了RT-Thread。它有著經典的操作系統架構,卻又在各模塊的設計上充滿著巧思,最重要的是,它的社區支持和文檔支持也非常豐富,這給我們的工作帶來了非常多的便利。所以,在課程結束后,我們也想做些工作來反哺開源社區,這才有了這篇文章的誕生。囿于本組組員的水平,以下內容僅供參考,當然也歡迎讀者有任何疑問的話與我們聯系。
項目地址:https://github.com/OSH-2025/oooooS
小組全體成員: @Piteright , @明日桐奈,@故俗,@LISTOI,@老葵澤
在物聯網與嵌入式系統領域,對功能安全與高可靠性的追求已成為行業共識,尤其是在資源受限的微控制器(MCU)應用中。傳統上,這類系統大量依賴C語言開發的實時操作系統(RTOS),通過任務(線程)作為并發與隔離的基本單元。然而,C語言固有的內存安全缺陷,如緩沖區溢出、懸垂指針等,使得在協作式多任務環境下,任何一個組件的微小失誤都可能導致整個系統的崩潰,這在工業控制、醫療設備、汽車電子等關鍵領域是不可接受的。開發者不得不在功能實現與系統穩定性之間艱難權衡,投入大量精力進行防御性編程和冗長的測試。
RusT-Thread正是在這樣的背景下誕生的。作為一款專為資源受限嵌入式平臺設計的開源實時操作系統,RusT-Thread 以業界成熟的 RT-Thread 內核理念為藍本,創新性地采用 Rust語言進行全面重構。它旨在從根本上解決傳統 RTOS 的安全痛點,利用 Rust 語言強大的靜態分析能力,包括所有權系統、借用檢查和類型安全,將大量潛在的內存與并發錯誤在編譯階段徹底消除。通過這種方式,RusT-Thread 致力于在不犧牲性能的前提下,提供一個輕量級、高安全性的并發執行環境。
本文將從項目特色、架構設計、核心實現機制、性能驗證等多個維度,詳細闡述 RT-Thread 的設計理念與實現方式,展示其如何將 Rust 的現代化語言優勢與實時操作系統的經典思想相結合,為嵌入式開發者提供一個更安全、更高效的開發新選擇。
目錄
簡介
項目特色
架構設計
分模塊介紹
性能與驗證
優缺點
總結與展望
1
簡介
RusT-Thread是一款基于 RT-Thread 理念,采用 Rust 語言打造的輕量級實時操作系統內核,已在ARM Cortex-M4上成功實現,并有望拓展至更多芯片平臺。
在線程調度上,它支持多線程創建、調度及優先級管理,提供多種調度算法,如優先級、優先級 + RR 等。同時,在內存分配上支持伙伴系統、小內存分配器等多種內存分配方式,滿足動態內存分配需求。此外,還實現了高精度定時器,支持單次和周期定時功能,并具備完整的異常和中斷處理機制。
RusT-Thread 的 Rust 實現保障內存安全,模塊化設計便于擴展和移植,支持資源受限的嵌入式系統,為開發者提供了安全、高效、精簡的 Rust 原生實時操作系統選擇。
2
項目特色
本項目是一個完全由Rust構建的操作系統內核。不同于本課程其他小組和前輩們的工作,我們放棄了C和Rust混合編譯改寫操作系統內核的開發路徑,而是選擇從底層開始就用 Rust開發,這種徹底的重構能讓我們更好地利用Rust擁有的現代化語言特性,組織起結構更加清晰,功能實現更加簡練的代碼。同時,我們還避免了混合編譯過程中的各種操作性問題和潛在的安全性風險。
本項目的架構參考RT-Thread nano內核實現,在實現功能模塊時我們保留了大部分RT-Thread內核的接口,確保熟悉RT-Thread內核的開發者能低成本快速上手我們的內核。RT-Thread的成功很難離開其眾多貢獻者帶來的豐富軟件包移植,我們希望我們的內核也能為 RT-Thread社區中的Rust開發者提供一個底層平臺,可以原生的用Rust實現各種組件,豐富這個操作系統的功能。
3
架構概述

RusT-Thread結構
當我們著手設計 RusT-Thread 架構時,我們的目標并不僅僅是復刻 RT-Thread,而是要用 Rust 的思想去重塑它。為此,我們將以下幾個關鍵原則融入了項目里:
安全性 :借助 Rust 的所有權系統與借用檢查機制,從編譯階段就徹底消除內存安全隱患。同時,通過其嚴格的并發模型有效防止數據競爭,能夠有效提升系統的并發安全性
可擴展性 :我們將整個系統設計為高度模塊化。這種架構使得無論是添加新的設備驅動、文件系統,還是集成復雜的網絡協議棧,都變得直觀而高效,為未來的功能拓展留出了充足的空間
性能:充分利用 Rust 的零成本抽象特性,在確保系統安全性的基礎上,對調度算法和內存管理機制進行深度優化,從而全面提升系統的整體性能表現
易移植性:我們采用分層設計策略并構建清晰的硬件抽象層,簡化了系統對不同芯片架構的適配過程。目前,該系統已成功支持 ARM Cortex-M4 芯片架構,未來也許會逐步擴展對更多類型芯片的支持范圍
4
分模塊介紹
1 內核服務層
內核服務層作為 RusT-Thread 操作系統的核心基礎,是連接硬件底層與上層應用的關鍵橋梁,其核心功能及在 Rust 中的實現方案如下:
錯誤處理機制:采用 Rust 的Option和Result枚舉類型替代傳統錯誤碼,通過模式匹配清晰表達函數執行結果。在編譯期對錯誤處理邏輯進行嚴格檢查,避免因錯誤處理不當引發的問題,確保系統穩定運行。
內存操作函數:利用 Rust 標準庫中的 Core::alloc模塊,結合自定義的內存分配策略和數據結構,實現高效靈活的內存分配與回收機制,優化內存使用效率,確保操作的正確性和安全性。
字符串操作函數:借助 Rust 內置的String和str類型及其操作方法,實現功能強大且安全高效的字符串處理功能,有效防止緩沖區溢出等問題,滿足系統對文本處理的需求。
格式化輸出功能:結合cortex_m_semihosting工具庫和 Rust 的格式化字符串宏(format!、println!等),實現數據格式化輸出功能。在QEMU模擬器環境下,通過半宿主功能將輸出數據發送至宿主機控制臺,支持多種數據類型和輸出格式,滿足調試和信息展示的需求。
調試和斷言功能:借助 Rust 的Debug和Display特性以及assert!、debug_assert!等宏,實現完善的調試和斷言功能。為自定義數據類型實現相關特質,以便在調試輸出時展示詳細信息;通過斷言條件檢查及時暴露問題,提高開發效率。
鏈表實現:利用 Rust 的Vec等標準容器類型,結合手動指針操作和數據結構管理邏輯,構建高效的鏈表結構。通過存儲節點指針模擬鏈接關系,實現節點的動態操作,同時借助所有權系統和借用檢查機制確保操作的安全性和正確性。
我們單獨添加了 Cell 模塊,以更好地適配 Rust 的語言特性。Cell 模塊實現了一個中斷安全的共享數據容器RTIntrFreeCell,這是 RT-Thread 實時操作系統中的核心內核服務組件之一。其核心目的就是在多線程和中斷環境下提供安全的共享數據訪問機制,通過自動禁用和啟用中斷來防止數據競爭,具體體現在以下三個方面:
1. 中斷安全性:
在訪問共享數據時自動調用rt_hw_interrupt_disable()禁用中斷
訪問結束后自動調用rt_hw_interrupt_enable()恢復中斷
確保臨界區代碼能夠原子性地執行,避免數據不一致的問題
2. RAII 資源管理:
使用RTIntrRefMut作為智能指針,利用 Rust 的 Drop 特質實現自動資源釋放
當RTIntrRefMut超出作用域時,自動恢復中斷級別,降低了手動管理資源的風險
3. 靈活的訪問方式:
提供exclusive_access()方法獲取獨占訪問權限
提供exclusive_session()方法在閉包中執行臨界區代碼
提供as_ptr()和as_mut_ptr()方法獲取原始指針,方便底層操作
提供field_ptr()和field_mut_ptr()方法獲取結構體字段的原始指針,增強靈活性
在 RusT-Thread 內核中,我們使用這個核心模塊來保護那些需要同時被中斷服務程序和普通線程訪問的關鍵數據,比如線程控制塊(TCB)、調度器狀態、定時器列表以及內存管理的內部數據。RTIntrFreeCell的作用就是提供一個“中斷鎖”,確保在任何時候數據訪問都是安全的,這對于保證高并發下系統的數據一致性和整體穩定性至關重要。
2 硬件抽象層
硬件抽象層(hardware)是 RusT-Thread 操作系統在 Cortex-M4 架構下的底層硬件支持模 塊,主要負責 CPU 端口、上下文切換、異常處理和中斷管理等功能,為上層系統提供與硬件緊密相關的基礎服務。
硬件抽象層是操作系統的核心組成部分,通過這些模塊,RusT-Thread 能夠實現高效、可靠的硬件資源管理和任務調度,為上層應用提供穩定的運行環境。
模塊內容如下:
hardware├── context.rs # 線程上下文切換,使用內聯匯編實現線程上下文保存與恢復├── cpuport.rs # CPU 接口-Cortex-M4,定義了異常棧幀、棧幀、CPU關機、CPU 重啟├── exception.rs # 異常處理相關函數├── irq.rs # 中斷管理模塊,提供了中斷嵌套計數、鉤子設置、使能/禁用中斷等功能└── mod.rs # 統合上述模塊,提供對外接口
上下文切換模塊 (context.rs)
負責線程上下文的切換機制,主要功能包括:
線程上下文的保存與恢復
PendSV 中斷處理(實際執行上下文切換)
提供rt_hw_context_switch、rt_hw_context_switch_interrupt和rt_hw_context_switch_to等上下文切換處理函數
實現線程間的高效切換,是多線程調度的核心機制
CPU 端口模塊 (cpuport.rs)
提供與 CPU 硬件直接相關的底層支持:
定義異常棧幀ExceptionStackFrame和棧幀StackFrame結構
實現線程棧初始化函數rt_hw_stack_init
提供 CPU 關機rt_hw_cpu_shutdown和重啟rt_hw_cpu_reset等功能
可選的 FPU 支持(浮點運算單元)
中斷管理模塊 (irq.rs)
實現中斷處理相關的功能:
中斷嵌套計數管理
提供中斷使能/禁用函數rt_hw_interrupt_disable/enable
中斷進入/退出處理rt_interrupt_enter/leave
支持中斷鉤子函數設置(通過特性開關控制)
獲取中斷嵌套層數rt_interrupt_get_nest
異常處理模塊 (exception.rs)
負責處理系統運行中的各種異常:
提供硬件錯誤處理(HardFault、MemManage、BusFault、UsageFault)
異常信息收集與輸出
支持異常鉤子機制rt_hw_exception_install
詳細的故障跟蹤與診斷功能
3進程調度層
作為 RusT-Thread 操作系統的核心,進程調度層負責管理和調度所有線程,確保它們能夠高效、公平地共享處理器資源,實現并發執行,核心職責如下:
任務調度:依據預設調度策略,決定處理器執行權的分配,保障高優先級任務的及時響 應,同時兼顧任務的公平執行。支持多種調度算法,具備靈活適應不同應用場景和實時性要求的能力
調度算法選擇 :提供優先級調度算法(如優先級 + 時間片輪轉)和多級反饋隊列調度算法等,用戶可根據實際需求靈活選擇調度算法,滿足不同任務對實時性和資源分配的需求
線程 API 接口 :為用戶提供了一系列豐富的接口,使用戶能夠更加便捷地對線程狀態進行調整和控制,例如創建、刪除、掛起、恢復線程等操作,同時提供了獲取和設置線程屬性的接口,方便用戶根據實際需求對線程進行精細化管理

調度策略抽象 :通過定義 SchedulingPolicy特質,將多種調度算法封裝和抽象。以優先級調度算法為例,實現了相應的結構體,包含線程優先級隊列管理和時間片分配與輪轉機制;對于多級反饋隊列調度算法,設計了多級隊列數據結構,實現了任務根據執行時間動態調整隊列級別的邏輯。基于特質的抽象方式使調度策略切換靈活,用戶在初始化時指定調度策略后,調度器即可根據具體實現執行調度操作
/// 調度策略 traitpub traitSchedulingPolicy:Send+Sync{ /// 選擇下一個要運行的線程 /// /// # 參數 /// * `current_thread` - 當前運行的線程 /// /// # 返回值 /// * `Option<(Arc, bool)>` - (選中的線程, 是否需要將原線程重新插入就緒隊列) fn select_next_thread( &self, current_thread:&Option
調度算法優化 :引入位圖 + FFS(Find First Set)算法提升調度效率。位圖標識各優先級隊列的線程就緒狀態,通過 FFS 算法快速定位最高優先級隊列中的首個就緒線程。FFS 算法借助預計算查找表,將復雜位運算轉化為簡單數組訪問,實現 O(1) 時間復雜度的最高優先級線程查找,顯著提升調度器響應速度和實時性能,確保系統及時響應高優先級任務
#[cfg(feature = "tiny_ffs")]const__LOWEST_BIT_BITMAP: [u8;37] = [ 0,1,2,27,3,24,28,32,4,17,25,31,29,12,32,14, 5,8,18,32,26,23,32,16,30,11,13,7,32,22,15,10, 6,21,9,20,19];
#[cfg(feature = "tiny_ffs")]pubfn__rt_ffs(value: u32) ->u8{ ifvalue ==0{ return0; } __LOWEST_BIT_BITMAP[((value & (value -1) ^ value) %37)asusize]}
該算法利用預計算查找表和數學運算避免復雜位運算循環,實現了快速最低有效位查找。它專為嵌入式環境優化,在資源受限設備上也能快速執行,滿足實時系統低延遲要求。能快速確定線程就緒隊列中最高優先級線程,確保調度器及時響應高優先級任務,提升系統實時性和性能。
多級反饋隊列調度實現 :在多級反饋隊列調度算法中,引入老化機制,使長期未被調度的線程逐漸升高優先級,防止低優先級線程饑餓,增強調度算法公平性和適應性。實現過程中,借助 Rust 語言零成本抽象特性,優化代碼實現,提升系統穩定性和可維護性。
4 內存管理層
在 RusT-Thread 中,我們實現了原本 RT-Thread 中的小內存分配器,同時并支持了庫實現的buddy_system allocator和good_memory allocator,可供用戶在實際場景中自由選擇,下面將對小內存分配器作具體分析:
RusT-Thread 中的小內存分配器主要體現在如下幾個文件中:
small_mem_impl.rs:核心算法實現
small_mem_allocator.rs、allocator.rs:分配器接口與適配
object.rs、safelist.rs:輔助對象和安全鏈表
oom.rs:內存溢出處理

表示內存塊的結構體:
///RTSmallMemItem 結構體表示一個小內存塊的基本信息,主要用于管理內存池中的單個內存塊#[repr(c)]pub structRTSmallMemItem { ///內存池指針 pub pool ptr: usize, #[cfg(target_pointer_width="64")]// 條件編譯,64位系統生效 pub resv:u32,//保留字段,用于對齊,64位系統下使用 ///下一個空閑塊的指針 pub next: usize, ///前一個空閑塊的指針 pub prev: usize, #[cfg(feature ="mem_trace")]//條件編譯,內存跟蹤生效 #[cfg(target pointer_width="64")]//條件編譯,64位系統生效 pub thread:[u8;8],//線程ID,64位系統下使用 #[cfg(feature="mem_trace")]//條件編譯,內存跟蹤生效 #[cfg(target pointer_width ="32")]//條件編譯,32位系統生效 pub thread:[u8;4],//線程ID,32位系統下使用}
小內存分配算法的原理是通過維護一塊連續的內存池,將其劃分為帶有頭部信息的內存塊,并用鏈表管理空閑和已用塊。分配時遍歷空閑鏈表,找到足夠大的塊后分割并標記為已用;釋放時將塊標記為空閑,并嘗試與相鄰空閑塊合并以減少碎片。整個過程包含邊界檢查和中斷保護,確保分配、釋放的安全性和原子性。
除了實現基本的小內存算法外,我們還有如下亮點:
邊界檢查與安全性提升
C 代碼主要依賴 RT_ASSERT 等宏進行運行時斷言,且大量裸指針操作,容易出現懸垂指針、越界、重復釋放等問題,這些斷言如果被關閉,代碼安全性大幅下降
debug_assert!((memasusize) >= ((*small_mem).heap_ptrasusize)); debugassert!((memasusize) < ((*small_mem).heap_end?as?usize));? debug?assert!(mem?is?used(mem));if?m.is_null()||size ==?0?{? ? return?ptr::null mut();? }
Rust 利用類型系統和所有權機制,天然防止了大部分內存安全問題,同時 rt_smem_free、rt_smem_alloc 等函數在操作前都做了空指針和邊界檢查
Rust 的 debug_assert! 只在 debug 模式下生效,release 下可關閉,但類型系統和生命周期機制依然提供了額外的安全保障
許多輔助函數(如 mem_is_used、mem_pool 等)都用 inline 和類型安全的方式實現,減少了手動錯誤
中斷保護
C 語言通過rt_hw_interrupt_disable/rt_hw_interrupt_enable 手動保護關鍵區,防止并發破壞堆結構
rt_base_t_level =rt_hw_interrupt_disable(); // ...關鍵區. rt_hw_interrupt_enable(level);
Rust 同樣調用rt_hw_interrupt_disable/rt_hw_interrupt_enable,但更易于用 RAII(資源自動釋放)等機制進行封裝,減少人為失誤
letlevel =rt_hw_interrupt_disable();//...關鍵區 ... rt_hw_interrupt_enable(level);
并且 Rust 代碼結構更清晰,便于后續用 RAII 或作用域自動恢復中斷,提升健壯性
5 線程通信層
進程間通信(IPC)是多任務操作系統中各個任務之間進行數據交換和協同工作的重要手段。我們的 RusT - Thread 提供了信號量機制,而消息隊列、郵箱等作為拓展,我們尚未支持。
信號量工作示意圖如下圖所示,每個信號量對象都有一個信號量值和一個線程等待隊列,通過信號量的值是否為零,決定線程是否可以訪問臨界區的資源,當信號量實例數目為零時,再申請該信號量的線程就會被掛起在該信號量的等待隊列上,等待可用的資源。

在 RT-Thread 中,信號量相關操作有以下函數——創建、刪除、獲取、釋放,我們實現的思路和 C 類似,先實現 ipc 的基礎操作,如_ipc_list_suspend掛起線程,_ipc_list_resume喚醒線程等等,然后,通過信號量的值,選擇不同的操作,實現信號量的相關操作即可。

6 時鐘控制層
時鐘節拍的產生
時鐘節拍由配置為中斷觸發模式的硬件定時器產生,當中斷到來時,將調用一次rt_tick_increase()函數,通知操作系統已經過去一個系統時鐘;不同硬件定時器中斷實現都不同,Rust_Thread 的中斷函數是在 QEMU 模擬器上的 stm32 系列單片機上實現的,具體的,程序中將使用#[exception]一個中斷處理函數SysTick(),在其中調用rt_tick_increase()函數。
在 Rust-Thread系統中,使用常數 RT_TICK_PER_SECOND 控制時鐘周期長度。本系統中默認主頻是 16MHZ,是通過 QEMU 模擬芯片內部高速振蕩器實現的,默認 RT_TICK_PER_SECOND=1000,即一個時鐘周期 16000 個硬件周期。
時鐘中斷的管理
時鐘中斷管理核心函數rt_tick_increase()主要完成以下工作:
將全局變量RT_TICK 自增,這個變量記錄了系統從初始化到當前經過了多少個時鐘周期,叫做系統時間。
檢查當前線程的時間片是否到期,若到期,則觸發線程調度
檢查是否有定時器到期,如果有,觸發定時器超時函數
時鐘管理中還包括系統時間的讀取和設定函數,毫秒數和時鐘周期數的轉換函數等功能函數。
定時器的管理
RT-Thread 的定時器由定時器控制塊RtTimer控制,定時器控制塊全部在運行時動態分配內存并按照超時時間升序掛載在動態數組TIMERS中。定時器的管理主要包括定時器的創建、激活、修改、超時與停止。
創建:使用new方法創建,體現了面向對象的思想
激活:計算超時時刻,通過二分查找插入TIMERS數組,保證有序性
修改:使用enum封裝所有修改操作(如周期、定時值),符合 Rust 風格且易于擴展。修改在下次激活時生效
超時:通過二分查找高效定位到期的定時器,執行回調。周期性定時器會自動重新激活,單次定時器則被移除
停止:從TIMERS數組中移除并回收定時器
5
性能與驗證
1 內存性能測試
原生的 RT-Thread 官方并沒有給出一些具體的有關內存性能的數據,所以這里我們參照標準的 std 庫來比較分析 RusT-Thread 的性能。
我們在 Linux(x86_64)平臺下,使用 Rust 重新實現了 RusT-Thread 的完全相同的內存管理模塊,并對其進行了適當的封裝,并使其接口與原系統保持一致。這樣,我們就可以在支持 std 庫和Criterion基準測試框架的環境下,對內存分配、釋放等核心操作進行高效、可重復的性能測試,并與 Rust 標準庫分配器進行公平對比。
測試代碼使用 Criterion 框架實現,測試內容包括小塊分配、混合分配、碎片處理、內存利用率等多種典型場景
這種方法雖然不能完全反映嵌入式平臺的絕對性能,但可以有效比較不同分配算法的相對性能,為實際部署和優化提供有價值的參考
具體測試結果如下:

該圖展示了 RusT-Thread 與標準分配器在進行小塊內存分配和混合內存分配時的性能表現:
Small Allocations 中,RusT-Thread 平均耗時約為 24.6μs,明顯優于std的 77.7μs,表明 RusT-Thread 在頻繁的小對象分配中具有更低的管理開銷
Mixed Allocations 中,標準分配器表現優異,耗時僅約 5.7μs,而 RusT-Thread 則為 31.4μs,可能是由于 RusT-Thread 對變長內存塊的處理不如標準庫靈活高效
RusT-Thread 在固定小塊內存操作中具有優勢,但在面對內存尺寸變化復雜的情況時性能下降。不過這同時也嶄展現出不同應用場景中,RusT-Thread 中小內存分配算法的性能更加穩定。

該圖展示了在逐步增加內存塊大小的條件下,RusT-Thread 和標準分配器的單次分配耗時變化趨勢:
RusT-Thread 的分配時間基本穩定在 7~8ns 范圍內,說明其設計對小中等大小塊分配進行了優化處理,性能幾乎不受塊大小影響
標準分配器的耗時隨著塊大小增加而變化更為劇烈,例如從 16B 的約 24ns 上升到 2048B時超過 47ns,說明其可能使用了更復雜的分配策略或存在內存對齊開銷
可見,RusT-Thread 分配器的響應速度更穩定,適用于內存塊尺寸變化不大的嵌入式任務場景。

本圖對比了在進行批量內存分配(10、100、1000 次)時,兩種分配器的平均耗時:
RusT-Thread 在 10~100 次批量分配中僅需 17μs 左右,而標準分配器耗時逐步上升到 60μs 以上
差距在批量操作中進一步放大,表明 RusT-Thread 的批處理性能更優,內部結構對頻繁申請釋放有較強的適應性
可以看出,RusT-Thread 分配器在多次重復分配的密集型任務中更具優勢,特別適用于任務頻繁上下文切換或數據緩沖場景。

該圖展示了常見四種內存重分配路徑(如 64→128, 128→64, 64→256, 256→64)下的耗時比較:
所有場景中 RusT-Thread 的耗時都遠低于標準分配器,例如 128→64 僅約 12.95ns,而標準庫約 89.6ns
表明 RusT-Thread 分配器可能采用就地擴展或快速搬遷機制,避免了額外的復制和元信息更新開銷
所以,RusT-Thread 對 reallocation 操作進行了優化,在需要動態改變內存塊大小的場景中表現更加出色,這使得對于真實環境中的復雜情況的處理會更加優秀。
2 模塊驗證測試
測試部分代碼結構如下:
RusT-thread/src/test├── README.md├── comprehensive_example.rs├── example.rs├── example_mfq.rs├── integration_test.rs├── mod.rs├── performance_test.rs├── switch_time_test.rs├── test_all.rs├── test_cell.rs├── test_excp.rs├── test_interupt.rs├── test_ipc.rs├── test_mem.rs├── test_scheduler.rs├── test_small_mem.rs├── test_thread.rs└── test_timer.rs
3 單元測試
我們為各個模塊編寫了詳細的單元測試用例,對模塊的功能進行充分驗證。例如,對線程管理模塊,測試了線程的創建、啟動、掛起、恢復、刪除等基本操作,以及不同調度策略下的線程切換和優先級管理;對內存管理模塊,測試了內存的分配、釋放、重分配等操作以及對標準 alloc 的容器支持;對定時器模塊,測試了定時器的創建、啟動、停止、重啟等操作,以及定時器回調函數的執行等
4 集成測試
在模塊間集成測試中,我們重點關注各模塊協作及系統整體功能正確性,設計了以下典型測試場景:
并發性測試
并發線程創建:多線程同時創建 RT-Thread 線程,驗證線程管理安全性
優先級調度驗證:創建不同優先級線程并記錄執行順序,確保調度器優先級語義正確
內存碎片化測試:模擬復雜內存分配釋放場景,驗證內存管理器健壯性
壓力測試
大規模線程創建:創建 100 個線程同時運行,測試系統高負載穩定性
內存分配壓力測試:進行 1000 次隨機大小內存分配釋放,驗證內存管理器性能
定時器密集測試:創建 50 個定時器同時運行,測試時鐘系統處理能力
邊界條件和錯誤處理
邊界值測試:測試最小 / 最大優先級、最小內存分配、零大小分配等邊界情況
錯誤場景模擬:測試重復啟動線程、重復掛起線程、無效線程 ID 等異常處理
資源耗盡測試:模擬內存不足等資源耗盡場景,驗證系統錯誤處理機制
系統穩定性測試
長時間運行測試:驗證系統長期穩定性
5 性能基準測試
為驗證 RusT-Thread 的實時性能,我們設計了針對 RTOS 核心指標的性能基準測試體系。測試重點關注時間確定性和系統響應的可預測性,這是實時操作系統區別于通用操作系統的關鍵特征。我們選擇了四項核心指標進行評估:中斷延時測試驗證系統對外部事件的響應速度,響應時間測試評估任務調度的實時性,上下文切換時間測試衡量線程切換效率,線程啟動時間測試檢驗系統資源分配性能。這些測試不僅幫助我們發現性能瓶頸和優化空間,更重要的是為系統的實時性保證提供了量化依據,確保 RusT-Thread 能夠滿足嵌入式和工業控制應用的嚴格時間要求。
中斷延時測試
我們利用 Cortex-M 內核自帶的 SysTick(系統滴答定時器)來精確測量中斷延時。SysTick本質上是一個 24 位的硬件自減計數器。其工作原理如下:
計數與觸發:計數器以系統時鐘頻率從一個預設的重載值(Reload Value)開始遞減。當計數值從 1 減到 0 時,硬件會立即觸發 SysTick 中斷
自動重載:在觸發中斷的同一時鐘周期,硬件會自動將重載值重新加載到計數器中,使其無縫開始下一輪遞減,整個過程無需任何軟件干預
由于中斷服務程序的執行會存在微小的延遲,而 SysTick 計數器在此期間并未停止。因此,我們可以在中斷服務程序的入口處,立即讀取此刻 SysTick 計數器的當前值。通過這個差 值,我們就能精確計算出中斷延時。計算公式為:

我們系統測得 1000 次平均中斷延時為 1.21us
響應時間測試
事件響應時間是指從事件發生到系統完成相應處理的總時間,包括事件檢測、任務調度和執行處理邏輯的全過程。此指標衡量了系統對外部事件的端到端處理能力,是評估實時操作系統性能的綜合指標。
在我們的測試中,使用隨機數生成器模擬事件的隨機生成,每隔相同時間生成一個隨機數并于一個給定的概率值比較,當小于此概率值時,就生成一個事件,此事件的優先級也為隨機數,可以證明,事件的間隔服從泊松分布。
我們將事件分為三種優先級:高中低,同時創建三個不同優先級的處理程序來處理事件,測量平均響應時間和各優先級的響應時間,結果如下:

一般硬實時操作系統響應時間的指標為:
| 優先級 | 高 | 中 | 低 ||:----------: | |:--: | ||響應時間(us)|1~5 |5~20|20~100|
可以看到我們三種優先級事件的響應時間均符合硬實時操作系統的要求。
上下文切換時間測試
上下文切換時間是指操作系統從一個線程切換到另一個線程所需的時間,包括保存當前線程狀態和恢復目標線程狀態的過程。該指標對多任務系統的整體性能有顯著影響,它決定了系統在任務間切換的效率。上下文切換時間越短,系統在高負載下的響應性越好,尤其在資源受限的嵌入式系統中,高效的上下文切換能顯著提高處理器利用率和系統吞吐量。
我們測試了兩個相同優先級線程來回切換 5000 次的平均時間,并執行了 100 次這樣的測試,求的線程切換的時間性能如下:

線程創建時間測試
線程創建時間是指從發起創建線程請求到新線程可以被調度執行所需的時間。該指標反映了系統動態資源分配和任務管理的效率。在需要頻繁創建臨時任務的應用場景中(如 Web 服務器、動態負載系統),高效的線程創建機制可以顯著降低系統開銷,提高資源利用率。對于嵌入式實時系統,快速的線程創建能力也有助于系統在運行時更靈活地調整工作負載,適應變化的環境需求。
由于 flash 大小限制,單次測試創建 50 個線程的平均時間,再做 100 次測試求平均,得到測試結果如下:

與 RT-Thread 性能對比
RT-Thread 官方給出了他們的性能測試結果如下圖:

其測試基于的硬件平臺是 Zynq 7020,該開發板的主頻為 800MHz,而我們使用的 QEMU模擬的是 stm32f405 的開發板,主頻為 168MHz ,在對比性能時應考慮相關的硬件資源。
| 指標 |RT-Thread|Rust-Thread| 折合后的等效時間 ||:------------: | |:---------: | || 中斷延時(ns) | 321 | 1210 | 254 || 上下文切換(us) | 0.633 | 2.58 | 0.542 || 線程創建(us) | 2.969 | 2.60 | 0.546 |
綜上,我們重寫后的 RusT-Thread 操作系統的實時性與 RT-Thread 相當甚至更加優秀,這符合我們當初制定的性能提升的目標。
6
優缺點
1 優點
安全導向的設計語言。Rust 的所有權機制使得 RusT-Thread 操作系統在內存安全和并發安全上很有優勢
高度模塊化并且可以定制。在搭建 RusT-Thread 操作系統時,我們基于 Rust 語言特性,建立了可模塊化的系統倉庫,定義改寫模塊方便快捷
平臺具備高度可擴展性,雖然目前僅支持 Cortex-M4 平臺,但模塊化的 Hardware 利于后續擴展平臺
多樣的算法特性選擇。在線程調度上提供多種調度算法,如優先級、優先級 + RR 等;在內存管理上支持伙伴系統、小內存分配器等多種內存分配方式
性能優秀。在 Rust 改寫后的系統線程上下文切換性能與原 C 程序性能相當
測試點豐富。我們對各個模塊開發了功能測試程序,利于后續的調試開發
2 缺點
相關文檔尚不完善。由于時間精力,我們暫未維護起完善的文檔體系
Rust 所有權機制等致使代碼可讀性差。為開發帶來一定困難
外設周邊尚未開發支持
異常反饋系統尚不完善,待后續開發
6
總結與展望
歷經數月的攻堅克難,RusT-Thread 項目終于迎來了階段性成果。我們成功地將 RT-Thread Nano 內核的核心功能,包括線程調度、內存管理、中斷處理、時鐘服務、IPC 等,用 Rust語言進行了高質量的重構與實現。這不僅是一次技術棧的遷移,更是在嵌入式實時操作系統領域,對 Rust 語言安全性、并發性和現代語言特性的一次深度實踐與驗證。
核心成果:安全性與性能的雙重提升
內存安全基石:最大的收獲莫過于 Rust 強大的所有權系統和借用檢查機制帶來的根本性改變。通過RTIntrFreeCell等創新設計,我們有效解決了嵌入式系統中全局共享數據訪問這一高危痛點,將數據競爭、野指針、緩沖區溢出等 C 時代常見的“幽靈”從編譯期就扼殺在搖籃里。內核服務的錯誤處理也因Option / Result變得更加健壯和可預測。
性能不妥協:我們并非單純追求“安全”而犧牲效率。精心優化的調度算法(如基于位圖+FFS 的優先級調度、創新的多級反饋隊列)、高效的小內存分配器實現,以及 Rust 零成本抽象的特性,共同確保了 RusT-Thread 在 QEMU 模擬環境下的性能指標(中斷延時、上下文切換、線程創建、響應時間)與原版 C 實現的 RT-Thread Nano 相當甚至略有優勢。這證明了 Rust 完全有能力勝任對實時性要求苛刻的嵌入式場景。
代碼精簡與清晰:Rust 的現代語言特性(如 trait、泛型、豐富的標準庫容器)顯著提升了代碼的表達力和可維護性。最直觀的體現是,在實現同等甚至更多功能(如更優的定時器二分查找算法)的前提下,Rust-Thread 的核心代碼量(約 5500 行)相比原 C 版(約 9600 行)有了顯著的精簡。模塊化設計和清晰的抽象也讓代碼結構更易于理解和擴展。
扎實的驗證體系:我們構建了涵蓋單元測試、集成測試和全面的性能基準測試(內存性 能、中斷延時、響應時間、上下文切換、線程創建)的驗證體系。詳實的數據不僅證明了系統的功能正確性,也為性能優化和后續迭代提供了堅實基礎。
挑戰與突破:在“裸機”上駕馭 Rust
項目過程并非一帆風順。調試手段匱乏時,我們深度依賴半宿主打印和內聯匯編調試技巧;硬件對接和啟動流程的復雜性,通過cortex-m、cortex-m-rt等庫結合內聯匯編巧妙化解;匯編與 Rust 聯合編譯調試的難題,最終以內聯匯編統一在 Rust 源碼中的方案優雅解決;而困擾嵌入式開發的全局變量問題,則由RTIntrFreeCell+lazy_static的組合拳提供了安全可靠的 Rust 式解決方案。每一次挑戰的克服,都加深了我們對 Rust 在嵌入式裸機環境應用的理解。
展望未來:構建更強大、更開放的 RusT-Thread 生態
RusT-Thread 的誕生只是一個起點,我們對其未來充滿期待:
1. 功能深化與擴展:
豐富軟件生態:系統性地移植 RT-Thread 社區成熟的核心軟件包(網絡協議棧lwIP/PicoTCP、文件系統 LittleFS/SPIFFS、GUI 組件等),是當務之急。我們將致力于構建標準化的 Rust-C 互操作層接口,讓海量的現有 C 語言資源能更順暢地融入 Rust 生態
高級內核特性:實現更完善的內存管理策略(Slab, MemHeap)、支持更豐富的 IPC 機制(消息隊列、郵箱、事件集)、探索多核(SMP)支持將是內核層面的重要方向
人性化體驗:當前錯誤處理主要透傳底層錯誤碼。未來計劃引入結構化的 Rust-native 錯誤類型,并集成分級日志與堆棧追蹤功能,讓異常反饋更清晰、調試更高效
2. 生態建設與普及:
廣泛的硬件支持:目前已在 Cortex-M4 上驗證。下一步將適配更多主流架構如 Cortex- M0+/M3/M7 和 RISC-V,目標是覆蓋更廣泛的物聯網和邊緣計算硬件平臺
清晰的開發者體驗:完善多級文檔體系是生態繁榮的關鍵:
代碼級:維護詳盡的 rustdoc API 文檔,包含示例和安全性說明
模塊級:編寫硬件抽象層(HAL)指南、驅動移植教程、核心模塊設計解析等
入門級:提供面向應用開發者的、易于上手的使用手冊和豐富的示例項目,顯著降低 Rust嵌入式開發的門檻
工具鏈優化:持續優化代碼體積(如替換重型打印宏)、提升構建體驗,并探索更好的調試支持集成(如更深入的 GDB 支持)
RusT-Thread 項目是一次勇敢的嘗試,它證明了 Rust 在資源受限的實時操作系統領域不僅可行,更能帶來顯著的安全性和開發效率提升。我們重構的不僅是一套代碼,更是在探索嵌入式系統開發的未來范式。代碼已開源,這只是一個開始。我們熱切期待更多對 Rust 和嵌入式系統感興趣的開發者加入,共同打磨 RusT-Thread,將其打造成為一個真正安全、高效、易用的開源實時操作系統選擇,為國產嵌入式基礎軟件生態注入新的活力!安全至上,性能無憂,Rust 讓嵌入式未來更可期。
-
內核
+關注
關注
4文章
1437瀏覽量
42544 -
RT-Thread
+關注
關注
32文章
1551瀏覽量
44349 -
Rust
+關注
關注
1文章
240瀏覽量
7493
發布評論請先 登錄
RusT-Thread:基于Rust面向資源受限嵌入式設備的操作系統的實踐 | 技術集結
RT-Thread 內核學習筆記 - 理解defunct僵尸線程
RT-Thread 內核學習筆記 - 設備模型rt_device的理解
RT-Thread 內核學習筆記 - 內核對象鏈表結構深入理解
RT-Thread 內核學習筆記 - 內核對象初始化鏈表組織方式
RT-Thread 內核學習筆記 - 內核對象操作API
大佬帶你理解RT-Thread內核并上手實踐
RT-Thread v5.0.2 發布

RT-Thread 遇上 Rust:安全內核 RusT-Thread 的誕生
評論