ARM嵌入式學習--OK6410裸板程序--2.GPIO控制LED跑馬燈(從ARM彙編跳轉到C語言)

第一個部分中,徹底使用ARM彙編來控制LED,徹底使用匯編來編寫大的系統存在理論可行性(固然現實中也有徹底使用匯編實現的操做系統),可是彙編理解起來太困難,編寫起來很複雜,太瑣碎,因此確定會想要使用理解性更好的C語言來編寫大部分代碼,那麼哪些代碼用匯編編寫?哪些用C語言編寫呢?linux

從工程實踐中能夠得出一些結論:函數

1.跟具體硬件緊密相關的功能,對這部分功能,無需保持可移植性。優化

2.對C語言編譯後的代碼沒有信心,或者必須進行特別優化時,必須依靠人工優化代碼時。spa

3.相對的是,若是須要保持可移植性,那麼必須把平臺無關的功能經過底層的部分彙編代碼進行隔絕,其餘代碼經過C語言來編寫。操作系統

功能原理和電路圖見第一篇。code

代碼:blog

彙編代碼完成硬件初始化,包括內存基地址和大小設定,WatchDog關閉,設置棧,而後跳轉到C代碼中。內存

start.S開發

 1 // 啓動代碼
 2 .global _start
 3 
 4 _start:
 5 
 6         // 把外設的基地址告訴CPU
 7     ldr r0, =0x70000000                                         //對於6410來講,內存(0x00000000~0x60000000),外設(0x70000000-0x7fffffff)
 8     orr r0, r0, #0x13                                           //外設大小:256M
 9     mcr p15,0,r0,c15,c2,4                               //把r0的值(包括了外設基地址+外設大小)寫給cpu
10          
11         // 關看門狗
12         ldr r0, =0x7E004000
13         mov r1, #0
14         str r1, [r0] 
15                  
16         // 設置棧,0x0c002000內存地址映射到SoC內部的SRAM中,速度較快
17         ldr sp, =0x0c002000
18 
19         // 調用C函數點燈
20         bl main
21 
22 halt:
23         b halt

C語言用來實現具體的流水燈功能:編譯

main.c

 1 // 功能:c實現流水燈
 2 
 3 // 延時
 4 void delay()
 5 {
 6         volatile int i = 0x100000;
 7         while (i--);
 8 }
 9 
10 int main()
11 {
12         int i = 0x01;
13 
14         // 配置引腳
15         volatile unsigned long *gpkcon0 = (volatile unsigned long *)0x7F008820;
16         volatile unsigned long *gpkdat = (volatile unsigned long *)0x7F008824;
17 
18         *gpkcon0 = 0x00001111;
19 
20         // 跑馬燈
21         while (1)
22         {
23                 *gpkdat = i;
24                 i = i << 1;
25                 if (i == 0x100)
26                         i = 0x01;
27                 delay();
28         }
29 
30         return 0;
31 }
 1 led.bin: start.o main.o
 2         arm-linux-ld -Ttext 0x50000000 -o led.elf $^
 3         arm-linux-objcopy -O binary led.elf led.bin
 4         arm-linux-objdump -D led.elf > led_elf.dis
 5 %.o : %.S
 6         arm-linux-gcc  -nostdlib -o $@ $< -c
 7 
 8 %.o : %.c
 9         arm-linux-gcc  -nostdlib -o $@ $< -c 
10 
11 clean:
12         rm *.o *.elf *.bin *.dis  -rf

編譯後下載到開發板中,運行,具體運行方法見第一篇。運行效果能夠看到四個LED燈依次熄滅,而後點亮。

總結:

1.彙編代碼完成必要的硬件初始化功能,從C語言也會被編譯爲彙編來講,C語言理論上也能完成這項工做,可是卻沒有這樣作的必要,由於這部分代碼無需可移植性,而且彙編比C代碼更可控,效率更高。

2.在上層功能上來講,C代碼可讀性優秀,比彙編代碼可理解性要好,並且可移植性也更好,若是要把本文代碼移植到另一個SoC上去,只需修改彙編部分,C基本無需修改。

3.彙編代碼中設置了棧,這部分是爲C代碼的運行準備好條件,由於C語言的代碼編譯後的局部變量,參數等都依賴棧纔可以工做。這也是和第一篇純彙編代碼有所區別的地方。

相關文章
相關標籤/搜索