1. 程式人生 > >第1個裸板程式(S3C2440)

第1個裸板程式(S3C2440)

第一個程式只能是彙編,以前寫微控制器程式,用到 IAR、MDK等,一上來就寫main()函式,那是編譯器幫你封裝好了。

目標:點亮LED1

有兩種方法:(1)只寫一個彙編檔案makefile。 (2)寫一個彙編檔案作為啟動檔案,再寫個c檔案,和makefile

裸機開發步驟: 1. 檢視原理圖 2. 檢視資料手冊 3. 寫程式

1.檢視原理圖 在這裡插入圖片描述

在這裡插入圖片描述 由原理圖得知,LED1連線S3C2440的GPF4引腳。當GPF4設定為輸出模式,且輸出低電平時,LED1被點亮。

2.檢視資料手冊 在這裡插入圖片描述 需要配置GPFCON暫存器和GPFDAT暫存器。 注意,這些暫存器和R0–R12、SP、LR、PC、CPSR不同。 R0–R12、SP、LR、PC、CPSR屬於內部暫存器,CPU可以直接訪問。 類似於GPFCON等暫存器,CPU只能通過定址的方式訪問(這些暫存器和記憶體是統一編址的)。 所以,要使LED1點亮,1、要往地址為0x56000050的地方存放0x100,設定GPF4位輸出模式。2、往地址為0x56000054的地方存放0,設定GPF4輸出低電平。

3.寫程式

(1)只寫一個彙編檔案makefile

/*
 *檔名:led_on.S
 *功能:點亮LED
 */


.text
.global _start

_start:

	ldr r0, =0x56000050
	ldr r1, =0x100
	str r1, [r0]				/* 要往地址為0x56000050的地方存放0x100,設定GPF4位輸出模式 */

	ldr r0, =0x56000054
	ldr r1, =0
	str r1, [r0]					/* 往地址為0x56000054的地方存放0,設定GPF4輸出低電平 */


halt:			/* 死迴圈 */
	b halt

makefile檔案

all:
	arm-linux-gcc -c -o led_on.o led_on.S
	arm-linux-ld -Ttext 0 led_on.o -o led_on.elf
	arm-linux-objcopy -O binary -S led_on.elf led_on.bin
	arm-linux-objdump -D led_on.elf > led_on.dis
clean:
	rm *.bin *.o *.elf

分析: .text .global 是arm-gcc編譯器的關鍵詞。 .text部分是處理器開始執行程式碼的地方,指定了後續編譯出來的內容放在程式碼段【可執行】。 .global關鍵字用來讓一個符號對連結器可見,可以供其他連結物件模組使用;告訴編譯器後續跟的是一個全域性可見的名字【變數/函式名】 .global _start讓_start符號成為可見的識別符號,這樣連結器就知道跳轉到程式中的什麼地方並開始執行程式。

makefile檔案的作用就是把arm-linux-gcc的編譯、彙編、連結等命令組合起來,在linux系統中,不用挨個執行編譯、彙編、連結命令,只需輸入make即可。

(2)寫一個彙編檔案

作為啟動檔案,再寫個c檔案,和makefile

/*
 *檔名:start.S
 *功能:設定棧、跳轉到c檔案中的main()函式執行。
 */
 
.text
.global _start

_start:

	ldr sp, =4096			/* NAND啟動 */
	
	bl main					/* 跳轉到main()執行 */
	
halt:
	b halt						/* 死迴圈 */

c檔案

int main(void)
{
	unsigned int *pGPFCON = (unsigned int *)0x56000050;
	unsigned int *pGPFDAT = (unsigned int *)0x56000054;
	
	*pGPFCON = 0x400;		/* led 配置為輸出模式 */
	*pGPFDAT = 0;			/* led 設定為點亮狀態 */
	
	return 0;
}

makefile檔案

all:
	arm-linux-gcc -c -o led.o led.c
	arm-linux-gcc -c -o start.o start.S
	arm-linux-ld -Ttext 0 start.o led.o -o led.elf
	arm-linux-objcopy -O binary -S led.elf led.bin
	arm-linux-objdump -D led.elf > led.dis
clean:
	rm *.bin *.o *.elf *.dis

分析: start.S中設定堆疊、跳轉到main()函式執行。

  1. 為什麼設定堆疊? 答:因為C函式要用。
  2. 怎麼使用棧? 答:a.儲存區域性變數 b.儲存lr等暫存器
  3. 為什麼要設定棧地址為4096? 答:先從S3C2440的啟動方式說起 S3C2440啟動流程: Nor啟動: Nor Flash的基地址為0,片內RAM地址為0x4000 0000; CPU讀出Nor上第1個指令(前4位元組),執行; CPU繼續讀出其它指令執行。 Nand啟動: 片內4k RAM基地址為0,Nor Flash不可訪問; 2440硬體把Nand前4K內容複製到片內的RAM,然後CPU從0地址取出第1條指令執行。

一般把堆疊放在片內RAM中。 若設定為Nand啟動,片內RAM的基地址為0,把堆疊地址設定為片內4k RAM的最大地址4096,堆疊從4096開始往低地址方向儲存,即sp = sp - 4; 若設定為Nor啟動,片內RAM的基地址為0x4000 0000,則把堆疊地址設定為片內4k RAM的最大地址0x4000 0000+4096,堆疊開始往低地址方向儲存,即sp = sp - 4;

編譯,燒錄 (1)把方法1和方法2對應的檔案放在相應資料夾中(即led_on.S和makefile放一個資料夾;startr.S、led.c、makefile放一個資料夾) (2)開啟Ubuntu9.10和FileZilla (3)通過FileZilla,把兩個資料夾複製到Ubuntu9.10 (4)在Ubuntu9.10中,執行make命令來編譯生成.bin檔案 (5)再通過FileZilla,把編譯生成的.bin檔案複製到windows系統中 (6)開啟cmd,用oflash+eop把.bin檔案燒錄到Nand (7)設定Nand啟動,重啟開發板。 (8)觀察LED1