韦东山嵌入式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;
while(1){
wait(30000);
GPBDAT = (~(i<<5));
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。