TMS320F28x(簡稱“F28x”)數字信號處理器是TI公司推出的32位定點DSP控製器,其頻率高達150 MHz,大大提高了控製係統的精度和芯片的處理能力。在F28x係列DSP上移植實時操作係統,需要對編譯器、係統啟動過程、中斷處理過程以及整體(ti) 代碼執行流程有一個(ge) 全麵的深入理解。對係統的整個(ge) 運行過程有清晰的概念是移植實時操作係統的前提條件。本文將對從(cong) DSP上電複位到其係統功能實現的整個(ge) 運行過程進行深入介紹,並在此基礎上進一步分析在F28x係列DSP上移植實時操作係統一般原理,詳細說明μC/OSⅡ的移植。
1 BootROM及其運行
在F281x、C281x、R281x器件中都有一塊4K×16位的BootROM。當引腳MP/nMC的狀態反映到XINTCNF2中為(wei) 0時,BootROM被映射到地址空間0x3FF000~0x3FFFC0上。片上ROM在出廠前就已經燒寫(xie) 好了一個(ge) 啟動程序以及一些其他數據和表格(版本信息、複位向量、中斷向量表、IQmath表等)。其空間分配如圖1所示。

圖1 片上BootROM分配
其中,中斷向量表在VMAP=1、ENPIE=0(PIE未使能向量表)、MPNMC=0時有效。另外,當VMAP=1、ENPIE=0時,係統將從(cong) BootROM的0x3FFFC0複位。雖然複位後ENPIE為(wei) 零,但大部分係統都是需要使能外部中斷擴展模塊的,即用戶程序中需要將ENPIE置1。由此可見,BootROM唯一常用的向量隻有複位向量;而其他的中斷向量是指向M0SRAM用於(yu) 芯片測試的,通常用不到。狀態位和向量表映射關(guan) 係如表1所列。
2 從(cong) 上電複位到用戶代碼
當係統重啟(上電或熱啟動)時,引腳XMPNMC的信號將被鎖存到XINTF的配置寄存器XINTCNF2中。重啟之後,XMPNMC的狀態不再反映到XINTCNF2,這時,可以用軟件來修改它的狀態,從(cong) 而確定程序要訪問的是內(nei) 部地址還是外部地址。但是,像F2810這樣的器件,沒有XINTF。它的XMPNMC在芯片內(nei) 部被拉低,也就是說,當器件重啟後,它總是自動從(cong) 內(nei) 部的BootROM啟動。如果XMPNMC為(wei) 高電平,則表示係統將從(cong) XINTF zone7中獲取複位向量。即從(cong) 外部獲取中斷向量(地址見表1)時,必須確保複位向量所指向正確的地址。這一般在希望自己編寫(xie) 啟動程序時使用。本文對此不作具體(ti) 討論。
當XMPNMC為(wei) 低電平時,係統從(cong) 內(nei) 部獲取複位向量。這個(ge) 複位向量指的就是上文中提到的BootROM中位於(yu) 0x3FFFC0的向量。此向量指向固化在BootROM中的InitBoot函數。所以上電複位後,程序將跳轉到InitBoot函數。
InitBoot函數首先對器件初始化,F281x器件將被配置為(wei) F28x工作模式。如果希望執行C2xLP兼容程序,則需要用戶自己寫(xie) 程序配置。PLL配置將保持不變。PIE使用缺省狀態,即不使能。另外要注意,M1的前80個(ge) 字將用做BootROM的堆棧,用戶應避免使用。初始化完成後,程序轉向執行SelectBootMode函數。此函數將掃描通用I/O口(GPIO),以確定啟動模式,如表2所列,包括跳轉到Flash、跳轉到H0 SARAM、跳轉到OTP等模式。
表1 狀態位和向量表映射關(guan) 係向量

表2 啟動模式

不同的模式有不同的程序起點(entrypoint)。對於(yu) Flash、H0 SARAM、OTP模式,有一個(ge) 固定的跳轉地址(見表2);而對於(yu) 從(cong) SCI、SPI啟動時,程序起點將調用bootloader按一定的格式(具體(ti) 格式見參考文獻[3])從(cong) 外部獲取。
最後,BootROM執行exitboot函數。執行這個(ge) 函數包括:置CPU狀態為(wei) 缺省,將SP指向0x400,跳轉到程序起點等工作。exitboot執行後CPU狀態為(wei) :ACC=0, RPC=0, P=0, XT=0, ST=0, XAR0=XAR7=0, SP=0x400, ST1=0x0A0B。
以上是BootROM完成的工作。從(cong) entrypoint開始,就進入用戶程序區了。對於(yu) 匯編程序,可以在程序起點處寫(xie) 一條跳轉到Start(如果程序起點是Start)的指令。匯編情況比較簡單,跳轉到Start後,各項初始化代碼工作都由自己完成。對於(yu) C語言程序,通常的做法是在程序起點處放置一條跳轉指令,轉到_c_init0。然後程序的執行分為(wei) 使用或不使用Bioses兩(liang) 種情況。
從(cong) rts.src中提取boot28.inc文件,其中包括對於(yu) 不使用Bioses的情況下,啟動後從(cong) _c_init0到main函數中間所做的工作。因為(wei) 這段代碼是由C編譯器自動運行的,因而常被初學者忽視,以致對其後自己編寫(xie) 的C代碼的運行環境不清楚。這一段程序主要完成以下工作:
◇ 分配C堆棧;
◇ 建立C運行環境(CPU寄存器和模式寄存器的配置);
◇ 複製cinit、pinit表、.const、.econst常量到工作區;
◇ 跳轉到main函數。
這段代碼聲明了2個(ge) 全局變量:__stack,係統堆棧棧底;_c_int00,啟動函數。下麵列出了C運行環境的初始化程序部分代碼:
C28OBJ;選擇C28x對象模式
C28ADDR;清除地址模式位
C28MAP;設置M0M1模式
CLRCPAGE0;使用堆棧尋址模式
MOVWDP,#0;初始化DP指向低64K地址
CLRCOVM;關(guan) 閉溢出模式
ASP;確保SP對齊
這些代碼設置了C語言的運行環境。在用戶程序中編寫(xie) 的匯編代碼不應該破壞這個(ge) 環境,否則C語言將無法正常運行。
3 中斷代碼的執行
#p#分頁標題#e#
F28x係列的DSP支持1個(ge) 不可屏蔽中斷(NMI)和16個(ge) 可屏蔽中斷(INT1~INT14、RTOSINT、DLOGINT)。其中,INT1~INT12由PIE控製單元管理。每個(ge) INT可以對應8個(ge) 外設中斷,即PIE可以控製96個(ge) 中斷源。
下麵對可屏蔽中斷響應過程作一介紹:
① 外設發出中斷請求。
② DSP看中斷請求是否被允許。設計PIEIER、PIEACK、IER、INTM等寄存器和標誌位的設置,具體(ti) 參見參考文獻[4]。
③ 如果中斷允許,則先執行完進入解碼的二階段之後的指令,將其他指令衝(chong) 出流水線。係統將自動保存ST0、T、AL、AH、PL、PH、AR0、AR1、DP、ST1、DBGSTAT、PC、IER,然後獲取中斷向量,加載到PC。
注意: 當中斷被允許後會(hui) 立即清除IFR中相應標誌位;但是,如果此時中斷信號仍有效(保持低電平),那麽(me) ,相應IFR標誌位又會(hui) 被置位(不過這時此中斷不會(hui) 被立即響應)。這是因為(wei) CPU禁止了所有的硬件中斷響應,當ISR開始執行時,它才解除禁止;並且,在執行ISR之前(此時原來的IER已保存),當前中斷的IER中相應位被清零。也就是說,同一中斷源的中斷不會(hui) 再被響應,要等到中斷服務子程序中用戶來使能中斷(如果需要嵌套),或者等到中斷返回自動恢複IER。
④ 執行中斷服務子程序。
由於(yu) 置位了INTM、DBGM,所以可屏蔽中斷默認是不被允許的。如果要嵌套,則需程序員自己動手清除禁止中斷標誌。另外,中斷裏麵LOOP、EALLOW、IDLESTAT都被清零了,這樣中斷服務子程序有了一個(ge) 全新的上下文。
4 從(cong) RAM中執行代碼
通常情況下,程序是保存在Flash裏麵的,CPU從(cong) Flash中取指運行;但是,有時會(hui) 要求將程序調到RAM中來執行。一方麵是為(wei) 追求更高的速度;另一方麵是為(wei) 了讓Flash有最好的運行性能,需要修改Flash的等待狀態周期,使能Flash Pipeline,而對Flash的操作必須在RAM裏麵執行,這些操作函數就必然要從(cong) Flash中調到RAM中執行。對於(yu) 這些程序,在啟動後用戶程序中需要先完成存儲(chu) 器拷貝工作。拷貝到RAM中之後,才能調用這些函數,順序不能亂(luan) 。
5 在DSP上移植實時操作係統
所謂移植,就是使一個(ge) 實時內(nei) 核能在某個(ge) 微處理器或微控製器上運行。在移植軟件之前,先要正確配置處理器的運行模式,了解處理器的中斷方式、中斷向量地址等。這些工作在F28x係列DSP中由BootROM中固化的程序完成。另外,為(wei) 了方便移植,大部分的RTOS代碼都是用C語言寫(xie) 的;但仍需要用C語言和匯編語言混合編寫(xie) 一些與(yu) 處理器相關(guan) 的代碼。這是因為(wei) 在讀寫(xie) 處理器寄存器時隻能通過匯編語言來實現。
對於(yu) 同時使用匯編語言和C語言的實時操作係統移植,必須小心使用匯編語言,防止破壞C語言運行環境。一方麵不可以改變相關(guan) 狀態位;另一方麵匯編函數的編寫(xie) 需要遵循C編譯器的調用規則。從(cong) 複位到用戶程序編譯器做的設置工作見前文。
中斷發生時,TMS320LF28x處理器自動保存了不少寄存器,但是如果中斷服務子程序中要用其他寄存器,那麽(me) 開始時要自己寫(xie) 現場保護程序。就實時操作係統而言,進入中斷和退出中斷須對係統堆棧進行現場保護。維護堆棧結構時,需要注意處理器堆棧的生長方向。雖然絕大多數微處理器和微控製器的堆棧是從(cong) 上往下長的,但TI公司的DSP一般為(wei) 從(cong) 下往上長。
一般實時操作係統需要先禁止中斷再訪問代碼的臨(lin) 界段,並且在訪問完畢後重新允許中斷。這就使得係統能夠保護臨(lin) 界段代碼免受多任務或中斷服務例程(ISRs)的破壞。最簡單的實現方法是直接調用處理器指令來禁止中斷和允許中斷。
筆者選擇了目前應用比較廣泛的實時操作係統μC/OS-Ⅱ。要移植μC/OS-Ⅱ需要滿足以下要求:
◇ 處理器的C編譯器能產(chan) 生可重入代碼;
◇ 用C語言就可以打開和關(guan) 閉中斷;
◇ 處理器支持中斷,並且能產(chan) 生定時中斷(通常在10~100 Hz之間);
◇ 處理器支持能夠容納一定量數據(可能是幾千字節)的硬件堆棧;
◇ 處理器有將堆棧指針和其他CPU寄存器讀出和存儲(chu) 到堆棧或內(nei) 存中的指令。移植工作包括以下幾個(ge) 內(nei) 容:
◇ 用#define設置一個(ge) 常量的值(OS_CPU.H);
◇ 聲明10個(ge) 數據類型(OS_CPU.H);
◇ 用#define聲明3個(ge) 宏(OS_CPU.H);
◇ 用C語言編寫(xie) 6個(ge) 簡單的函數(OS_CPU_C.C);
◇ 編寫(xie) 4個(ge) 匯編語言函數(OS_CPU_A.ASM)。
移植的難點在於(yu) 實現OS_CPU_A.ASM。這個(ge) 文件的實現需要十分清楚處理器啟動過程和中斷處理,以及代碼的運行過程。由於(yu) TI公司的DSP堆棧從(cong) 下往上長,所以移植時需要置OS_STK_GROWTH為(wei) 0。可以簡單地使用TIMS320LF28x的中斷使能和禁止命令來實現OS_ENTER_CRITICAL()、OS_EXIT_CRITICAL()兩(liang) 個(ge) 宏。
以下是移植時OS_CPU_A.ASM文件裏任務切換的代碼。任務切換時,須時刻注意自己設計的堆棧結構。
_OSCtxSw:
CALL_CTX_SAVE
LDPK_OSTCBCur; OSTCBCur>OSTCBStkPtr = SP
LARAR3, _OSTCBCur
MAR*, AR3
SARAR1, * , AR1
_OSIntCtxSw:
CALL_OSTaskSwHook; OSTaskSwHook()
LDPK_OSTCBHighRdy; OSTCBCur = OSTCBHighRdy
BLDD_OSTCBHighRdy,#_OSTCBCur
LDPK_OSPrioHighRdy; OSPrioCur = OSPrioHighRdy
BLDD_OSPrioHighRdy,#_OSPrioCur
LDPK_OSTCBHighRdy; SP=OSTCBHighRdy>OSTCBStkPtr
LARAR3, _OSTCBHighRdy
MAR*, AR3
LARAR1, *
B_CTX_REST, AR1
結語
本文詳細說明了從(cong) 上電複位開始,DSP中程序運行的過程;分析了固化在片上ROM的程序以及由編譯器自動生成的程序。另外,通過對DSP/Bioses啟動、中斷執行、從(cong) RAM中執行代碼等問題的探討,了解DSP的運行機製,掌握移植實時操作係統的關(guan) 鍵技術知識。筆者成功地將實時操作係統μC/OS-Ⅱ移植到了TMS320LF2812數字信號處理器上。
轉載請注明出處。







相關文章
熱門資訊
精彩導讀



















關注我們

