(中國空間技術研究院510所,甘肅蘭州730030)
嵌入式操作系統目前發展迅猛,被運用于飛機、雷達、航天等各個領域[1]。BM3803是基于SPARC V8體系結構的32位精簡指令國產化嵌入式處理器,可用于板上嵌入式實時計算機系統,具有功能強、抗輻照、高可靠和低功耗等特點,能適合多種航天應用功能及性能要求。在BM3803上,移植操作系統可以使應用工程軟件人員從與硬件平臺相關的繁瑣設計中解放出來,專注于具體的應用軟件開發研究。μC/OS-Ⅱ(Micro Control Operation System Two)操作系統是一個可以基于ROM運行、可裁減、搶占式、實時多任務內核,可移植性強,特別適合于微處理器和控制器,達到了DO-178B從E級到A級的標準。
本文結合BM3803的寄存器功能及μC/OS-Ⅱ操作系統的特點,詳細介紹了將μC/OS-Ⅱ操作系統移植到BM3803平臺的過程,并給出相應測試結果。
對于SPARC架構的CPU來說,其最大的特點是窗口寄存器結構。每組寄存器窗口包含32個窗口寄存器,分為4類:inputs,locals,outputs,globals,每類各8個,通常記為i0~i7,l0~l7,o0~o7和g0~g7,其中g0~g7是全局寄存器,其余24個為窗口的寄存器,相鄰寄存器之間的關系如圖1所示[2]。

圖1 相鄰窗口寄存器之間的相互關系
由圖1可以注意到相鄰寄存器窗口的outputs同時又是下一個窗口的inputs,這被稱作寄存器公用。寄存器窗口數為NWINDOWS,該值為21~25,即為2,4,8,16,32五種情況。在BM3803中該值為8。8組寄存器中有一組是當前窗口寄存器(CWP),同時也有一組是無效寄存器(WIM)。窗口寄存器之間通過加減來實現對程序的調度,比較常見操作是SAVE指令和RESTORE指令。SAVE指令能使當前窗口指針CWP減1,起到保存調用程序窗口的作用。RESTORE指令的作用相反,會使CWP加1,從而恢復調用程序的窗口。
8組寄存器一般分為4種狀態,分別是Current態、Invalid態、Used態和Unused態,如果假設%WIM的值為0x06,而CWP為2,則8組寄存器窗口的狀態分配如下:W2,Current;W3、W4、W5,Used;W6,Invalid;W7、W0、W1,Unused。整體的寄存器窗口寄存器組的原理如圖2所示[3]。
除了窗口寄存器外,還有特殊狀態寄存器,包括處理器狀態寄存器(%PSR)、窗口無效掩碼寄存器(%WIM)、異常基址標志寄存器(%TBR)、乘法/除法寄存器(%Y)、程序計數器(%PC,%NPC)和輔助狀態寄存器(%ASR)。其中最重要的是處理器狀態寄存器和窗口無效掩碼寄存器。
PSR一共32位,包含了多種字段來控制處理器和保持狀態信息[3]。PSR可以被SAVE,RESTORE,Ticc,RETT以及所有可以修改條件碼的指令所修改。PSR的格式如表1所示,其中比較重要的是第0~4位,這組成當前窗口指針(CWP),而第5位(ET)表示能否使用陷阱,1表示可以使用,表1為其字段分配。

圖2 窗口寄存器整體示意圖

表1 PSR字段的分配
WIM由管理軟件控制,硬件利用WIM來決定執行一條SAVE,RESTORE或者RETT指令是否會產生窗口上溢或下溢陷阱。陷阱是一種特殊的中斷形式。BM3803有8組寄存器窗口,因此該寄存器的低8位有效。當執行SAVE,RESTORE或者RETT指令時,CWP的當前值與WIM比較。如果SAVE,RESTORE或者RETT指令使CWP指向一個“無效”寄存器組,也就是對應的WIM位等于1(WIM[CWP]=1)的寄存器組的話,就會產生一個窗口上溢或者窗口下溢陷阱。當因為CWP減1而發生窗口上溢陷阱時,通常會將Used狀態的寄存器的值保存在RAM中。而當因為CWP加1而發生窗口下溢陷阱時,會將之前因為上溢陷阱保存于RAM中的寄存器的值讀取出來,以用于恢復之前的狀態。
嵌入式操作系統μC/OS-Ⅱ由Labrosse編寫,歷經20多年,其具有較高的可靠性和穩定性,達到了多類標準要求。本文使用的是其2.90版,其代碼結構可分為3個部分,如圖3所示。

圖3 μC/OS-Ⅱ的組成結構
由圖3可見,μC/OS-Ⅱ的組成包含3個部分,操作系統源代碼、與配置相關代碼和與移植相關代碼。下面分別介紹這3個文件的組成。
(1)操作系統源代碼是實現操作系統基本功能的代碼文件,組成包括:
os_core.c:操作系統內核文件,主要功能包括內核初始化、任務切換、事件塊管理等;
os_task.c:操作系統任務管理文件;
os_time.c:操作系統時間管理文件;
os_flag.c:操作系統事件標志組管理文件;
os_mbox.c:操作系統郵箱消息管理文件;
os_mem.c:操作系統內存管理文件;
os_sem.c:操作系統信號量管理文件;
os_mutex.c:操作系統互斥性信號量管理文件;
os_tmr.c:操作系統定時器管理文件;
os_q.c:操作系統消息隊列管理文件;
ucos_ii.c:源代碼的包含文件,作用是把源代碼所包含的C語言文件放置到一個文件里,使得編譯器能夠直接編譯;
ucos_ii.h:頭文件,負責內核函數參數設置。
(2)與配置相關代碼主要是為了符合應用的需要而改寫的,結構組成包括:
includes.h:與應用相關的包含文件,作用是加載與應用相關的一些頭文件,根據實際情況要做相應修改;
os_cfg.h:系統內核配置文件的頭文件;
os_dbg.c:內核調試數據和編譯函數文件。
(3)與移植相關代碼有3個[4]:
os_cpu.h:頭文件,負責與處理器相關變量、類型和宏的定義,比如堆棧方向、開關中斷的方式等;
os_cpu.s:匯編文件,負責與處理器直接相關的函數,主要是任務切換函數。因為C語言不太方便對寄存器直接進行操作所以用匯編語言編寫,同時也是移植的難點;
os_cpu_c.c:負責任務堆棧段的設置和一些HOOK函數的定義。HOOK函數是為應用的管理平臺監控任務的各種功能而設計的,可以只聲明,不包含任何代碼。
操作系統移植的一般過程如圖4所示。首先確定整體結構體系;再建立工程,把各個模塊加載進工程;再按照目標處理器的具體特點進行代碼的改寫和調試;再移植完畢后通過編寫測試代碼來驗證移植的正確性和可靠性。

圖4 移植操作系統的流程
μC/OS-Ⅱ的整體結構體系如圖5所示。系統的硬件包括BM3803開發板、存儲設備等;軟件部分包括操作系統內核、各種功能的管理文件和驅動設備(UART)等;最上層是根據不同需求設計的應用程序。

圖5 系統軟件整體結構
本文所使用的開發環境是SPE-C 2.52,這是一款針對BM3803,BM3802,BM3101應用軟件的開發平臺。它采用GNU的整套集成開發套件作為編譯和調試的組件,適合在32位的Windows系統環境下使用。
首先創建工程,將文件分為操作系統源代碼、與移植相關代碼、與平臺相關代碼和應用程序源代碼分別加載,結構如下:
(1)操作系統源代碼;
(2)與移植相關代碼:包括os_cpu.h,os_cpu.s和os_cpu_c.c;
(3)與平臺相關代碼:BM3803mg.h(與平臺相關的常數定義)和trap.s(平臺的陷阱列表);
(4)應用程序源代碼:主要用于測試本文中的移植結果,其中包括serial.c和serial.h串口操作源代碼文件及其頭文件,os_dbg.c,app_cfg.h和test.c。
下面分別給出移植需要處理的代碼[5]:
(1)os_cpu.h
對于os_cpu.h,主要修改的部分是其堆棧長度和堆棧增長方向(由高地址向低地址生長),同時對于任務切換函數(OS_TASK_SW())、時鐘節拍中斷服務函數(OSTickISR())、開關中斷函數等也要有相應的定義。
(2)os_cpu_c.c
對于os_cpu_c.c,重點是堆棧段的設計。BM3803的堆棧段標準定義的程序主要包含棧頂指針(%sp)和棧底指針(%fp),以及一些必須保存的寄存器的值,寄存器的初始化如圖6所示。
圖6中這些部分都是常規堆棧。根據實際情況,BM3803還有浮點寄存器,所以實際的堆棧長度比圖中所示還要長。

圖6 堆棧段的設計
(3)os_cpu.s
由于任務切換需要與寄存器進行直接交互,需要采用匯編語言來編寫任務切換部分的代碼,而該部分代碼是移植的最重要內容。本文的任務切換部分代碼放置于os_cpu.s文件中。主要包括的函數為OSStart High Rdy(),OSCtxSw(),OSIntCtxSw(),OSTick ISR()以及開關中斷函數。函數OSStart HighRdy()的功能是找到優先級最高的任務,并將最高優先級的任務堆棧中的內容復制到寄存器中,就好像剛執行完中斷一樣,緊接著去執行優先級最高的就緒任務。
任務級任務調度函數和中斷級任務調度函數大部分代碼類似,不同的是任務級任務調度函數(OSCtxSw())有保存上下文的操作。具體過程是先保存程序寄存器(%PC)和處理器狀態寄存器(%PSR)的值,然后申請足夠的空間用于保存上下文,再保存當前任務控制塊的棧頂位置,最后再保存棧頂指針,返回位置、所在窗口寄存器等。需要注意的是,OSCtxSw()是由軟中斷(ta指令)實現的,所以在trap.s中的軟中斷列表(0x80~0x FF)中一定要設置中斷入口。后面的過程與OS-IntCtxSw()一致。
中斷級任務調度(OSIntCtxSw())由退出中斷函數OSInt Exit()調用,在任務發生中斷時完成任務的調度,主要工作是將當前任務的任務控制塊指針(OSTCBCur)更換為OSStart High Rdy所指的位置[5],從而得到最高優先級任務的任務控制塊地址,然后將當前任務優先級轉換為最高優先級,再調出最高優先級任務的任務控制塊,將最高優先級任務寄存器的值從堆棧中恢復到寄存器中,最后用jmpl和rett從中斷處返回,具體的流程如圖7所示。

圖7 任務調度
函數OSTickISR()負責時鐘節拍中斷服務[4],其核心功能是通過調用函數OSTime Tick()來跟蹤與任務相關的定時器,判斷是否超時來完成時間的延遲和超時功能,以保證任務之間的同步。BM3803有兩個定時器(timer1和timer2),選擇timer1產生一定周期的系統中斷來實現時鐘節拍,所以在trap.s中要在timer1的位置設置時鐘節拍中斷服務程序的入口OSTickISR。中斷的嵌套是比較關鍵的問題,由于OSTickISR()在嵌套層數為1時要先保存上下文,再對timer1進行操作,而嵌套層數不為1時直接對timer1進行操作,所以要在函數內進行嵌套層數的判斷。在進入OSInt Enter(內核函數,負責中斷加1)之前要保存上下文。在調用完OSTimeTick()執行退出中斷函數(OSIntExit)時也要對嵌套層數進行判斷,如果還處于多層嵌套中,則無需執行任務切換,直接恢復上下文,具體的流程如圖8所示。

圖8 定時中斷服務
開關中斷函數是通過直接對寄存器%PSR的操作來實現的。BM3803的陷阱一共有15個優先級,在%PSR的第5位(ET,陷阱使能)使能的情況下IU會將%PSR的第8~11位(PIL,可接受的陷阱優先級)與中斷請求等級比較,如果中斷請求等級大于或等于PIL字段值,即未屏蔽此中斷,則處理器響應該中斷請求。利用這一點可以直接將PIL位設為1111,這樣所有的中斷請求都被屏蔽了,實現了屏蔽中斷的功能。同理將PIL位設置為0000就可以實現打開中斷的功能。
完成所有的修改后,需要編寫測試程序來驗證移植的正確性。
編寫測試代碼的主要目的是驗證操作系統是否移植完成、各項基本功能是否正常[6]。本次移植所編寫的測試代碼是為了驗證創建任務、任務延時、定時器設置、時鐘中斷服務程序和串口操作程序是否能正常運行。
測試代碼的結構比較具有針對性。操作系統本身是個無限循環,要保證每時每刻都要有任務存在,因此系統自動創建了空閑任務,空閑任務會在系統啟動后立刻開始執行,并且優先級始終設為最低。在設計測試代碼時,考慮到空閑任務的存在,要把創建任務的優先級、堆棧空間設置好。首先為任務task1和task2申請堆棧,通過串口初始化函數將串口1的波特率和模式設置好(模式指對串口1控制寄存器的值進行設置,本例用的是0x3,即發送和接收位使能)。初始化μC/OS-Ⅱ后,創建任務task1和task2,task1的優先級為5,task2的優先級為6。通過函數OSStart()啟動操作系統。在task1中先設置時鐘節拍,再循環以10個節拍的延時后通過串口輸出字符“-task1-”,task2也是同樣的功能,但延時的時鐘節拍數為2,串口輸出字符為“-task2-”。具體流程圖如圖9所示。

圖9 測試代碼流程圖
程序運行后,在PC機上打開串口調試軟件后看到的結果為每接收到5次“-task2-”,接收到1次“-task1-”。結果證實了本文的移植方法是合理和正確的,測試結果如圖10所示。

圖10 測試結果
SPARC架構的CPU使用了窗口寄存器,使得工作效率得到提高,目前已經廣泛應用于航天領域。對于SPARC架構的CPU浮點運算功能的開發和使用會成為以后工作的重點。
本文在國產新型CPU BM3803上移植了經典的嵌入式操作系統μC/OS-Ⅱ,實現了多任務、高實時性的嵌入式操作系統在這款CPU上的使用,使得任務調度、時間管理等功能更加完善,為后續應用程序的開發和使用創造了良好條件。同時為這款CPU上移植其他操作系統起到良好的示范作用。
[1]熊毅,張承志.VxWorks平臺下的米波雷達點跡凝聚方法研究[J].雷達科學與技術,2009,7(6):443-446.
XIONG Yi,ZHANG Chengzhi.A Plot Clotting Approach of Meter Wave Radar Based on Vx Works[J].Radar Science and Technology,2009,7(6):443-446.(in Chinese)
[2]詹盼盼,郭廷源,高建軍,等.基于BM3803處理器的即插即用星載計算機系統設計[J].航天器工程,2013,22(6):92-96.
ZHAN Panpan,GUO Tingyuan,GAO Jianjun,et al.Plug-and-Play On-Board Computer System Design Based on BM3803 Processor[J].Spacecraft Engineering,2013,22(6):92-96.(in Chinese)
[3]馮磊,李飛.SPARC結構與實時內核的移植[J].微計算機信息(嵌入式與SOC),2006,22(12-2):6-8,49.
[4]LABROSSE J.嵌入式實時操作系統μC/OS-Ⅱ[M].2版.邵貝貝,譯.北京:北京航空航天大學出版社,2003.
[5]朱東亮.基于LPC1343的UCOS-II移植[J].中國新通信,2013(17):111-112.
[6]任鎖平.基于μC/OS-Ⅱ的嵌入式校園導航系統的設計與實現[J].自動化與儀器儀表,2014(11):139-141.