|
本帖最后由 kingvenlee 于 2013-4-1 17:27 编辑
看到第一课硬件初始化部分的视频,韦老师说硬件初始化部分只能放在nand中运行。我在tq2440开发板上试验了一下,直接拷贝文件key_led.bin到内存中,不能运行。具体如下:
程序拷贝到nand中,可以运行,但是把链接地址从0x0改成0x30000000再拷贝到nand不能运行了。
把链接地址改成0x30000000再用uboot下的tftp工具烧写到内存"tftp 0x30000000 key_led.bin"使用"go 30000000"还是不能运行。
我使用了其他的程序leds和led_on_c程序都可以正常运行。
设置链接地址为0x0,把leds.bin拷贝到内存0x30000000,程序可以运行。
设置链接地址为0x30000000,把leds.bin拷贝到内存0x30000000,程序还是可以运行。
设置链接地址为0x0,把led_on_c.bin拷贝到内存0x30000000,程序可以运行。
设置链接地址为0x30000000,把led_on_c.bin拷贝到内存0x30000000,程序还是可以运行。
问题是key_led.bin直接下载到内存为什么不能运行呢?链接地址改了也不行啊 。上面的代码用的是韦东山视频中TQ2440源码中硬件初始化中的程序。
代码如下:key_led.c
#define GPFCON (*(volatile unsigned long *)0x56000050)
#define GPFDAT (*(volatile unsigned long *)0x56000054)
#define GPBCON (*(volatile unsigned long *)0x56000010)
#define GPBDAT (*(volatile unsigned long *)0x56000014)
/*
* LED1,LED2,LED4对应GPB5、GPB6、GPB7、GPB8
*/
#define GPB5_out (1<<(5*2))
#define GPB6_out (1<<(6*2))
#define GPB7_out (1<<(7*2))
#define GPB8_out (1<<(8*2))
#define GPB5_msk (3<<(5*2))
#define GPB6_msk (3<<(6*2))
#define GPB7_msk (3<<(7*2))
#define GPB8_msk (3<<(8*2))
/*
* K1,K2,K3,K4对应GPF1、GPF4、GPF2、GPF0
*/
#define GPF0_in (0<<(0*2))
#define GPF1_in (0<<(1*2))
#define GPF2_in (0<<(2*2))
#define GPF4_in (0<<(4*2))
#define GPF0_msk (3<<(0*2))
#define GPF1_msk (3<<(1*2))
#define GPF2_msk (3<<(2*2))
#define GPF4_msk (3<<(4*2))
int main()
{
unsigned long rGPFDAT;
// LED1,LED2,LED3,LED4对应的4根引脚设为输出
GPBCON &= ~(GPB5_msk | GPB6_msk | GPB7_msk | GPB8_msk); //清零GPBCON
GPBCON |= GPB5_out | GPB6_out | GPB7_out | GPB8_out;
// K1,K2,K3,K4对应的4根引脚设为输入
GPFCON &= ~(GPF0_msk | GPF1_msk | GPF2_msk | GPF4_msk); //清零GPFCON
GPFCON |= GPF0_in | GPF1_in | GPF2_in | GPF4_in;
while(1)
{
//若Kn为0(表示按下),则令LEDn为0(表示点亮)
rGPFDAT = GPFDAT; // 读取GPF管脚电平状态
if( (rGPFDAT&(1<< 0)) == 0 )
{
GPBDAT = GPBDAT & ~(1<<8); //亮LED
}
else if( (rGPFDAT&(1<< 2)) == 0 )
{
GPBDAT = GPBDAT & ~(1<<7); //亮LED
}
else if( (rGPFDAT&(1<<4)) == 0 )
{
GPBDAT = GPBDAT & ~(1<<6); //亮LED
}
else if( (rGPFDAT&(1<< 1)) == 0 )
{
GPBDAT = GPBDAT & ~(1<<5); //亮LED
}
else
{
GPBDAT = GPBDAT & ~0x1e0|0x1e0; //LED[8:5] => 1;
}
}
return 0;
}
crt0.S:
@******************************************************************************
@ File:crt0.S
@ 功能:通过它转入C程序
@******************************************************************************
.text
.global _start
_start:
ldr r0, =0x53000000 @ WATCHDOG寄存器地址
mov r1, #0x0
str r1, [r0] @ 写入0,禁止WATCHDOG,否则CPU会不断重启
ldr sp, =1024*4 @ 设置堆栈,注意:不能大于4k, 因为现在可用的内存只有4K
@ nand flash中的代码在复位后会移到内部ram中,此ram只有4K
bl main @ 调用C程序中的main函数
halt_loop:
b halt_loop
Makefile:
key_led.bin : crt0.S key_led.c
arm-linux-gcc -g -c -o crt0.o crt0.S
arm-linux-gcc -g -c -o key_led.o key_led.c
arm-linux-ld -Ttext 0x0000000 -g crt0.o key_led.o -o key_led_elf
arm-linux-objcopy -O binary -S key_led_elf key_led.bin
arm-linux-objdump -D -m arm key_led_elf > key_led.dis
clean:
rm -f key_led.dis key_led.bin key_led_elf *.o |
|