kildare 发表于 2008-12-4 23:01:32

求助,s3c2440初始化内存控制器时程序跑飞【恢复】

我的程序在执行

void  TargetBusInit(void)

{   

#ifdef        __Release        

    int  i = 0;

    volatile uint32  *cp1;



        // 总线设置,初始化SDRAM控制器

        cp1 = (void *)BWSCON_ADDR;

        for(i=0; i<13; i++)

        {

                *cp1++ = __BUS_INIT;                

        }

#endif    

}

代码中__BUS_INIT[]是一个数组,存储的是BWSCON地址开始连续十三个寄存器的值。

这段代码时会把0x30000000开始的地址全部置为0xFFFFFFFF,而这个地址是程序各个异常堆栈的所在,直接导致存在栈中的LR值被改为0xFFFFFFFF。

各堆栈对应的地址是:

StackUsr           dcd      0x300001e0  ...0

StackSvc           dcd      0x30000220   ..0

StackIrq           dcd      0x30000320   ..0

StackFiq           dcd      0x30000360  ~..0

StackAbt           dcd      0x30000360  ~..0

StackUnd           dcd      0x30000360  ~..0





奇怪的是,我是在程序的下面两个函数中加入内容后才发生上述情况

void Beep_Start(void){        

        rGPBCON &= ~3;                //set GPB0 as tout0, pwm output

        rGPBCON |= 2;



        rTCFG0 &= ~0xff;

        rTCFG0 |= 15;                        //prescaler = 15+1

        rTCFG1 &= ~0xf;

        rTCFG1 |= 2;                        //mux = 1/8

        rTCNTB0 = (PCLK>>7)/20;

        rTCMPB0 = rTCNTB0>>2;        

        rTCON &= ~0x1f;

        rTCON |= 0xb;                //disable deadzone, auto-reload, inv-off, update TCNTB0&TCMPB0, start timer 0

        rTCON &= ~2;                //clear manual update bit*/

        

}



void Beep_Stop( void ){

        rGPBCON &= ~3;                //set GPB0 as tout0, pwm output

        rGPBCON |= 1;

        rGPBDAT &= ~1;

}



如果上面函数体中内容都注释掉的话则能正常运行,请教各位大侠这有可能是什么原因?



我用的开发板是s3c2440,仿真器是Jlink v6,调试软件是AXD。

本贴被 kildare 编辑过,最后修改时间:2008-12-04,23:08:38.

kildare 发表于 2008-12-5 23:19:40

问一个新问题:

为什么我的程序只能下载4K?

从0x1000处开始就全部变成andeq r0,r0,r0了?

kildare 发表于 2008-12-5 11:50:46

做了如下测试:

1、把Beep_Start函数体内的函数放置到一个叫LED_init()的函数内且LED_init()函数被main()调用,程序出现同样的症状

2、Beep_Start函数直接在main()调用,程序出现同样症状



3、把Beep_Stop函数体内的函数旋转到LED_init()且LED_init()函数被main()调用,程序能正确运转

4、Beep_Stop函数直接在main()调用,程序出现同样症状

从3、4两点看,同样的函数体,放置的位置不一样程序运行结果就不一样

kildare 发表于 2008-12-5 11:27:34

谢谢回复。

不过你说的没办法查,因为程序并没执行到这一步,现在程序流程是这样的:

1、调用TargetBusInit()初始化

2、B       __main跳转到C语言入口

3、在main()函数内调用Beep_Start、Beep_Stop等函数。

然后出现是这样的:

在第一步执行过程中0x3000 0000开始的地址全被置为FF,继续执行TargetBusInit()子程序能正常返回

然后执行B __main语句,在这条语句单步调试过程中有一次出入栈操作:stmfd和ldmfd,其中stmfd中R13的值是正确的

但语句执行后R13对应地址的值并没有被改变,还是0xFFFFFFFF,这样,但执行ldmfd后程序就跳转到0xFFFFFFFF处执行了

也就是并没有跳转到main()中去运行Beep_Start等函数,但奇怪的是,如果在main()中把函数的调用注释了,则程序又能正常跳转了

huatong 发表于 2008-12-5 10:39:38

有没有查过 ~3,~0xFF等等最后得出的值是什么

kildare 发表于 2008-12-5 15:09:54

在网上找到一篇“阿南的ARM入门调试笔记”,其中有这么一段:

      3>在软件仿真的情况下,执行“B __main”指令,能使程序跳到C 文件的main 函数,但用硬件仿真 

时,还没执行到main 函数时就进入了异常中断。 

      原因是执行“B __main”指令后,程序先跳到__main 库函数的入口,再进行一些初始化操作,最后再 

跳入用户的main 函数。但在初始化过程中,由于堆栈或其它原因造成程序出错。有两种方法可以解决这个 

问题。第一:将“B __main”指令直接改成“B main”,使程序不进行初始化而直接跳入用户的main()函数。 

第二:合理初始化堆栈。由于考虑到刚接触ARM 和将问题简单化,我选择了第一种方法。 



我按上述方法把 B __main改成B main,程序能正常进入main()函数,但新问题就是程序没有按预期的执行,

例如不能和串口通信了(如果程序按B __main方法进入main()不出错的话是能行的)。



其中还有一段:

      3>  在起动代码中,可以调用__main()库函数进行存储器的初始化,也可以自己编写更有效的代码进 

行初始化,在初始化后就可以使用“B __main”指令直接跳转到C 的main()函数。 



想请问一下,调用__main()库函数时启动代码需要初始化一些什么东西?





顺便共享一下阿南的ARM入门调试笔记,pdf格式

点击此处下载 ourdev_530036.rar(文件大小:193K) (原文件名:阿南的ARM入门调试笔记.rar) 

snowy 发表于 2011-1-4 17:14:48

SDRAM初始化了没?

snowy 发表于 2011-1-4 17:20:34

目标文件的加载是在你初始之前的,所以你如果在程序中初始化内存控制器,初始化之后需要写个小程序将代码重新复制到SDRAM中。如果只是调试的话,建议将SDRAM初始化程序写到调试器的初始化脚本中。

snowy 发表于 2011-1-4 17:27:58

汗,没看时间……
页: [1]
查看完整版本: 求助,s3c2440初始化内存控制器时程序跑飞【恢复】