嵌入式系統(tǒng)工程課程設計報告_第1頁
嵌入式系統(tǒng)工程課程設計報告_第2頁
嵌入式系統(tǒng)工程課程設計報告_第3頁
嵌入式系統(tǒng)工程課程設計報告_第4頁
嵌入式系統(tǒng)工程課程設計報告_第5頁
已閱讀5頁,還剩36頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、2010/2011學年第2學期課程設計任務書課程名稱 : 嵌入式系統(tǒng)工程課程設計 班 級 : 計算計控制0901 姓名 :學號 :教學周數 : 2周 地 點 : 嵌入式系統(tǒng)實訓室(205)指導教師 :一 、實訓目的(1):進一步熟悉ADS集成環(huán)境的使用方法。(2):熟悉ARM7硬件平臺和UCOSII操作系統(tǒng),掌握操作系統(tǒng)移植的原理與具體過程。將uCOS-II 核移植到ARM7 微處理器上(3):了解uCOS-II 的嵌入式系統(tǒng)BootLoader 的框架和編寫過程 (4):了解MP3 歌曲的編、解碼的相關知識。(5):掌握MP3 文件的格式并能分析幀數據結構。(6):掌握MP3 歌曲的解碼播放

2、的基本方法。(7):學習解碼播放存中的一段MP3 歌曲。(8):掌握ARM7實驗箱上各模塊的電路結構,功能,與能進行熟練的使用。二 、設計容uCOS-II的剪裁和移植,學習在實驗箱上實現MP3歌曲的播放。軟件: WINDOWS XP、ARM SDT 或ADS或IAR、超級終端通訊程序、仿真器、驅動程序。硬件:聯想CPU 420,1.60GHZ 電腦一臺,S3C44B0主板一塊,多功能JTAG調試下載器一個,串口線一根,并口線一根,5V電源一個。三 、實訓環(huán)境四 、實訓步驟(1)BootLoader 實驗1、實驗目的了解基于uCOS-II 的嵌入式系統(tǒng)BootLoader 的框架和編寫過程。2、

3、實驗容編寫簡單的BootLoader 程序,實現Shell Menu 測試功能以與應用程序引導功能,并燒寫到ROM 中驗證。3、預備知識1掌握在ARM SDT 2.5 或ADS1.2 集成開發(fā)環(huán)境中編寫和調試程序的基本過程。2了解計算機啟動引導過程。4、實驗設備與工具硬件:ARM 嵌入式開發(fā)平臺、用于ARM7TDMI 的JTAG 仿真器、PC 機Pentium100 以上。軟件:PC 機操作系統(tǒng)win98、Win2000 或WinXP、ARM SDT 2.51 或ADS1.2 集成開發(fā)環(huán)境、仿真器驅動程序、超級終端通訊程序嵌入式系統(tǒng)設計與實例開發(fā)實驗指導書1176、實驗步驟1在編譯環(huán)境下新建工

4、程。需要注意的是,由于BootLoader 映象文件最終運行的地址空間是0Bank,所以該工程的連接地址不同于其他運行于SDRAM 的工程。Release 版本的ROBase 是0x0,RW Base 是0xc600000;由于該工程的Debug 版本還可以進行仿真調試,所以Debug 版本的RO Base 是0xc400000,RW Base 是0xc600000(Debug 版本的連接地址設置僅供參考)。另外,也可以把工程最后產生的二進制文件名改為bootloader.bin,詳情參考“SDT2.5 和ADS1.2 環(huán)境設置實驗”。ADS 環(huán)境下,該工程無需其他工程才具有的init 目錄,

5、而ARMLinker 配置中的Output選項中LinkerType 也要選擇Simple,然后輸入上述地址即可。把本實驗目錄下的源文件加入工程。在這里沒有給出文件系統(tǒng)的源碼,所以把文件系統(tǒng)的庫文件也加入到工程中。SRC 目錄下包括系統(tǒng)啟動的必須初始化配置文件和部分用到的硬件驅動,以實現檢測功能。2打開main.c 文件,查看BootLoader 的編寫過程。這里首先作了必要的硬件初始化,僅給出了NAND FLASH 自檢例程(沒有給出芯片操作細節(jié)),然后輸出提示信息。接下來會等待查詢是否有鍵按下,如果沒有則直接引導系統(tǒng);否則顯示Shell Menu。3每個菜單項都對應一個類型為Bios_fu

6、nction 的結構體變量,其中包括該菜單項的功能函數指針,快捷鍵,菜單中的提示信息等容。所有這些結構體變量都在一個數組中,嵌入式系統(tǒng)設計與實例開發(fā)實驗指導書118以方便檢索。在顯示菜單后程序等待按鍵并根據鍵值查找對應的功能函數。typedef struct Bios_func_t func;char *pShellMenu; /shell 模式下顯示的菜單字符串char MenuAcc; /shell 模式下菜單快捷鍵char *pCommand; /命令行模式下的命令char *pHelp; /命令行模式下的幫助Bios_function;4有的測試功能函數不是一直運行結束再返回菜單,而是

7、邊對目標進行操作邊查詢終端是否有停止命令,如果有則立刻返回,否則繼續(xù)執(zhí)行。BootLoader 是這樣完成該動作的:index=Set_UartLoopFunc(ADTest_Loop);Uart_Getch(0);Clear_UartLoopFunc(index);其中ADTest_Loop 是對AD 硬件的操作函數。Set_UartLoopFunc() 函數把ADTest_Loop設置到串口輪詢函數數組中。Uart_Getch()函數查詢串口是否有輸入,如果沒有的話就調用串口輪詢數組中的函數,否則立刻返回。請查看相關代碼分析這種測試過程。5實現引導功能的代碼并不復雜,請查看Boot()和L

8、oadFile()兩個函數源碼。由于有了文件系統(tǒng),只須打開并讀取指定文件到指定位置即完成了裝載,然后把程序指針指向該位置即實現了控制的轉移。int LoadFile(char *filename, unsigned char *pbuffer)_FILE *file;int i;file=OpenOSFile(filename,FILEMODE_READ);if(file=NULL)return FALSE;ReadOSFile(file, pbuffer, file->filesize);CloseOSFile(file);return TRUE;void Boot(char *pbo

9、otfile)if(pbootfile=NULL)pbootfile=SYSTEM_CODE; /File name is system.bindisconnect_USB(); /Exit USBrINTMSK=0xffffffff; /close all interrupt. Default value=0x7ffffffinitOSFile(); /initialize the FILE systemif(!LoadFile(pbootfile,(unsigned char *)(DOWNLOAD_ADDRESS)Uart_Printf("nCan not find file

10、%s",pbootfile);return; run();程序中定義了函數指針static void (*run)(void)=(void(*)(void)DOWNLOAD_ADDRESS;嵌入式系統(tǒng)設計與實例開發(fā)實驗指導書119并把指定位置的地址強制轉換為函數指針類型,然后使用run() 即可運行該地址處的指令了。DOWNLOAD_ADDRESS 實際實際上被定義為0xc080000。6對工程進行編譯,使用合適的燒寫工具,比如博創(chuàng)科技的硬件仿真器,把Release版本的bootloader.bin 燒寫到BOOT FLASH 中。注意燒寫的映象文件必須是Release 版本的。注意

11、:在本實驗中請用戶確保有可靠的燒寫工具后再嘗試把本實驗的結果燒寫到BOOT FLASH中。否則可能無確恢復原有BIOS 將會導致系統(tǒng)不能正常使用!而Debug 版本也可以用仿真器進行調試,但是點GO 按鈕后最好按住平臺鍵盤不放,使程序進入測試狀態(tài);假如程序在調試中嘗試實現引導功能的話,可能出現無法預料的結果,因為調試的時候bootloader 自己就在SDRAM,而引導過程也是把目標復制到SDRAM,如果地址空間重疊,勢必導致程序運行失常。前邊設置Debug 版本的RO Base 是0xc400000,RW Base 是0xc600000,而引導程序的目標地址是0xc080000,如果裝載sy

12、stem.bin 文件后地址空間沒有沖突,則Debug 版本也可以正常引導。7、思考題1在bootloader 實驗中是何時安裝的文件系統(tǒng),該文件系統(tǒng)是如何安裝的?2PC 機硬盤引導過程是怎樣的?對比嵌入式設備理解引導過程。_這里的BootLoader 和前邊曾經提到的BIOS 在功能上是沒有差別的。其功能包括上電后對系統(tǒng)進行自檢,主要包括SDRAM,CACHE,FLASH 等硬件;提供Shell Menu 檢測設置菜單和相應的檢測程序;引導操作系統(tǒng)與應用程序。需要說明,平臺的BIOS 燒寫到一片2M BOOT FLASH 芯片中,相當于BOOT ROM,該芯片掛在系統(tǒng)總線上,占用0Bank

13、地址空間;當系統(tǒng)上電或硬件復位后首先從0Bank 的0x00000000地址執(zhí)行指令,也就是從BIOS 開始執(zhí)行程序。BIOS 首先獲得系統(tǒng)的控制權。而操作系統(tǒng)以與應用程序等則是拷貝到另外一片16M NAND FLASH 芯片中的,而且是用文件系統(tǒng)進行管理的,這相當于一個海量存儲器或電子硬盤,同時當平臺激活USB 時,該芯片構成U 盤使用。BootLoader 所謂的引導功能指的是:BootLoader 程序首先獲得系統(tǒng)的控制權之后,對關鍵硬件自檢沒有發(fā)現故障并且控制臺沒有發(fā)出啟用Shell Menu 檢測菜單的情況下,依據文件系統(tǒng)的管理和支持,從電子硬盤即16M NAND FLASH 中讀取

14、操作系統(tǒng)或應用程序的代碼到SDRAM 的指定位置,然后把程序指針轉移到該位置,從而使操作系統(tǒng)獲得控制權,完成引導過程。在Shell Menu 檢測菜單中也可以設置實現引導功能的命令。由于BootLoader 依賴文件系統(tǒng)進行引導,所以可以按文件名進行查找,在平臺的BIOS中規(guī)定操作系統(tǒng)所在文件的文件名必須是“system.bin”。所以所有的工程設置中都將最后產生的二進制文件命名為“system.bin”。(2)uCOS-II 在ARM 微處理器上的移植與編譯一、實驗目的1了解uCOS-II 核的主要結構。2掌握將uCOS-II 核移植到ARM7 處理器上的基本方法。二、實驗容1將uCOS-I

15、I 核移植到ARM7 微處理器上。2編寫兩個簡單任務,在超級終端上觀察兩個任務的切換。三、預備知識1掌握在ARM SDT 2.5 或ADS1.2 集成開發(fā)環(huán)境中編寫和調試程序的基本過程。2了解ARM7 處理器的結構。嵌入式系統(tǒng)設計與實例開發(fā)實驗指導書1203了解uCOS-II 系統(tǒng)結構。四、實驗設備與工具硬件:ARM 嵌入式開發(fā)平臺、用于ARM7TDMI 的JTAG 仿真器、PC 機Pentium100 以上。軟件:PC 機操作系統(tǒng)win98、Win2000 或WinXP、ARM SDT 2.51 或ADS1.2 集成開發(fā)環(huán)境、仿真器驅動程序、超級終端通訊程序。五、實驗原理所謂移植,指的是一個

16、操作系統(tǒng)可以在某個微處理器或者微控制器上運行。雖然uCOS-II的大部分源代碼是用C 語言寫成的,仍需要用C 語言和匯編語言完成一些與處理器相關的代碼。比如:uCOS-II 在讀寫處理器、寄存器時只能通過匯編語言來實現。因為uCOS-II 在設計的時候就已經充分考慮了可移植性,所以,uCOS-II 的移植還是比較容易的。要使uCOS-II 可以正常工作,處理器必須滿足以下要求:1處理器的C 編譯器能產生可重入代碼??芍厝氲拇a指的是一段代碼(如一個函數)可以被多個任務同時調用,而不必擔心會破壞數據。也就是說,可重入型函數在任何時候都可以被中斷執(zhí)行,過一段時間以后又可以繼續(xù)運行,而不會因為在函數

17、中斷的時候被其他的任務重新調用,影響函數中的數據。下面的兩個例子可以比較可重入型函數和非可重入型函數:程序1:可重入型函數void swap(int *x, int *y)int temp;temp=*x;*x=*y;*y=temp;程序2:非可重入型函數int temp;void swap(int *x, int *y)temp=*x;*x=*y;*y=temp;程序1 中使用的是局部變量temp 作為變量。通常的C 編譯器,把局部變量分配在棧中。嵌入式系統(tǒng)設計與實例開發(fā)實驗指導書121所以,多次調用同一個函數,可以保證每次的temp 互不受影響。而程序2 中temp 定義的是全局變量,多次

18、調用函數的時候,必然受到影響。代碼的可重入性是保證完成多任務的基礎,除了在C 程序中使用局部變量以外,還需要C 編譯器的支持。筆者使用的是ARM SDT 以與ADS 的集成開發(fā)環(huán)境,均可以生成可重入的代碼。2在程序中可以打開或者關閉中斷。在uCOS-II 中,可以通過OS_ENTER_CRITICAL()或者OS_EXIT_CRITICAL()宏來控制系統(tǒng)關閉或者打開中斷。這需要處理器的支持,在ARM7TDMI 的處理器上,可以設置相應的寄存器來關閉或者打開系統(tǒng)的所有中斷。3處理器支持中斷,并且能產生定時中斷(通常在10Hz1000Hz 之間)。uCOS-II 是通過處理器產生的定時器的中斷來

19、實現多任務之間的調度的。在ARM7TDMI的處理器上可以產生定時器中斷。4處理器支持能夠容納一定量數據的硬件堆棧。5處理器有將堆棧指針和其他CPU 寄存器存儲和讀出到堆棧(或者存)的指令。uCOS-II 進行任務調度的時候,會把當前任務的CPU 寄存器存放到此任務的堆棧中,然后,再從另一個任務的堆棧中恢復原來的工作寄存器,繼續(xù)運行另一個任務。所以,寄存器的入棧和出棧是uCOS-II 多任務調度的基礎。圖3-2 說明了uC/OS 的結構以與它與硬件的關系。嵌入式系統(tǒng)設計與實例開發(fā)實驗指導書圖3-2 uCOS-II 硬件和軟件體系結構ARM7TDMI 處理器完全滿足上述要求。接下來將介紹如何把uC

20、OS-II 移植到Samsung 公司的一款ARM7TDMI 的嵌入式處理器S3C44B0X 上。六、實驗步驟1該實驗的文件分為兩類,其一是STARTUP 目錄下的系統(tǒng)初始化、配置等文件,其二是uCOS-II 的全部源碼,arch 目錄下的3 個文件是和處理器架構相關的。2設置os_cpu.h 中與處理器和編譯器相關的代碼typedef unsigned char BOOLEAN;typedef unsigned char INT8U;typedef signed char INT8S;typedef unsigned int INT16U;typedef signed int INT16S;

21、typedef unsigned long INT32U;typedef signed long INT32S;typedef float FP32;typedef double FP64;typedef unsigned int OS_STK;typedef unsigned int OS_CPU_SR;嵌入式系統(tǒng)設計與實例開發(fā)實驗指導書123extern int INTS_OFF(void);extern void INTS_ON(void);#define OS_ENTER_CRITICAL() cpu_sr = INTS_OFF(); #define OS_EXIT_CRITICAL(

22、) if(cpu_sr = 0) INTS_ON(); #define OS_STK_GROWTH 11)與編譯器相關的數據類型因為不同的微處理器有不同的字長,所以uCOS-II 的移植包括了一系列的類型定義以確保其可移植性。尤其是uCOS-II 代碼從不使用C 的short,int 和long 等數據類型,因為它們是與編譯器相關的,不可移植。相反的,我們定義的整形數據結構既是可移植的又是直觀的。為了方便,雖然uCOS-II 不使用浮點數據,但我們還是定義了浮點數據類型。例如,INT16U 數據類型總是代表16 位的無符號整數?,F在,uCOS-II 和用戶的應用程序就可以估計出聲明為該數據類型

23、的變量的取值圍是065535。將uCOS-II 移植到32 位的處理器上也就意味著INT16U 實際被聲明為無符號短整形數據結構而不是無符號整數數據結構。但是,uCOS-II 所處理的仍然是INT16U。用戶必須將任務堆棧的數據類型告訴給uCOS-II。這個過程是通過為OS_STK 聲明正確的C 數據類型來完成的。我們的處理器上的堆棧成員是16 位的,所以將OS_STK 聲明為無符號整形數據類型。所有的任務堆棧都必須用OS_STK 聲明數據類型。2)OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()與所有的實時核一樣,uCOS-II 需要先禁止中斷再訪問代碼的臨界區(qū),

24、并且在訪問完畢后重新允許中斷。這就使得uCOS-II 能夠保護臨界區(qū)代碼免受多任務或中斷服務例程(ISR)的破壞。在S3C44B0X 上是通過兩個函數(OS_CPU_A.S)實現開關中斷的。INTS_OFFmrs r0, cpsr ; 當前 CSRmov r1, r0 ; 復制屏蔽orr r1, r1, #0xC0 ; 屏蔽中斷位msr CPSR, r1 ; 關中斷(IRQ and FIQ)and r0, r0, #0x80 ; 從初始CSR 返回FIQ 位mov pc,lr ; 返回INTS_ONmrs r0, cpsr ; 當前 CSRbic r0, r0, #0xC0 ; 屏蔽中斷msr

25、 CPSR, r0 ; 開中斷 (IRQ and FIQ)mov pc,lr ; 返回1243)OS_STK_GROWTH絕大多數的微處理器和微控制器的堆棧是從上往下長的。但是某些處理器是用另外一種方式工作的。uCOS-II 被設計成兩種情況都可以處理,只要在結構常量OS_STK_GROWTH 中指定堆棧的生長方式就可以了。置OS_STK_GROWTH 為0 表示堆棧從下往上長。置OS_STK_GROWTH 為1 表示堆棧從上往下長。3用C 語言編寫6 個操作系統(tǒng)相關的函數(OS_CPU_C.C)1)OSTaskStkInitOSTaskCreate()和OSTaskCreateExt()通過

26、調用OSTaskStkInit()來初始化任務的堆棧結構。因此,堆??雌饋砭拖駝偘l(fā)生過中斷并將所有的寄存器保存到堆棧中的情形一樣。圖-3 顯示了OSTaskStkInt()放到正被建立的任務堆棧中的東西。這里我們定義了堆棧是從上往下長的。在用戶建立任務的時候,用戶傳遞任務的地址,pdata 指針,任務的堆棧棧頂和任務的優(yōu)先級給OSTaskCreate()和OSTaskCreateExt()。一旦用戶初始化了堆棧,OSTaskStkInit()就需要返回堆棧指針所指的地址。OSTaskCreate()和OSTaskCreateExt()會獲得該地址并將它保存到任務控制塊(OS_TCB)中。圖3-

27、3 堆棧初始化(pdata 通過堆棧傳遞)OS_STK * OSTaskStkInit (void (*task)(void *pd), void *pdata, OS_STK *ptos,INT16U opt) unsigned int * stk;stk = (unsigned int *)ptos; /* 裝載堆棧指針 */opt+; /* 為新任務建立堆棧 */*-stk = (unsigned int) task; /* pc */低地址存存儲的處理器寄存器值中斷返回地址處理器狀態(tài)字任務起始地址pdata高地址存堆棧指針堆棧增長方向嵌入式系統(tǒng)設計與實例開發(fā)實驗指導書125*-stk

28、= (unsigned int) task; /* lr */*-stk = 12; /* r12 */*-stk = 11; /* r11 */*-stk = 10; /* r10 */*-stk = 9; /* r9 */*-stk = 8; /* r8 */*-stk = 7; /* r7 */*-stk = 6; /* r6 */*-stk = 5; /* r5 */*-stk = 4; /* r4 */*-stk = 3; /* r3 */*-stk = 2; /* r2 */*-stk = 1; /* r1 */*-stk = (unsigned int) pdata; /* r0

29、 */*-stk = (SUPMODE); /* cpsr */*-stk = (SUPMODE); /* spsr */return (OS_STK *)stk);2)OSTaskCreateHook當用OSTaskCreate() 和OSTaskCreateExt() 建立任務的時候就會調用OSTaskCreateHook()。該函數允許用戶或使用移植實例的用戶擴展uCOS-II 功能。當uCOS-II設置完了自己的部結構后,會在調用任務調度程序之前調用OSTaskCreateHook()。該函數被調用的時候中斷是禁止的。因此用戶應盡量減少該函數中的代碼以縮短中斷的響應時間。當OSTask

30、CreateHook()被調用的時候,它會收到指向已建立任務的OS_TCB 的指針,這樣它就可以訪問所有的結構成員了。函數原型:void OSTaskCreateHook (OS_TCB *ptcb)3)OSTaskDelHook當任務被刪除的時候就會調用OSTaskDelHook()。該函數在把任務從uCOS-II 的部任務鏈表中解開之前被調用。當OSTaskDelHook()被調用的時候,它會收到指向正被刪除任務的OS_TCB 的指針,這樣它就可以訪問所有的結構成員了。OSTaskDelHook()可以來檢驗TCB擴展是否被建立(一個非空指針)并進行一些清除操作。函數原型:void OST

31、askDelHook (OS_TCB *ptcb)4)OSTaskSwHook當發(fā)生任務切換的時候就會調用OSTaskSwHook() 。OSTaskSwHook()可以直接訪問OSTCBCur 和OSTCBHighRdy,因為它們是全局變量。OSTCBCur 指向被切換出去的任務OS_TCB,而OSTCBHighRdy 指向新任務OS_TCB。注意在調用OSTaskSwHook()期間中斷一直是被禁止的。因此用戶應盡量減少該函數中的代碼以縮短中斷的響應時間。函數原型:void OSTaskSwHook (void)5)OSTaskStatHookOSTaskStatHook()每秒鐘都會被O

32、STaskStat()調用一次。用戶可以用OSTaskStatHook()嵌入式系統(tǒng)設計與實例開發(fā)實驗指導書126來擴展統(tǒng)計功能。例如,用戶可以保持并顯示每個任務的執(zhí)行時間,每個任務所用的CPU 份額,以與每個任務執(zhí)行的頻率等。函數原型:void OSTaskStatHook (void)6)OSTimeTickHookOSTimeTickHook()在每個時鐘節(jié)拍都會被OSTaskTick()調用。實際上,OSTimeTickHook()是在節(jié)拍被uCOS-II 真正處理,并通知用戶的移植實例或應用程序之前被調用的。函數原型:void OSTimeTickHook (void)后5 個函數為

33、鉤子函數,可以不加代碼。只有當OS_CFG.H 中的OS_CPU_HOOKS_EN 被置為1 時才會產生這些函數的代碼。4用匯編語言編寫4 個與處理器相關的函數(OS_CPU.ASM)1)OSStartHighRdy ();運行優(yōu)先級最高的就緒任務OSStartHighRdyLDR r4, addr_OSTCBCur ; 得到當前任務TCB 地址LDR r5, addr_OSTCBHighRdy ; 得到最高優(yōu)先級任務TCB 地址LDR r5, r5 ; 獲得堆棧指針LDR sp, r5 ; 轉移到新的堆棧中STR r5, r4 ; 設置新的當前任務TCB 地址LDMFD sp!, r4MSR

34、 SPSR, r4LDMFD sp!, r4 ; 從棧頂獲得新的狀態(tài)MSR CPSR, r4 ; CPSR 處于 SVC32Mode 摸式LDMFD sp!, r0-r12, lr, pc ; 運行新的任務2)OS_TASK_SW ();任務級的任務切換函數OS_TASK_SWSTMFD sp!, lr ; 保存 pcSTMFD sp!, lr ; 保存 lrSTMFD sp!, r0-r12 ; 保存寄存器和返回地址MRS r4, CPSRSTMFD sp!, r4 ; 保存當前的PSRMRS r4, SPSRSTMFD sp!, r4 ; 保存SPSR; OSPrioCur = OSPri

35、oHighRdyLDR r4, addr_OSPrioCurLDR r5, addr_OSPrioHighRdyLDRB r6, r5STRB r6, r4; 得到當前任務TCB 地址嵌入式系統(tǒng)設計與實例開發(fā)實驗指導書127LDR r4, addr_OSTCBCurLDR r5, r4STR sp, r5 ; 保存sp 在被占先的任務的 TCB; 得到最高優(yōu)先級任務TCB 地址LDR r6, addr_OSTCBHighRdyLDR r6, r6LDR sp, r6 ; 得到新任務堆棧指針; OSTCBCur = OSTCBHighRdySTR r6, r4 ; 設置新的當前任務的TCB 地址

36、;保存任務方式寄存器LDMFD sp!, r4MSR SPSR, r4LDMFD sp!, r4MSR CPSR, r4; 返回到新任務的上下文LDMFD sp!, r0-r12, lr, pc3)OSIntCtxSw();中斷級的任務切換函數OSIntCtxSwadd r7, sp, #16 ; 保存寄存器指針LDR sp, =IRQStack ;FIQ_STACKmrs r1, SPSR ; 得到暫停的 PSRorr r1, r1, #0xC0 ; 關閉 IRQ, FIQ.msr CPSR_cxsf, r1 ; 轉換模式 (應該是 SVC_MODE)ldr r0, r7, #52 ; 從I

37、RQ 堆棧中得到IRQ's LR (任務 PC)sub r0, r0, #4 ; 當前PC 地址是(saved_LR - 4)STMFD sp!, r0 ; 保存任務 PCSTMFD sp!, lr ; 保存 LRmov lr, r7 ; 保存 FIQ 堆棧 ptr in LR (轉到 nuke r7)ldmfd lr!, r0-r12 ; 從FIQ 堆棧中得到保存的寄存器STMFD sp!, r0-r12 ;在任務堆棧中保存寄存器;在任務堆棧上保存PSR 和任務 PSRMRS r4, CPSRbic r4, r4, #0xC0 ; 使中斷位處于使能態(tài)STMFD sp!, r4 ; 保

38、存任務當前 PSRMRS r4, SPSRSTMFD sp!, r4 ; SPSR; OSPrioCur = OSPrioHighRdy / 改變當前程序LDR r4, addr_OSPrioCur嵌入式系統(tǒng)設計與實例開發(fā)實驗指導書128LDR r5, addr_OSPrioHighRdyLDRB r6, r5STRB r6, r4; 得到被占先的任務TCBLDR r4, addr_OSTCBCurLDR r5, r4STR sp, r5 ; 保存sp 在被占先的任務的 TCB; 得到新任務 TCB 地址LDR r6, addr_OSTCBHighRdyLDR r6, r6LDR sp, r6

39、 ; 得到新任務堆棧指針; OSTCBCur = OSTCBHighRdySTR r6, r4 ; 設置新的當前任務的TCB 地址LDMFD sp!, r4MSR SPSR, r4LDMFD sp!, r4BIC r4, r4, #0xC0 ; 必須退出新任務通過允許中斷MSR CPSR, r4LDMFD sp!, r0-r12, lr, pc4)OSTickISR();時鐘節(jié)拍中斷多任務操作系統(tǒng)的任務調度是基于時鐘節(jié)拍中斷的,uCOS-II 也需要處理器提供一個定時器中斷來產生節(jié)拍,借以實現時間的延時和期滿功能。但在本系統(tǒng)移植uCOS-II 時,時鐘節(jié)拍中斷的服務函數并非uCOS-II 文獻

40、中提到的OSTickISR(),而直接是C 語言編寫的OSTimeTick()。請參考“定時器中斷實驗”的容,時鐘節(jié)拍中斷的產生與該實驗中所述容類似。本系統(tǒng)uCOS-II 移植時占用的時鐘資源是TIMER1。在平臺初始化函數ARMTargetInit()中,調用uHALr_InitTimers()函數初始化TIMER1相關寄存器;調用uHALr_InterruptRequestInit()函數初始化中斷請求,其過語句SetISR_Interrupt(INT_TIMER1_OFFSET, OSTimeTick, NULL)將OSTimeTick()函數設置為TIMER1 的中斷服務函數。這些函數

41、在文件UHAL.C 以與ISR.C 中。程序中必須在開始多任務調度之后再允許時鐘節(jié)拍中斷,即在OSStart()調用過后,uCOS-II 運行的第一個任務中啟動節(jié)拍中斷。如果在調用OSStart()啟動多任務調度之前就啟動時鐘節(jié)拍中斷,uCOS-II 運行狀態(tài)可能不確定而導致崩潰,請參考uCOS-II 文獻移植一節(jié)。本系統(tǒng)是在系統(tǒng)任務SYS_Task 中調用uHALr_InstallSystemTimer()函數打開IRQ 和TIMER1 中斷的,從而啟動時鐘節(jié)拍。本實驗A 部分的SYS_Task 見下文第5 步所述。在系統(tǒng)提供的完整uCOS-II 庫中,SYS_Task()在文件OSAddT

42、ask.C 中定義,用戶不必創(chuàng)建,請參考本實驗B 部分“完善的uCOS-II 開發(fā)框架”。完成了上述工作以后,uCOS-II 就可以運行在ARM 處理器上了。編寫一個簡單的多任務程序來測試一下移植是否成功。為了使uCOS-II 可以正常運行,除了上述必須的移植工作外,硬件初始化和配置文件也嵌入式系統(tǒng)設計與實例開發(fā)實驗指導書129是必須的。STARTUP 目錄下的文件還包括中斷處理,時鐘,串口通信等基本功能函數。在文件main.c 中給出了應用程序的基本框架,包括初始化和多任務的創(chuàng)建,啟動等。任務創(chuàng)建方法如下:1)在程序開頭定義任務堆棧,任務函數聲明和任務優(yōu)先級:OS_STK TaskName_

43、StackSTACKSIZE=0, ; /任務堆棧void TaskName(void *Id); /任務函數#define TaskName_Prio N /任務優(yōu)先級2)在main()函數中調用OSStart()函數之前用下列語句創(chuàng)建任務:OSTaskCreate(TaskName,(void*)0,(OS_STK*)&TaskName_StackSTACKSIZE-1,TaskName_Prio);OSTaskCreate()函數的原型是:INT8U OSTaskCreate (void (*task)(void *pd), void *p_arg, OS_STK *ptos,

44、INT8U prio);需要將任務函數TaskName,任務堆棧TaskName_Stack,任務優(yōu)先級TaskName_Prio 三個參數傳給OSTaskCreate()函數。根據任務函數的容決定堆棧大小,宏STACKSIZE 定義為4KB,可以在此基數上乘倍。任務優(yōu)先級越高,TaskName_Prio 值越??;uCOS-II 可以管理64個任務,由OSInit()創(chuàng)建的空閑任務的優(yōu)先級最低為63;uCOS-II 保留4 個最高和4 個最低優(yōu)先級,用戶任務可以使用其余56 個優(yōu)先級值。3)編寫任務函數容:void TaskName(void *Id)/添入任務初始化語句for(;) /添入任

45、務循環(huán)容OSTimeDly(SusPendTime);/掛起一定時間,以使其他任務可以占用CPUuCOS-II 至少要有一個任務,這里首先創(chuàng)建一個系統(tǒng)任務SYS_Task,其中由語句OSRunning=TRUE; /使能uCOS-II 運行uHALr_InstallSystemTimer();啟動系統(tǒng)時鐘和多任務切換。為了驗證uCOS-II 多任務切換的進行,再編寫兩個簡單的任務,分別在超級終端上輸出run task1 和run task2??梢詤⒖糾ain.c 的結構創(chuàng)建多個不同功能的任務,觀察個任務的切換。1編譯并下載移植后的uCOS-II所有的源代碼都準備好后就可以進行編譯了。在ADS

46、環(huán)境下需要設置工程的訪問路徑。嵌入式系統(tǒng)設計與實例開發(fā)實驗指導書130從菜單Edit | Debug Settings 進入設置對話框,在Target | Access Paths 中選擇User Paths并選上Always search user paths。然后點Add 按鈕添加路徑ucos-ii 和arch。這主要是設置編譯器處理文件包含時的搜索圍。按照實驗一的方法可以對編譯后的代碼進行調試或下載到平臺的電子硬盤中。這個實驗從結構上看和其他的實驗沒有多大區(qū)別,同樣生成可執(zhí)行文件system.bin??梢栽谄脚_BIOS中激活電子硬盤,然后把system.bin 拷貝進去,重啟平臺,然后在

47、超級終端上觀察結果。七、思考題1UCOS-II 是如何利用定時器中斷來實現多任務之間的調度的?_(3)音頻實驗一、實驗目的1掌握S3C44B0X 自帶的IIS 音頻接口的使用方法。2掌握DMA 數據傳輸方式。二、實驗容學習S3C44B0X 自帶的IIS 音頻接口的使用,通過DMA 數據傳輸方式編程實現對WAV 聲音文件(不超過10 秒)的循環(huán)播放。三、預備知識1、用ARM SDT 2.5 或ADS1.2 集成開發(fā)環(huán)境,編寫和調試程序的基本過程。2、基于uCOS-II 操作系統(tǒng)的應用程序的框架結構。3、會使用Source Insight 3 編輯C 語言源程序。4、學習IIS 音頻總線協(xié)議。5、

48、學習DMA 數據傳輸方式四、實驗設備與工具硬件:ARM 嵌入式開發(fā)平臺,用于ARM7TDMI 的JTAG 仿真器、PC 機Pentium100 以上、耳麥。軟件:PC 機操作系統(tǒng)win98 以上、ARM SDT 2.51 或ADS1.2 集成開發(fā)環(huán)境、仿真器驅動程序、Source Insight 3.0。嵌入式系統(tǒng)設計與實例開發(fā)實驗指導書134五、實驗原理與說明1WAV 音樂格式在Windwos 環(huán)境下,大部分的多媒體文件都依循著一種結構來存放信息,這種結構稱為“資源互換文件格式”( resources interchange file format , 簡稱RIFF)。例如聲音的WAV 文件

49、、視頻的AVI 文件等等均是由此結構衍生出來的。RIFF 可以看作是一種樹狀結構,其基本構成單位為chunk ,猶如樹狀結構中的節(jié)點,每個chunk 由“辨別碼”、“數據大小”與“數據”所組成。辨別碼由4 個ASCII 碼所構成,數據大小則標示出緊跟其后數據的長度(單位為Byte),而數據大小本身也用掉4 個Byte,所以事實上一個chunk 的長度為數據大小加8。一般而言,chunk 本身并不允許部再包含chunk,但有兩種例外,分別為以“RIFF”與“LIST”為辨別碼的chunk 。而針對這兩種chunk,RIFF 又從原先的“數據”中切出4個Byte。這4 個Byte 稱為“格式辨別碼

50、”,然而RIFF 又規(guī)定文件中僅能有一個以“RIFF”為辨別碼的chunk。只要是依循這一結構的文件, 我們均稱之為RIFF 文檔。這種結構提供了一種系統(tǒng)化的分類。如果和MS-DOS 文件系統(tǒng)作比較,“RIFF”chunk 就好比是一臺硬盤的根目錄,其格式辨別碼便是此硬盤的邏輯代碼(C:或D:),而“LIST”chunk 即為其下的子目錄,其他的chunk 則為一般的文件。至于在RIFF 文件的處理方面,微軟提供了相關的函數。視窗下的各種多媒體文件格式就如同在磁盤上規(guī)定僅能放怎樣的目錄,而在該目錄下僅能放何種數據。WAV 為waveform(波形)的縮寫。聲音文件的結構如表4-1 所示,“RI

51、FF”的格式辨別碼為“WAVE”。整個文件由兩個chunk 所組成:辨別碼“fmt ”(注意,最后一個是空白字符!)與“data”。在“fmt”的chunk 下包含了一個PCMWAVE-FORMAT 數據結構,其定義如下:typedef struct pcmwaveformat-tagWAVEFORMAT wf;WORD wBitsPerSample;PCMWAVEFORMAT;typedef struct waveformat-tag嵌入式系統(tǒng)設計與實例開發(fā)實驗指導書135WORD wFormat Tag ;WORD nChannels;DWORD nSamplesPerSec;DWORD

52、nAvgBytesperSec;WORD nBlockAlign;WAVEFORMAT;其意義分別為:wFormat Tag:記錄著此聲音的格式代號,例如WAVE- FORMAT- PCM,WAVE- FORAM- AD-PCM等等。nChannels:記錄聲音的通道數。nSamplesPerSec:記錄每秒取樣數。nAvgBytesPerSec:記錄每秒的數據量。nBlockAlign:記錄區(qū)塊的對齊單位。wBitsPerSample:記錄每個取樣所需的位數。“data”Chunk 包含著真正的聲音數據。Windows 目前僅提供WAVE- FORMAT- PCM 一種數據格式,所代表的意義

53、是脈沖編碼調制(pulse code modulation)。針對這種格式,Windows定義了在“data”的chunk 中數據的存放情形,圖4-1 中列出了四種不同通道數與取樣所需的位元數以與位元位置的安排。圖4-1 PCM 文件中位元安排方式第一排表示單聲道8 位元,第二排表示雙聲道8 位元,第三排表示單聲道16 位元,第四排表示雙聲道16 位元。8 位元代表音量大小由8 個位元所表示,16 位元則代表音量大小由16 個位元所表示。理論上8 位元可以表示0255,16 位元可表示065535,不過Windows規(guī)定16 位元其值的圍為-3216832167。此外尚有一點要注意的是,0 并

54、不一定代表無聲,而是由中間的數值來決定,也就是在8 位元時為128,16 位元時為0 才是無聲。所以,若程序設計時需放入無聲的數據,需特別注意聲音格式是16 或是8 位元,以放入適當的值。2IIS 音頻接口IIS 音頻接口總線共有四根線:串行數據輸入(IISDI)、串行數據輸出(IISDO)、左右嵌入式系統(tǒng)設計與實例開發(fā)實驗指導書136聲道選擇(IISLRCK)和串行位時鐘(IISCLK)。由主控設備提供IISLRCK 和IISCLK。1) IISCON 寄存器IISCON 寄存器的設置和位描述如表4-2 和表4-3 所示。表4-2 IISCON 寄存器的設置寄存器地址 R/W 描述復位值IISCON0x01D18000(Li/HW, Li/W, Bi/W)0x01D18002(Bi/HW)R/W IIS控制寄存器0x100表4-3 IISCON 寄存器的位描述IISCON 位描述初始化狀態(tài)左/右聲道指示(只讀)8 0 =左聲道 1 =右聲道1發(fā)送FIFO準備好標志(只讀)70=FIFO沒準備好(空) 1=FIFO 準備好(非空)0接收FIFO準備好標志

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論