• 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语言的代码编译后的局部变量,参数等都依赖栈才能够工作。这也是和第一篇纯汇编代码有所区别的地方。

  • 相关阅读:
    Sencha Ext JS 4开发入门教程
    用C#编程从数据库中读取图片数据导进Excel文件的方法
    所选中的要素,赋值给一个定义好的变量pCurFea
    Extjs4.0.7 tree 结构读取json文件(在框架viewport中)
    为什么使用接口编程
    对featureclass中插入和删除feature的几种方法进行了比较
    C#3.0之LINQ数据库表的映射
    c# Linq to sql 基本查询例子
    用ArcEngine的工具条添加图层要素
    ArcGIS Engine开发基础之QI
  • 原文地址:https://www.cnblogs.com/wenix/p/3544802.html
Copyright © 2020-2023  润新知