天嵌 ARM开发社区

 找回密码
 注册
查看: 1847|回复: 2

一个程序能在nand中运行,但不能直接下载到内存运行。

[复制链接]
kingvenlee 发表于 2013-3-11 10:11:11 | 显示全部楼层 |阅读模式
本帖最后由 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
 楼主| kingvenlee 发表于 2013-3-11 11:58:09 | 显示全部楼层
现在我自己搞清楚了,原来还要修改栈指针sp到内存地址才行。
亚瑟王 发表于 2013-3-11 14:43:30 | 显示全部楼层
kingvenlee 发表于 2013-3-11 11:58
现在我自己搞清楚了,原来还要修改栈指针sp到内存地址才行。

亲,问题解决了请把帖子类型修改为“已解决”(请参考:http://www.armbbs.net/forum.php?mod=viewthread&tid=15200
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

i.MX8系列ARM cortex A53 M4 工控板上一条 /1 下一条

Archiver|手机版|小黑屋|天嵌 嵌入式开发社区 ( 粤ICP备11094220号 )

GMT+8, 2024-6-1 14:46 , Processed in 1.031250 second(s), 19 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表