韦东山嵌入式Linux应用开发完全手册GPIO和MMU测试代码的错误

2019-07-12 21:12发布

韦东山嵌入式Linux应用开发完全手册GPIO和MMU测试代码的错误

错误现象

参考韦东山嵌入式Linux应用开发完全手册,使用mini2440进行测试时,发现GPIO和MMU的测试例子工作异常,现实是led并不能实现流水灯,只是四个LED全亮。

出错的代码

#define GPBCON (*(volatile unsigned long *)0x56000010) #define GPBDAT (*(volatile unsigned long *)0x56000014) #define GPB5_out (1<<(5*2)) #define GPB6_out (1<<(6*2)) #define GPB7_out (1<<(7*2)) #define GPB8_out (1<<(8*2)) void wait(unsigned long dly) { for(; dly > 0; dly--); } int main(void) { unsigned long i = 0; GPBCON = GPB5_out|GPB6_out|GPB7_out|GPB8_out; // 将LED1-4对应的GPB5/6/7/8四个引脚设为输出 while(1){ wait(30000); GPBDAT = (~(i<<5)); // 根据i的值,点亮LED1-4 if(++i == 16) i = 0; } return 0; } 使用的Makefile CFLAGS := -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -ffreestanding leds.bin : crt0.S leds.c arm-linux-gcc $(CFLAGS) -c -o crt0.o crt0.S arm-linux-gcc $(CFLAGS) -c -o leds.o leds.c arm-linux-ld -Ttext 0x0000000 crt0.o leds.o -o leds_elf arm-linux-objcopy -O binary -S leds_elf leds.bin arm-linux-objdump -D -m arm leds_elf > leds.dis clean: rm -f leds.dis leds.bin leds_elf *.o

错误原因

经过对现象分析和不断修改参数测试,发现wait函数的for循环没有起作用,后查阅资料发现是因为Makefile中使用了-O2优化参数,而wait()函数的输入参数dly没有使用volatile关键字,导致编译过程中将for循环进行了优化。

修改方法

1 给for循环的变量声明加上volatile关键字
2 去掉Makefile中的-O2优化选项

另外注意

韦东山提供的测试源码中leds文件夹中的crt0.S中关闭看门狗的代码有问题,源代码是 ldr r0, =0x56000010应该改为 ldr r0, =0x53000000。