ARM嵌入式学习--OK6410裸板程序--2.GPIO控制LED跑马灯(从ARM汇编跳转到C语言)

第一个部分中,完全使用ARM汇编来控制LED,完全使用汇编来编写大的系统存在理论可行性(当然现实中也有完全使用汇编实现的操作系统),但是汇编理解起来太困难,编写起来很复杂,太琐碎,所以肯定会想要使用理解性更好的C语言来编写大部分代码,那么哪些代码用汇编编写?哪些用C语言编写呢?

从工程实践中可以得出一些结论:

1.跟具体硬件紧密相关的功能,对这部分功能,无需保持可移植性。

2.对C语言编译后的代码没有信心,或者必须进行特别优化时,必须依靠人工优化代码时。

3.相对的是,如果需要保持可移植性,那么必须把平台无关的功能通过底层的部分汇编代码进行隔绝,其他代码通过C语言来编写。

功能原理和电路图见第一篇。

代码:

汇编代码完成硬件初始化,包括内存基地址和大小设定,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语言的代码编译后的局部变量,参数等都依赖栈才能够工作。这也是和第一篇纯汇编代码有所区别的地方。

转载于:https://www.cnblogs.com/wenix/p/3544802.html

你可能感兴趣的:(ARM嵌入式学习--OK6410裸板程序--2.GPIO控制LED跑马灯(从ARM汇编跳转到C语言))