李志嬡 王宜懷 劉長勇
摘 要:針對實時操作系統(tǒng)復雜性內核導致嵌入式應用程序編譯速度慢、可復用性差的問題,提出基于通用嵌入式計算機架構(GEC)的RT-Thread實時操作系統(tǒng)駐留方法。在合理劃分存儲空間的基礎上,通過對中斷服務例程進行共享,為用戶提供底層驅動與軟件應用層的函數(shù)調用服務。最后以D1-H應用處理器為例進行RT-Thread駐留測試。實踐結果表明,該駐留方法實現(xiàn)了系統(tǒng)內核與應用程序的物理隔離,編譯時間更短,開發(fā)效率更高,為嵌入式程序開發(fā)的時效性、便捷性和簡易性提供了應用基礎。
關鍵詞:實時操作系統(tǒng);應用處理器;通用嵌入式計算機;駐留;函數(shù)調用
中圖分類號:TP316.2?? 文獻標志碼:A?? 文章編號:1001-3695(2024)01-034-0222-04
doi:10.19734/j.issn.1001-3695.2023.04.0223
Resident method of RT-Thread based on D1-H multimedia application processor
Abstract:This paper proposed a method for the residency of the RT-Thread real-time operating system based on the general embedded computer (GEC) architecture to address the issues of slow compilation speed and poor reusability caused by the complexity of the real-time operating system kernel in embedded applications.On the basis of reasonable storage space allocation,the method achieved the sharing of interrupt service routines,providing users with function call services for both low-level drivers and software application layers.Finally,the residency method was tested using the D1-H application processor as an example.And the results demonstrate that it achieves physical isolation between the system kernel and application programs,resulting in shorter compilation time and higher development efficiency.This method provides a foundation for the timeliness,convenience,and simplicity of embedded program development.
Key words:real time operation system;multimedia application processor;general embedded computer;residency;function call? 實時操作系統(tǒng)(RTOS)[1]作為面向應用處理器的重要工具和運行載體,不僅能有效管理和利用處理器資源,而且實現(xiàn)了應用程序的模塊化管理與并發(fā)性執(zhí)行,保證了嵌入式系統(tǒng)的安全性、可靠性和實時性。在RTOS的應用程序開發(fā)中,仍存在因RTOS源碼被誤改或代碼量較大而影響編譯效率與系統(tǒng)穩(wěn)定性的現(xiàn)象。若在物理層面實現(xiàn)RTOS源碼與應用程序的隔離,同時利用好RTOS為軟件開發(fā)提供的高效服務,則能夠在降低開發(fā)難度的基礎上提升開發(fā)效率。借助GEC架構從功能層面將基本輸入輸出系統(tǒng)(basic input and output system,BIOS)與用戶程序(user)進行有效分割的思想,將RTOS駐留在BIOS內,實現(xiàn)對嵌入式應用程序編程顆粒度和可復用性的提高。目前,已有部分學者對操作系統(tǒng)的駐留應用進行了相關研究,如:楊靜遠等人[2]提出了一種基于ARINC653標準的分區(qū)操作系統(tǒng)固化映像啟動配置策略;Chen等人[3]以Quark分區(qū)操作系統(tǒng)作為研究對象,基于微內核架構配置分區(qū)來實現(xiàn)系統(tǒng)實時性能的提升;白曦等人[4]參考分區(qū)操作系統(tǒng)時空隔離機制,設計了機電軟件開發(fā)平臺,將復雜業(yè)務應用分解為功能單一的多個業(yè)務應用,將其獨立駐留在不同分區(qū),保證了應用的健壯性。
RT-Thread[5]是一個集RTOS內核與中間層組件于一體的開源物聯(lián)網(wǎng)操作系統(tǒng)(IoT OS)[6],支持可靠性、實時性、高可伸縮性,被廣泛應用于智能家居、工業(yè)自動化、國防軍工、消費電子等眾多領域。本文依據(jù)通用嵌入式計算機思想構建D1-H[7]芯片軟件框架,將RT-Thread與底層驅動駐留于BIOS程序,通過函數(shù)映射的方式為用戶在USER程序開發(fā)提供構件級應用,降低了編程門檻、提高了開發(fā)效率、保障了系統(tǒng)穩(wěn)定,從而提高嵌入式應用程序的易用性、穩(wěn)定性和可復用性。
1 RTOS駐留方法共性技術研究
RTOS作為嵌入式系統(tǒng)的核心組件,在系統(tǒng)啟動后處于持續(xù)存在和運行的狀態(tài),負責高效地管理有限的資源以滿足任務調度的實時性能需求。其駐留實現(xiàn)方式因系統(tǒng)和應用需求而異,但其目的都是確保嵌入式系統(tǒng)的實時性和可靠性。
1.1 通用嵌入式計算機架構
為了解決在嵌入式軟件開發(fā)中存在的編程顆粒度低、可移植性弱等問題,通用嵌入式計算機GEC基于模塊共性知識要素對底層驅動進行構件化,并采用類PC機開發(fā)模式將嵌入式軟件分為BIOS程序與user程序兩部分[8],如圖1所示。其中,BIOS程序固化于MCU的非易失性存儲器中,MCU上電啟動時,先運行BIOS程序,再跳轉至user程序,隨后在user程序中啟動操作系統(tǒng)RT-Thread。在GEC架構下,BIOS程序為user程序提供工作時鐘與函數(shù)原型級調用接口,用戶在基于標準軟件工程框架的user程序中進行應用開發(fā),通過調用BIOS程序提供的構件進行快速編程。GEC架構從存儲空間和功能定義兩個方面實現(xiàn)了BIOS程序與user程序的合理劃分,為RT-Thread的駐留提供了應用基礎。以BIOS程序作為先導程序,實現(xiàn)RT-Thread在MCU硬件層的固化,用戶則專注于軟件層,在user程序中進行應用開發(fā)。下面從共性角度對RT-Thread駐留在BIOS的關鍵點進行分析。a)MCU的存儲資源是RTOS在實際應用中的首要考慮因素,尤其是在使用大多低成本終端設備時,其flash和RAM資源更為有限。因此,為了避免出現(xiàn)BIOS程序與user程序在物理地址上沖突而導致代碼重疊、變量越界等問題,需要對存儲資源進行合理有效的劃分與利用。b)RTOS的核心功能是通過調度器對線程進行管理,當RTOS駐留在BIOS程序后,為了實現(xiàn)調度器在user程序中的運轉,對系統(tǒng)中斷服務例程進行共享是實現(xiàn)BIOS程序與user程序在空間上保持聯(lián)動的必要項。c)RTOS具有豐富的函數(shù)調用接口,例如線程創(chuàng)建啟動、線程狀態(tài)轉換以及線程上下文切換等,RTOS駐留后,在user程序中不包含函數(shù)接口,用戶無法直接在user程序中調用函數(shù)。因此,如何定位并調用函數(shù)是RTOS駐留后正常使用系統(tǒng)服務的關鍵。
1.2 RTOS駐留方法研究與對比
RTOS作為運行在CPU內部的程序,通常與用戶程序一同編譯,導致存儲空間與CPU算力的開銷增長,文獻[9]利用現(xiàn)場可編程邏輯門陣列(FPGA)將μC/OS-Ⅲ內核硬件化,通過定制硬件調度器進行任務調度,使得CPU專注于用戶任務的運算,從而實現(xiàn)系統(tǒng)內核與用戶任務的隔離。這種方法具有直接在硬件層面運行的優(yōu)勢,可以利用FPGA的并行計算能力與低功耗特性,提供高度可定制化的解決方案,但同時也面臨著復雜的硬件設計與開發(fā)流程,不具備通用性、可移植性與擴展性,技術實現(xiàn)難度較大。文獻[10]針對人造器官軟件更新的應用場景,提出部分動態(tài)軟件更新機制,通過將輕量級實時操作系統(tǒng)Cyborgan OS的內核駐留在固定代碼區(qū)域,實現(xiàn)應用程序的增量更新與功能升級,該方法在確保系統(tǒng)穩(wěn)定性和可靠性的前提下,提供了更加靈活和高效的軟件更新方案。文獻[11]基于汽車嵌入式實時操作系統(tǒng)的順序內核展開形式建模和驗證研究,通過擴展C-IL / CC- IL配置狀態(tài)模型,為操作系統(tǒng)和可信任應用程序的內存隔離提供基礎機制,保障嵌入式系統(tǒng)的設計和開發(fā),提高了系統(tǒng)的可維護性和可擴展性。以上兩種方案通過固定代碼駐留RTOS的思想,為本文研究提供了重要的參考價值。不同的RTOS駐留方法在實時性能、資源利用率、開發(fā)復雜度以及可移植性等方面存在著差異。選擇合適的駐留方法需要綜合考慮具體的應用需求和系統(tǒng)要求。通過對上述方法的介紹和對比,可以進一步驗證本文方法的科學性和創(chuàng)新之處,并為讀者提供更全面的研究視角。
2 基于D1-H的GEC軟件框架設計與實現(xiàn)
嵌入式軟件工程由若干不同類型的文件組成,其中包括程序文件、頭文件、與編譯調試相關的文件、工程說明文件、開發(fā)環(huán)境生成文件等,基于GEC架構的層次化原則,將BIOS程序和user程序按照功能定義進行邏輯劃分,通過清晰的層次結構為長期的軟件維護和功能拓展提供保障。
1)BIOS程序工程框架 BIOS工程框架如表1所示,依據(jù)“分門別類,各有歸處”的原則將RT-Thread源碼駐留在BIOS程序的05_UserBoard文件夾,并在該文件下通過自定義的OsFunc.c程序對RT-Thread的啟動流程進行統(tǒng)一收攏,由OS_start函數(shù)調用RT-Thread實際的啟動函數(shù)。
2)user程序工程框架 user程序工程框架的組織架構與BIOS基本一致,不同之處在于05_UserBoard文件中的RT-Thread源碼被替換為了Os_Self_API.h文件,在07_AppPrg中增加了threadauto_appinit.c文件。其中,Os_Self_API.h頭文件是按照RT-Thread中的原函數(shù)進行重映射的接口文件,threadauto_appinit.c則用于存放RT-Thread操作系統(tǒng)中的自啟動線程函數(shù)app_init,即BIOS程序中函數(shù)OS_start的入口參數(shù),對于用戶而言,app_init則是進行應用程序開發(fā)的快速入口。
3 基于D1-H實現(xiàn)RT-Thread駐留的關鍵要素
在GEC架構下,BIOS與user在物理空間中是相互獨立的軟件工程,但兩者的代碼和變量都是在MCU的同一存儲空間下運行和定義的,若要成功實現(xiàn)RT-Thread的駐留,首先要對D1-H的flash與雙倍速率同步動態(tài)隨機存儲器(double data rate,DDR)進行合理分區(qū),從而保障RT-Thread正常調度運行。
3.1 片外flash與DDR的空間劃分
flash區(qū)主要用于保存工程編譯后的機器碼,包含了程序代碼、中斷向量和常數(shù)等。為確保用戶層的可擴展性,在滿足BIOS程序基本存儲空間需求后,將flash存儲空間的剩余量一并劃分到user程序下。為進一步提高BIOS程序和user程序對flash資源的利用率,依據(jù)緊湊劃分原則,從片外flash的零地址開始為BIOS程序分配空間,并將BIOS程序的結束地址作為user程序的起始地址。同時,為了保持各自的獨立性,防止user程序在開始寫入時出現(xiàn)意外擦除BIOS程序的情況,需要將BIOS程序與user程序各自的代碼分別存放在不同扇區(qū)。片外flash劃分樣例如圖2所示,1~n扇區(qū)為BIOS程序,n+1扇區(qū)及后續(xù)空間均為user程序。
DDR區(qū)主要由以下數(shù)據(jù)段組成:存放初始化不為0的全局變量或靜態(tài)變量的data段、存放未初始化或初始化為0的全局變量或靜態(tài)變量的bss段、存放臨時局部變量的heap段以及保存函數(shù)變量和參數(shù)的stack段?;谄鈌lash的劃分要點,將DDR中的BIOS程序和user程序進行獨立分區(qū),如圖3所示。該劃分方式的弊端表現(xiàn)為:BIOS程序運行結束后,釋放stack段的存儲空間且不再使用,在一定程度上造成了DDR資源的浪費。因此,在獨立分區(qū)的基礎上,保留BIOS程序和user程序的data段、bss段和heap段,將各自的stack段合并后設置為共享區(qū),如圖4所示,實現(xiàn)user程序對stack段的二次使用,從而有效提高DDR存儲資源的利用率。
3.2 BIOS程序與user程序的銜接
BIOS程序與user程序之間的銜接由以下兩個方面組成:為確保user程序的正常運行,需要由BIOS程序提供正確引導;當user程序運行異常時,需要由BIOS提供有效方法使得user程序順利回退至BIOS程序。
1)BIOS程序對user程序的正確引導 當BIOS程序燒錄至MCU內部后,通過特定標識信息對片外flash中的user程序進行檢測,若user程序存在,則由BIOS程序提供引導,將user程序拷貝到DDR,通過鏈接文件獲取user程序的運行地址和代碼量,并將PC指針指向user程序的復位函數(shù),在該函數(shù)內利用內嵌匯編加載并跳轉至user程序的運行地址,即可完成BIOS程序到user程序的跳轉,執(zhí)行過程如圖5所示。為了避免標識信息在熱復位后被清除,本文將該標識信息存放于user程序bss段與data段之間的獨立范圍內,保證了BIOS程序對user程序引導的可靠性與通用性。
2)由user程序返回BIOS程序 通過在短時間內對MCU進行6次熱復位,且每次觸發(fā)間隔控制在1 s左右,即可實現(xiàn)user程序主動返回至BIOS程序;若觸發(fā)次數(shù)不足6次,則清空已觸發(fā)次數(shù)并繼續(xù)運行user程序,具體執(zhí)行流程如圖6所示。
由于D1-H內部不包含識別冷復位與熱復位的控制狀態(tài)寄存器,本文利用熱復位不會導致存儲器內容丟失的特性,取消啟動文件中的bss段清零操作,對未初始化的全局變量進行判斷,若初值改變,則返回冷復位標志,反之則返回熱復位標志。
3.3 底層驅動的駐留與調用
底層驅動的駐留是指在BIOS程序中將底層驅動封裝為構件,通過應用程序編程接口(application programming interface,API)為用戶在user程序中提供函數(shù)調用服務。本文將底層驅動函數(shù)地址按照順序依次存放在全局指針數(shù)組ComponentFun,利用“attribute”關鍵字將該數(shù)組固定存儲在BIOS程序的“.component_list”數(shù)據(jù)段,并使用缺省函數(shù)reserved_func為接口函數(shù)的更新與擴充預留空間。在user程序中,按照全局指針數(shù)組ComponentFun中的存放順序,對接口函數(shù)的函數(shù)名、返回值類型和參數(shù)類型等進行重定義,通過全局指針數(shù)組的固定索引調用相應函數(shù)。具體實現(xiàn)方法如下:
__attribute__((section (".component_list"))) void *
ComponentFun[MAP_SECTORSIZE/2] = {
(void*) gpio_init,
(void*) gpio_set,
(void*) reserved_func,
}
#define 函數(shù)名((接口函數(shù)聲明指針表達形式)(全局數(shù)組[序號]))
4 RT-Thread駐留測試
RT-Thread的駐留測試工程在AHL-GEC-IDE開發(fā)環(huán)境和基于玄鐵C906內核的D1-H應用處理器上進行,首先運行BIOS程序,將RT-Thread駐留在D1-H的外接flash中,隨后運行user程序,并分別對線程間的事件、互斥量、信號量以及消息隊列四種同步與通信方式進行測試。
4.1 flash和DDR的實際空間劃分情況
D1-H外接NAND Flash[12]大小為256 MB,分為131 072個扇區(qū),用于存放程序、常數(shù)以及中斷向量;外接RAM為雙倍速率同步動態(tài)隨機存儲器第三代DDR3[13],大小為512 MB,用于存放全局變量、靜態(tài)變量以及堆棧空間。測試工程中NAND Flash采用圖2所示劃分方式,DDR3采用圖4所示劃分方式,RT-Thread駐留在BIOS后,NAND Flash與DDR3的空間劃分如表2所示。
4.2 RT-Thread駐留后程序啟動流程分析
當RT-Thread駐留到BIOS后,從D1-H上電復位到RT-Thread對用戶線程進行調度主要包含以下五個階段:啟動內部固化引導程序BROM、啟動第二階段程序SPL、啟動BIOS、由BIOS跳轉至user、啟動user以及啟動RT-Thread,其啟動流程如圖7所示。首先,D1-H上電復位后,按照內部機制從固化在片內ROM處的引導程序BROM開始執(zhí)行,接著啟動SPL,通過自定義程序完成對時鐘、串口以及DDR3的初始化,在將BIOS程序復制到DDR3的空間地址0x4000_0000后,開始BIOS的啟動,由硬件從NAND Flash的起始地址取出中斷向量表的第一個表項,賦值給堆棧指針寄存器SP進行初始化,程序計數(shù)器PC加載中斷向量表第二個表項,啟動BIOS復位向量,接著對DDR3中的各個數(shù)據(jù)段完成初始化,然后在主程序中調用user_jump跳轉至user程序。user程序的啟動過程與BIOS程序的啟動過程基本一致,唯一不同的是,user在主程序中調用函數(shù)rtthread_startup啟動RT-Thread,包括對板級硬件初始化、延時阻塞列表初始化、調度器初始化、創(chuàng)建自啟動線程和空閑線程、啟動調度器,然后由RT-Thread完成對用戶線程的調度運行。
4.3 駐留運行測試
在user程序中分別對事件、互斥量、信號量和消息隊列四種線程同步與通信方式進行功能測試。RT-Thread駐留測試工程的運行結果如表3所示。測試結果表明,RT-Thread成功駐留于BIOS程序,并在user程序中按照啟動流程順利實現(xiàn)了創(chuàng)建線程、啟動線程、延時調度以及四種同步與通信等功能,驗證了RT-Thread駐留方法的可行性。
a)事件測試工程。在串口中斷中設置紅燈事件,改變紅燈亮暗。b)互斥量測試工程。紅、綠、藍三種顏色的小燈按照紅燈5 s、綠燈10 s、藍燈20 s的順序單獨實現(xiàn)亮暗,每種顏色的小燈線程之間通過鎖定單色燈互斥量獨立占有資源。c)信號量測試工程。通過串口輸出線程申請、等待和釋放信號量的響應過程。d)消息隊列測試工程。通過消息隊列實現(xiàn)線程間的消息傳遞。觸發(fā)串口接收中斷后,通過串口發(fā)送的數(shù)據(jù)幀被存放到消息隊列,消息隊列接收線程每隔1 s從消息隊列中獲取消息并通過串口打印出消息內容和當前消息隊列中的消息量。
5 結束語
為了更好地發(fā)揮RT-Thread對嵌入式軟件開發(fā)的應用支撐,本文在GEC架構的設計基礎上,實現(xiàn)了國產RISC-V應用處理器D1-H的GEC軟件框架,深入剖析了實現(xiàn)RT-Thread駐留的關鍵要素,提出了BIOS程序正向引導與user程序順利回退兩種機制來有效實現(xiàn)BIOS程序與user程序之間的銜接,給出了具體的存儲空間劃分、底層驅動駐留與調用的實現(xiàn)方法。后續(xù)將進一步對RT-Thread架構中的協(xié)議棧、圖形庫以及虛擬文件系統(tǒng)等組件進行研究,實現(xiàn)用戶程序功能的擴展。
參考文獻:
[1]Wang K C.Embedded real-time operating systems[M].Berlin:Springer,2017:401-475.
[2]楊靜遠,黃保壘,楊弋.一種分區(qū)操作系統(tǒng)兩態(tài)下錯誤號處理策略[J].信息技術與信息化,2021(4):169-170.(Yang Jingyuan,Huang Baolei,Yang Yi.A partition operating system error number processing strategy under two states[J].Information Technology and Informatization,2021(4):169-170.)
[3]Chen Tanhong,Li Huiyong,Niu Jianwei,et al.Embedded partitioning real-time operating system based on microkernel[C]//Proc of IEEE International Conference on Computational Science and Engineering and IEEE International Conference on Embedded and Ubiquitous Computing.Piscataway,NJ:IEEE Press,2019:205-210.
[4]白曦,王俊.基于分區(qū)操作系統(tǒng)的機電軟件架構研究與應用[J].信息通信,2019,33(10):95-96.(Bai Xi,Wang Jun.Research and application of electromechanical software architecture based on partitioned operating system[J].Information Communication,2019,33(10):95-96.)
[5]邱祎,熊譜翔,朱天龍.嵌入式實時操作系統(tǒng):RT-Thread設計與實現(xiàn)[M].北京:機械工業(yè)出版社,2019:36-47.(Qiu Wei,Xiong Puxiang,Zhu Tianlong.Embedded real-time operating system:design and implementation of RT-Thread[M].Beijing:China Machine Press,2019:36-47.)
[6]Bansal S,Kumar D.IoT ecosystem:a survey on devices,gateways,ope-rating systems,middleware and communication[J].International Journal of Wireless Information Networks,2020,27:340-364.
[7]全志開發(fā)者社區(qū).D1-H芯片介紹[EB/OL].(2021-04-27).https://d1.docs.aw-ol.com.(Allwinner Online Developer Community.Introduction of D1-H chip[EB/OL].(2021-04-27).https://d1.docs.aw-ol.com.)
[8]王宜懷,李躍華,徐文彬,等.嵌入式技術基礎與實踐 [M].6版.北京:清華大學出版社,2021:51-57.(Wang Yihuai,Li Yuehua,Xu Wenbin,et al.Embedded technology foundation and practice[M].6th ed.Beijing:Tsinghua University Press,2021:51-57.)
[9]張曉宇.實時操作系統(tǒng)內核硬件化的研究與實現(xiàn)[D].沈陽:沈陽工業(yè)大學,2019.(Zhang Xiaoyu.Research and implementation of hardware for real-time operating system kernel[D].Shenyang:Shen-yang University of Technology,2019.)
[10]Lyu Pan,Li Hong,Qiu Jinsong,et al.Cyborgan OS:a lightweight real-time operating system for artificial organ[J].Security and Communication Networks,2020,2020:article ID 8871626.
[11]Zhang Haitao,Chen Lirong,Luo Lei.Formal modeling and verification of the sequential kernel of an embedded operating system[C]//Proc of the 18th International Computer Conference on Wavelet Active Media Technology and Information Processing.Piscataway,NJ:IEEE Press,2021:553-569.
[12]李中,周加誼,曹睿.基于NAND Flash固態(tài)硬盤的壞塊管理方法 [J].電子設計工程,2022,30(23):24-27,32.(Li Zhong,Zhou Jiayi,Cao Rui.Bad block management method based on NAND Flash solid state drive[J].Electronic Design Engineering,2022,30(23):24-27,32.)
[13]黃姣英,趙如豪,王琪,等.基于FPGA的DDR3 SDRAM控制器設計[J].現(xiàn)代電子技術,2022,45(22):68-74.(Huang Jiaoying,Zhao Ruhao,Wang Qi,et al.Design of DDR3 SDRAM controller based on FPGA[J].Modern Electronic Technology,2022,45(22):68-74.)