Chinaunix首页 | 论坛 | 博客
  • 博客访问: 14725
  • 博文数量: 3
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 40
  • 用 户 组: 普通用户
  • 注册时间: 2011-08-09 11:42
文章分类

全部博文(3)

文章存档

2023年(1)

2016年(1)

2015年(1)

我的朋友

分类: LINUX

2016-12-18 19:45:16

1. 修改leds.c

使用的是FL2440,这个开发板gpio对应的LED与mini2440有点差异,为了跑马灯,只好封装了一些宏。
有几点注意:
    1. 采用虚拟地址访问寄存器,将0x56000000->0xA0000000
    2. wait函数使用内联,目的是将main的地址编译后指向0xb0004000
    3. Makefile中需要配合-O选项与函数的内联申明才能真正实现内联。
    4. 2440没有开启PLL,默认时钟为12MHz, wait函数的软延迟并不精确。

点击(此处)折叠或打开

  1. /*
  2.  * leds.c: 循环点亮4个LED
  3.  * 属于第二部分程序,此时MMU已开启,使用虚拟地址
  4.  */

  5. #define    GPBCON        (*(volatile unsigned long *)0xA0000010)
  6. #define    GPBDAT        (*(volatile unsigned long *)0xA0000014)

  7. //#define    GPBCON        (*(volatile unsigned long *)0x56000010)
  8. //#define    GPBDAT        (*(volatile unsigned long *)0x56000014)

  9. #define    GPB5_out    (1<<(5*2))
  10. #define    GPB6_out    (1<<(6*2))
  11. #define    GPB8_out    (1<<(8*2))
  12. #define    GPB10_out    (1<<(10*2))

  13. #define LED0        5
  14. #define LED1        6
  15. #define LED2        8
  16. #define LED3        10

  17. #define __LED_OUT(led)     do { GPBCON |= (1 << ((led)*2)); } while (0)
  18. #define __LED_ON(led)     do { GPBDAT &= ~(1 << (led)); } while (0)
  19. #define __LED_OFF(led)     do { GPBDAT |= (1 << (led)); } while (0)
  20. #define __LED_IS_OFF(led) (GPBDAT & (1 << (led)))


  21. /*
  22.  * wait函数加上“static inline”是有原因的,
  23.  * 这样可以使得编译leds.c时,wait嵌入main中,编译结果中只有main一个函数。
  24.  * 于是在连接时,main函数的地址就是由连接文件指定的运行时装载地址。
  25.  * 而连接文件mmu.lds中,指定了leds.o的运行时装载地址为0xB4004000,
  26.  * 这样,head.S中的“ldr pc, =0xB4004000”就是跳去执行main函数。
  27.  */

  28. static inline void wait(unsigned long dly)
  29. {
  30.     for(; dly > 0; dly--);
  31. }

  32. int main(void)
  33. {
  34.     unsigned cnt = 0, i, led[] = {LED0, LED1, LED2, LED3};

  35.     for (i = 0; i < 4; ++i) {
  36.         __LED_OUT(led[i]);
  37.         __LED_OFF(led[i]);
  38.     }

  39.     while (1) {
  40.         wait(100000);
  41.         if (++cnt == 16)
  42.             cnt = 0;
  43.         for (i = 0; i < 4; ++i) {
  44.             if (cnt & (1 << i))
  45.                 __LED_ON(led[i]);
  46.             else
  47.                 __LED_OFF(led[i]);
  48.         }
  49.     }

  50.     return 0;
  51. }
2. 修改Makefile

点击(此处)折叠或打开

  1. objs := head.o init.o leds.o

  2. mmu.bin : $(objs)
  3.     arm-linux-ld -Tmmu.lds -o mmu_elf $^
  4.     arm-linux-objcopy -O binary -S mmu_elf $@
  5.     arm-linux-objdump -D -m arm mmu_elf > mmu.dis
  6.     
  7. %.o:%.c
  8.     arm-linux-gcc -Wall -O -c -o $@ $<

  9. %.o:%.S
  10.     arm-linux-gcc -Wall -O -c -o $@ $<

  11. clean:
  12.     rm -f mmu.bin mmu_elf mmu.dis *.o

示例代码中使用-O2的选项,优化过头了,导致跑马灯跑不起来。另外wait函数的软延迟也不精确。后续学到时钟和中断的时候,可以改成硬延迟。


阅读(1714) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~