實驗程序可以從四個方面設計:一是啟動程序的設計,主要是對ARM工作模式的配置和中斷服務程序的設計;二是初始化程序,包括S5PV210中斷控制器的初始化、GPIO引腳的配置;三是主程序設計;最后編寫Makefile,編譯生成目標文件。下面就從這四方面編寫測試代碼以及代碼的詳解。 1.啟動程序start.S 前面已介紹過,S5PV210本身的固化代碼(iROM)在上電后配置好IRQ中斷的棧,以及系統模式所使用的棧,所以在啟動代碼中可以不用設置這些棧(如果重新配置也可以),所以實驗的啟動程序比較簡單,主要是當中斷發生時先保存現場,跳到中斷服務程序執行中斷處理,處理結束再恢復現場。具體代碼示例如下: 01 .text 02 .global _start/*聲明一個全局的標號*/ 03 .global IRQ_handle 04_start: 06mrs r0,cpsr 07bic r0,r0,#0x00000080/*使能IRQ中斷bit[7]=0 */ 08msr cpsr,r0 09bl main 10 halt_loop: 11bhalt_loop/*死循環,不讓程序跑飛*/ 12 13 IRQ_handle: 14sub lr, lr, #4/*計算返回地址*/ 15stmdb sp!, {r0-r12, lr} /*保存用到的寄存器*/ 16bl irq_handler/*跳到中斷服務函數*/ 17ldmia sp!, {r0-r12, pc}^/*中斷返回, ^表示將spsr的值復制到cpsr */ 2.初始化階段 初始化階段重點講下外部中斷控制寄存器的配置方法,以及中斷向量控制寄存器的設置,關于LED相關的引腳配置不作重復介紹。 …… 08 #define GPH0CON*((volatile unsigned int *)0xE0200C00) 09 #define GPH0DAT*((volatile unsigned int *)0xE0200C04) 10 #define EXT_INT_0_CON*((volatile unsigned int *)0xE0200E00) 11 #define EXT_INT_0_MASK*((volatile unsigned int *)0xE0200F00) 12 13 #define VIC0IRQSTATUS*((volatile unsigned int *)0xF2000000) 14 #define VIC0INTSELECT*((volatile unsigned int *)0xF200000C) 15 #define VIC0INTENABLE*((volatile unsigned int *)0xF2000010) 16 #define VIC0VECTADDR0*((volatile unsigned int *)0xF2000100) 17 #define VIC0VECTADDR1*((volatile unsigned int *)0xF2000104) 18 #define VIC0ADDRESS*((volatile unsigned int *)0xF2000F00) 19 20 extern void IRQ_handle(void); …… 38 //配置中斷引腳 39 void init_key(void) 40 { 41//配置GPIO引腳為中斷功能 42GPH0CON &= ~(0xFF int.dis 07 08 %.o : %.c 09arm-linux-gcc -c -O2 $< -o $@ 10 11 %.o : %.S 12arm-linux-gcc -c -O2 $< -o $@ 13 14 clean: 15rm -f *.o *.elf *.bin *.dis 將以上編寫好的源代碼上傳到宿主機上編譯生成可執行的目標文件int.bin,然后燒寫到開發板上電測試。 實驗最終結果是:當按下“KEY1”,LED1燈會被點亮或熄滅;當按下“KEY2”,LED2燈會被點亮或熄滅。 |