這個範例主要希望透過 ARM組合語言初始化必要條件後,呼叫 C 語言中的 main 函式來執行控制 LED,這個範例主要內容為使用 ARM 組合語言呼叫 C 語言程式,對於 GPIO 控制內容,請參考【S3C2440 控制單顆 LED(JZ2440 筆記)】。
程式動作:
設定 WTCON Register 來關閉 Watchdog。
設定堆疊指標 SP ( Stack Pointer ):
程式中將堆疊指標設定在 0x00001000 (4096),其原因如下:
1. 當使用 NAND Flash 啟動時,會由S3C2440 CPU Boot ROM 開始運行,Boot Rom 會將 NAND Flash 前 4KB 資料 Copy 到 S3C2440 內部 SRAM,並從 SRAM 0x00000000 位址開始執行程式,由於程式是被 COPY 到僅有 4KB 的SRAM上運行,所以當使用 NAND Flash 啟動時,設定SP 不能指定超出 4KB位址處。
2. 當使用 Nor Flash 啟動時,SRAM Memory Map起始位址則為 0x40000000,當要設定堆疊指標(SP)時,可將位址設在 0x40001000 處。
3. Arm 堆疊特性為高位址向低位址遞減堆疊,所以將堆疊指標設在 SRAM 4KB 處,不用擔心實際使用推疊會超出 SRAM 位址 。
以下程式使用 Nor Flash 開機啟動,所以將 SP 設在 0x40001000。
程式:crt0.S
@************************************************************************ @ File:crt0.S @************************************************************************ .text .global _start _start: ldr r0, =0x53000000 @ WTCON Register mov r1, #0x0 str r1, [r0] @ 設定 0 關閉 WATCHDOG
ldr sp, =0x40001000 @ 設置堆疊,使用 NorFLASH 開機, @ 所以將 SP 初始位址設在 0x40001000 bl main @ Call C 語言 Main 函式 halt_loop: @ 無窮迴圈 b halt_loop |
程式:led_on_c.c
#define GPFCON (*(volatile unsigned long *)0x56000050) #define GPFDAT (*(volatile unsigned long *)0x56000054) int main() { GPFCON = 0x00000400; //設定 GPF5 為 OUTPUT GPFDAT = 0x00000000; //設定 GPF5 輸出 0,低電位 LED 亮 return 0; } |
Makefile:
led_on_c.bin : crt0.S led_on_c.c arm-linux-gcc -g -c -o crt0.o crt0.S arm-linux-gcc -g -c -o led_on_c.o led_on_c.c arm-linux-ld -Ttext 0x0000000 -g crt0.o led_on_c.o -o led_on_c_elf arm-linux-objcopy -O binary -S led_on_c_elf led_on_c.bin arm-linux-objdump -D -m arm led_on_c_elf > led_on_c.dis clean: rm -f led_on_c.dis led_on_c.bin led_on_c_elf *.o |
反組譯:
Arm-linux-objdump 指令可將 elf 格式程式,反組譯為 Arm 組合語言。
arm-linux-objdump -D -m arm led_on_c_elf > led_on_c.dis |
反組譯後程式:
led_on_c_elf: file format elf32-littlearm Disassembly of section .text: 00000000 <_start>: 0: e3a00453 mov r0, #1392508928 ; 0x53000000 4: e3a01000 mov r1, #0 ; 0x0 8: e5801000 str r1, [r0] c: e59fd004 ldr sp, [pc, #4] ; 18 <.text+0x18> 設定 SP 10: eb000001 bl 1c <main> ;跳到 main 函式 00000014 <halt_loop>: 14: eafffffe b 14 <halt_loop> 18: 40001000 andmi r1, r0, r0 0000001c <main>: 1c: e1a0c00d mov ip, sp 20: e92dd800 stmdb sp!, {fp, ip, lr, pc} ;將fp ip lr pc 丟到堆疊 24: e24cb004 sub fp, ip, #4 ; 0x4 28: e3a03456 mov r3, #1442840576 ; 0x56000000 2c: e2833050 add r3, r3, #80 ; 0x50 30: e3a02b01 mov r2, #1024 ; 0x400 34: e5832000 str r2, [r3] 38: e3a03456 mov r3, #1442840576 ; 0x56000000 3c: e2833054 add r3, r3, #84 ; 0x54 40: e3a02000 mov r2, #0 ; 0x0 44: e5832000 str r2, [r3] 48: e3a03000 mov r3, #0 ; 0x0 4c: e1a00003 mov r0, r3 50: e89da800 ldmia sp, {fp, sp, pc} ;將fp ip pc 從堆疊取出 Disassembly of section .comment: |
參考資料:
JZ2440 開發板提供之相關資料
留言列表