摘要:介紹源代碼公開的實時操作系統(tǒng)μC/OS-II的特點,、內(nèi)核結(jié)構(gòu)及ADSP—BF53l的硬件特征,,同時給出將μC/0S-II移植到ADSP-BF531型數(shù)字信號處理器上的詳細步驟和關(guān)鍵代碼。
關(guān)鍵詞:RTOS,;μC/OS-II,;ADSP-BF53l;移植
引言
隨著計算機技術(shù)的發(fā)展,,嵌入式系統(tǒng)的應(yīng)用愈來愈廣泛,,對人們的生活產(chǎn)生了巨大的影響。通常,,嵌入式系統(tǒng)的軟件部分都應(yīng)用了實時操作系統(tǒng)(簡稱RTOS),,在特定的RTOS之上開發(fā)應(yīng)用軟件,可以讓程序開發(fā)人員屏蔽掉許多底層硬件細節(jié),,提高軟件功能設(shè)計效率,,簡化開發(fā)難度,同時使得程序調(diào)試方便,,移植簡單,,易維護,大大縮短開發(fā)周期,,RTOS也因此越來越受到嵌入式系統(tǒng)開發(fā)人員的青睞,。目前實時操作系統(tǒng)很多,如VxWorks,、Windows CE,、pSOS等,但這些軟件的價格和使用成本(版權(quán)費,、維護費等)都十分昂貴,,因此商業(yè)級RTOS軟件在使用上受到諸多的限制,。而μC/OS-II則不同,,它的源代碼是全部公開的,并且完全免費,,是一個自由操作系統(tǒng),,程序開發(fā)人員可以改寫其中的源代碼使之符合自己的要求。由于其極強的可移植性和可裁減性,,用戶可以根據(jù)自己的需要,裁剪掉不需要的部分,使操作系統(tǒng)變得小巧靈活,,同時又能夠滿足用戶特定操作系統(tǒng)的需要,。μC/OS-II的可靠性完全可以與商業(yè)級RTOS軟件相媲美,因此筆者在移植過程中選用了這一實時操作系統(tǒng)。
1 ADSP—BF531的硬件特征
Blackfin系列中的ADSP—BF531型數(shù)字信號處理器是由ADl和Intel公司合作,,針對音頻和視頻信號的編解碼,、手持設(shè)備和移動通信設(shè)備而研發(fā)的16位定點處理器,是建立在微信號架構(gòu)基礎(chǔ)之上,,集高性能數(shù)字信號處理器與微控制器于一身,。ADSP-BF53l的內(nèi)核工作頻率最高可達400MHz,處理器內(nèi)核中包含2個16位MAC,、2個40位ALU及4個8位ALU,。專門用于視頻信號的處理;還集成了許多片上外設(shè),,包括硬件UART,、SPI接口、PPI接口,、同步串口,、
看門狗電路、16個GPIO接口等,。為了達到降低功耗的目的,,該處理器具有多種工作模式,同時通過編程還可以動態(tài)改變處理器內(nèi)核的工作頻率和電壓.這些特性都為手持設(shè)備提供了絕佳的選擇,。用戶可以利用ADI公司提供的VisualDSP++3.0(或更高版本)集成開發(fā)環(huán)境對處理器進行編程,、調(diào)試和開發(fā)。
2 實時操作系統(tǒng)介紹
μC/OS-II是一種專門為微處理器設(shè)計的占先式實時多任務(wù)操作系統(tǒng),,具有源代碼公開,、可移植性和可裁減性強、代碼可固化,、穩(wěn)定性和可靠性高等特點,。其內(nèi)核主要提供任務(wù)管理、內(nèi)存管理,、時間管理等服務(wù),,系統(tǒng)最多可以支持64個任務(wù)(8個留于系統(tǒng)),每個任務(wù)均有自己獨立的優(yōu)先級,。由于內(nèi)核為占先式的,,因此總是運行優(yōu)先級最高的任務(wù)。系統(tǒng)提供了豐富的函數(shù)可供調(diào)用,,實現(xiàn)任務(wù)間的通信和切換,。μ/OS-II的大部分代碼都是使用標準的A-NIS C編寫的.只有與處理器相關(guān)的一部分代碼使用匯編語言.因此具有極強的移植性,在大多數(shù)8位,、16位和32位處理器上都能穩(wěn)定的運行,。
圖1示出μC/OS-II的軟硬件體系結(jié)構(gòu),。從圖中可以看出,要實現(xiàn)μC/OS-II的移植,,必須為其編寫OS_CPU.H,、0S_CPU_C.C和OS_CPU_A.ASM 3個文件,這3個文件都與處理器的硬件特性相關(guān),,提供任務(wù)切換和系統(tǒng)時鐘功能,。其余源文件的代碼都是公開的,可以直接從μC/OS-II的官方網(wǎng)站下載,。
3對編譯器的要求
雖然μC/OS-II具有很強的移植性,,但在移植時,對處理器的編譯器有如下幾點要求:
處理器的C編譯器能夠產(chǎn)生可重人代碼,;
用C語言可以打開和關(guān)閉中斷,;
處理器支持中斷,并且能夠產(chǎn)生定時中斷,;
處理器能夠容納一定量數(shù)據(jù)的硬件堆棧,;
處理器有將堆棧指針和其他CPU寄存器讀出和存儲到堆棧空間或內(nèi)存中的指令,。
ADSP-BF531型處理器的集成開發(fā)環(huán)境Visu-al++3.0通過關(guān)鍵字asm能在C代碼中嵌入?yún)R編語言,,同時內(nèi)核定時器可以為系統(tǒng)提供定時中斷,總數(shù)量達20kbyte的片上數(shù)據(jù)RAM和SP,、FP,、USP 3個堆棧指針寄存器為操作系統(tǒng)各任務(wù)提供了豐富的硬件堆棧空間及對堆棧的方便操作,。筆者正是在這些基礎(chǔ)上利用Visual++3.0編譯環(huán)境成功地完成了對ADSP-BF531處理器的μC/OS-II移植,。
4 移植μJLC/OS-II
4.1重定義OS_CPIJ.H文件
4.1.1與編譯器相關(guān)的數(shù)據(jù)類型
不同的處理器有不同的字長,μC/OS-II不使用C的short,、int,、long等與編譯器相關(guān)的數(shù)據(jù)類型,而是重新定義了一系列類型以確保系統(tǒng)的可移植性,,在系統(tǒng)移植時必須在OS_CPU.H頭文件中對這些數(shù)據(jù)類型重新定義,,具體內(nèi)容如下:
typedef unsigned char BOOLEAN
typedef unsigned char INT8U
typedef signed char INT8S
typedef unsigned short INTl6U
typedef signed short INTl6S
typedef unsigned int INT32U
typedef signed int INT32S
μC/OS-II中的指針根據(jù)處理器堆棧數(shù)據(jù)入口寬度定義為OS_STK類型:
typedef unsigned int OS_STK
4.1.2臨界代碼
RTOS在進入系統(tǒng)臨界區(qū)之前都必須先關(guān)中斷,退出后再開中斷,,μC/OS-II定義了2個宏指令來關(guān)閉/打開中斷:
#define OS_ENTER_CRITICAL0
asm(“cli%O:”:”=d”(InterrupLach))
#define OS_EXIT_CRITICAL()
asm(“sti%0:”::”=d”(InterrupLaeh))
其中InterrupLaeh為一全局變量,,用于開關(guān)中斷時
IMASK寄存器內(nèi)容的恢復(fù)和保存,。
4.1.3堆棧增長方向設(shè)定
在OS CPU.H頭文件中還必須根據(jù)處理器堆棧的增長方向?qū)S_STK_GROWTH進行宏定義,,由于ADSP-BF531是按照由高地址到低地址的結(jié)構(gòu)組織處理器堆棧,因此宏定義如下:
#define OS_STK_GROWTH 1
4.1.4 OS_TASK_SW0宏定義
OS_TASK_SW0在μC/OS-II從低優(yōu)先級任務(wù)切換到高優(yōu)先級任務(wù)時被調(diào)用,,定義如下:
#define OS_TASK_sw() asm(“raise 13,;”)
4.2編寫OS_CPU_C.C文件
μC/OS-lI的移植要求用戶在OS_CPU_C.C文件中編寫6個簡單的C函數(shù),其中主要是完成OS-TaskStkInit (),其余5個函數(shù)可以不作處理,。OS-TaskStkInit()負責任務(wù)堆棧的初始化,,使得任務(wù)堆棧看起來就像剛發(fā)生過中斷并將所有的寄存器保存到堆棧中的情形一樣,。不同的編譯器在函數(shù)調(diào)用時有不同的入棧方法,,因此在具體實現(xiàn)時必須根據(jù)處理器的編譯環(huán)境進行調(diào)整。VisualDSP++3.0在函數(shù)調(diào)用時的堆棧結(jié)構(gòu)如圖2所示,。
OSTaskStkInit()調(diào)用時需要傳遞任務(wù)代碼起始地址(task),、用戶參數(shù)指針(pdata)、任務(wù)堆棧頂端的地址(堆棧棧頂指針ptos),、返回參數(shù)為新任務(wù)堆棧棧頂指針,,函數(shù)原型如下:
void OSTaskStkInit()
{OS_STK*stk;
stk=(void *)ptos,;
opt=opt,;
*stk--=fINT32U)pdata;//用戶數(shù)據(jù)區(qū)
*stk--=fINT32U)(task),;//RETI寄存器
*stk--=fINT32U)ptos,;//FP寄存器
(由于需要入棧的寄存器數(shù)量比較多,限于篇幅,,在此省略其中多數(shù))
*stk--=fINT32U)0,; //SEQSq、AT寄存器
*stk--=fINT32U)0,;//ASTAT寄存器
retum((void*)stk),;}
任務(wù)建立時調(diào)用該函數(shù)對新建任務(wù)的堆棧進行初始化,初始化后的堆棧結(jié)構(gòu)如圖3所示,。
4.3編寫OS_CPU_A.ASM文件
μC/OS-II移植的最后還需要用戶編寫4個重要的匯編函數(shù),,包括OSStartHighRdy()、OSCtxSw(),、OSIntCtxSw()及OSTickISR(),。分別介紹如下:
4.3.1 OSStartltighRdy()函數(shù)
該函數(shù)由OSStart()調(diào)用,用以運行優(yōu)先級最高的就緒任務(wù),,其運行過程:調(diào)用用戶定義的OS-TaskSwHook()數(shù)→獲取任務(wù)堆棧指針→置位全局
變量0SRunning 出棧CPU寄存器 中斷返回,。在ADSP-BF531中的實現(xiàn)如下:
_OSStartHighRdy:
call_OSTaskSwHook;
p0.1=_OSTCBHighRdy,;
p0.h=_0STCBHighRdy,;
pl=[p0];
ssync,;
sp=[p1],;
p0.1=_OSRunning,;
p0.h=_OSRunning;
r0=TRUE,;
[p0]=r0;
ASTAT=[sp++],;
SEQSTAT=[sp++];
FP =[sp++],;
RETI=[sp++,;
rti;
4.3.2 OSCtxSw()函數(shù)
實時操作系統(tǒng)內(nèi)任務(wù)級的切換是通過處理器的軟中斷實現(xiàn)的,,并且軟中斷服務(wù)例程的向量地址必須指向OSCtxSw()函數(shù),,因此該函數(shù)的匯編程序代碼如下:
_OSCtxSw:
[--sp]=RETI;
[--sp]=FP,;
[--sp]=SEQTAT,;
[--sp]=ASTAT;
p0.1=_OSTCBCur,;
p0.h=_OSTCBCur,;
pl=[p0];
ssync,;
[pl]=sp,;
call_OSTaskSwHook;
p0.1 =_OSPrioHighRdy,;
p0.h=_OSPrioHighRdy,;
r0=[p0];
p0.1=_0SPrioCur,;
p0.h=_OSPrioCur,;
[p0]=r0;
p0.1=_OSTCBHighRdy,;
p0.h=_OSTCBHighRdy,;
pl=[p0];
rO=[p0],;
ssync,;
sp=[p1];
p0.1=_OSTCBCur,;
p0.h=_OSTCBCur,;
[p0]:r0; ,、
ASTAT=[sp++],;
SEQSTAT=[sp++];
FP:[SP++],;
RETI=[sp++],;
rti;
4.3.3 OSIntCtxSw()函數(shù)
OSIntCtxSw()用于實現(xiàn)中斷級任務(wù)切換,,由于該函數(shù)在中斷服務(wù)程序中調(diào)用,,因此在函數(shù)代碼中不需要寄存器入棧,但堆棧結(jié)構(gòu)中還包含了一些用戶不需要的函數(shù)調(diào)用返回地址,,因此該函數(shù)必須在最初清理堆棧(調(diào)整堆棧指針的位置),,其匯編程序代碼如下:
_OSIntCtxSw:
p0=20;
sp=sp+p0,;
p0.1=_OSTCBCur,;
p0.h=_OSTCBCur;
pl=[p0],;
ssync,;
[p1]=sp;
call_OSTaskSwHook,;
p0.1=_OSPrioHighRdy,;
p0.h=_OSPrioHighRdy;
r0=[p0],;
p0.1=_OSPrioCur,;
p0.h=_OSPfioCur;
[po]=10,;
p0.1=_OSTCBHighRdy,;
p0.h=_OSTCBHighRdy;
pl=[p0],;
r0=[p0],;
ssync;
sp=[p1],;
p0.1=_OSTCBCur,;
p0.h=_0STCBCur;
[po】=r0,;
ASTAT=[sp++],;
SEQSTAT=[sp++];
FP =[sp++],;
RETI=[sp++],;
rti;
4.3.4 OSTicklSR()函數(shù)
μ,C/OS-II要求用戶提供一個時鐘資源來實現(xiàn)時間的延時和期滿功能,。筆者在移植過程中使用內(nèi)核定時器產(chǎn)生時鐘節(jié)拍,,并通過定時器中斷服務(wù)例程OSTickISR0實現(xiàn)任務(wù)切換等功能,該函數(shù)的匯編程序代碼如下:
_OSTicklSR:
[--sp】=RETI,;
[--sp]=FP,;
[--sp]=SEQTAT,;
[--sp]=ASTAT;
call_OSIntEnter,;
call_OSTimeTick,;
call_OSIntExit;
ASTAT=[sp++],;
SEQSTAT=[sp++],;
FP =[sp++];
RETI=[sp++],;
rti,;
4.4程序下載及調(diào)試
完成以上文件的修改和編寫之后。就可在Vi-sualDSP++3.0環(huán)境中對所有的源文件進行編譯和連接,,生成處理器可執(zhí)行的.dxe文件,,通過JTAG直接下載到處理器內(nèi)核的程序區(qū)運行。由于VisualD-SP++3.0提供了強大的調(diào)試功能,,用戶能夠很清楚地了解μC/OS--II在處理器內(nèi)的運行情況,,這無疑也對μC/OS-Ⅱ向ADSP—BF531移植提供了強大的支持。
5 結(jié)束語
詳細介紹了向ADSP—BF531型處理器移植μC/OS-II實時操作系統(tǒng)的步驟和與處理器相關(guān)函數(shù)的代碼編寫,,并成功地進行移植,。通過測試,實時操作系統(tǒng)各任務(wù)之間的調(diào)用,、中斷處理,、任務(wù)之間的通信等都能夠穩(wěn)定的運行。μC/OS-II實時操作系統(tǒng)的使用,。將程序員從冗繁的流程圖中解放出來,,使得應(yīng)用程序的設(shè)計過程大大簡化,并且程序的可讀性,、擴展性,、可靠性也得到了很大的改善。
------------
關(guān)于μC/OS-II系列軟件版權(quán)的說明
Micrium 公司產(chǎn)品包括μC/OS-II,,μC/GUI,,uC/FS,μC/TCP-IP,,μC/USB等,。Micrium 公司提供嵌入式系統(tǒng)應(yīng)用方面的產(chǎn)品,并對其軟件擁有知識產(chǎn)權(quán),。Micrium花費了大量的時間和財力為嵌入式領(lǐng)域提供高質(zhì)量的軟件產(chǎn)品,。所有上述產(chǎn)品都以源代碼的形式提供給客戶,具有極大的適用性。產(chǎn)品不是免費軟件,,也不是開放源碼的軟件,,因此,不能免費使用,,需要清楚的闡明μC/OS-II和系列的軟件不是開放源碼的免費軟件,,這是和Linux完全不一樣的。
開發(fā)和研究者可以通過購買Micrium公司的Jean先生的μC/OS-II的書籍,,而得到μC/OS-II源代碼,但是僅可以作為個人和學(xué)校學(xué)習(xí)使用,,所有和μC/OS-II直接和間接相關(guān)的商業(yè)目的行為,,必須購買使用μC/OS-II及系列產(chǎn)品的商業(yè)授權(quán),,包括芯片/單板/系統(tǒng)廠家的任何參考設(shè)計,教學(xué)設(shè)備和最終的產(chǎn)品,,如果沒有得到Micrium公司Jean先生簽字的合法授權(quán)都是不合法的使用, 這在μC/OS-II的書籍Micrium公司(www.micrium.com)和中國代理商-北京麥克泰軟件公司網(wǎng)站(www.bmrtech.com)上面中有明確規(guī)定,。
Micrium公司其它軟件如μC/GUI,μC/FS,,μC/TCP-IP,,μC/USB 等的銷售模式與μC/OS-II不同,如果沒有購買使用授權(quán),,完全不可以擁有該源代碼,,也不能將源代碼用于產(chǎn)品的設(shè)計,培訓(xùn),,教學(xué)和生產(chǎn),。
μC/OS-II, μC/GUI,μC/FS,,μC/TCP-IP,,μC/USB 等授權(quán)方式有:單個產(chǎn)品、產(chǎn)品線(系列),、按照CPU 劃分的產(chǎn)品三種形式,,μC/OS-KA,μC/OS-VIEW 等工具是按照使用人的數(shù)目收取費用的,,相對起傳統(tǒng)的RTOS 動輒2-3萬美圓的開發(fā)費用和每塊單板的使用費(根據(jù)數(shù)量從數(shù)百到幾個美圓),,μC/OS-II及系列產(chǎn)品是采用一次性的收費方式,應(yīng)該只是大約相當于傳統(tǒng)RTOS 的10-20% 的總體費用,。
如果您正在將μC/OS-II系列軟件用于您的產(chǎn)品,,您需要購買并獲得正式使用授權(quán)。
北京麥克泰軟件技術(shù)有限公司