首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

ARM开发调试笔记心得(转)(2)

ARM开发调试笔记心得(转)(2)

四.出现的问题与解决方法

    当完成上述操作后,先用软件仿真,很快达到了目的,但将程序通过仿真器在目标板运行时出现了下述问题。

    1. 当执行单步运行时,PC一直停留在0x0处,而且Debug Log窗口中显示“RDI Warning 00148: Can't set point”。原因是仿真器在ROM中设置的断点数是有限的,且单步运行时内部还要占用断点。可以使用“Option->Config Processor”打开“Processor Properties-ARM7TDMI”窗口,且按照下图设置以关断相应的断点。

'700')this.width='700';if(this.height>'700')this.height='700';">

         2. 装载的代码与实践程序不一样
    原因是由于程序没有装载到AT91SAM7S64的FLASH ROM里,在调试器中显示的是FLASH ROM中原先就有的程序。因为在连接器的选项设置中,将RO Base和Image entry point指向了0地址,而在AT91SAM7S64的这段空间为FLASH ROM区,而仿真器不能直接将代码下载到FLASH ROM里。用仿真器只能将代码下载到AT91SAM7S64的内部SRAM里进行调试,必须将ARM Linker->Output->Simple image->RO Base和Image entry point的0,改成SRAM的地址0x002000000。

     3. 在软件仿真的情况下,执行“B __main”指令,能使程序跳到C文件的main函数,但用硬件仿真时,还没执行到main函数时就进入了异常中断。原因是执行“B __main”指令后,程序先跳到__main库函数的入口,再进行一些初始化操作,最后再跳入用户的main函数。但在初始化过程中,由于堆栈或其它原因造成程序出错。有两种方法可以解决这个问题。第一:将“B __main”指令直接改成“B main”,使程序不进行初始化而直接跳入用户的main()函数。第二:合理初始化堆栈。由于考虑到刚接触ARM和将问题简单化,我选择了第一种方法。

          五.总结

     1. 在用仿真器时,必须将程序下载到AT91SAM7S64的内部SRAM中,而不是Flash ROM。

     2. 从汇编代码进入C文件函数时,可以直接使用C语言中的标号(可参考书中混合编程部分),如执行“B main”则直接跳到C语言的main()函数入口。

     3. 在起动代码中,可以调用__main()库函数进行存储器的初始化,也可以自己编写更有效的代码进行初始化,在初始化后就可以使用“B __main”指令直接跳转到C的main()函数。

点亮我的LED――I/O输出实验
一.背景
    当完成上述实验后,我就可以像使用51单片机那样,在C文件的main()函数中通过设置相应的寄存器来达到对相应外设(如I/O的输入、输出等)的控制目的。
二.实验目的
    通过控制PIO的相关寄存器,使特定的I/O口输出高电平和低电平,来点亮LED
三.实验程序和参数设置
    1> 连接器选项设置
    RO Base = 0x00200000;
        RW Base = 0x00202000;
        Image entry point=0x00200000;
        2> 启动代码
        启动代码与第一个实验中修改后的相同,即将“__main()”改成main()。
    3> C语言的代码
               #include "AT91SAM7S64.h" //特殊功能寄存器头文件。类似与51单片机中reg51.h
               #include "Board.h" //定义目标板的头文件
                int main(void)
               {
                    *AT91C_PIOA_PER = LED_MASK;//使能4个LED对应管脚的I/O口功能
                    *AT91C_PIOA_OER = LED_MASK;//使能4个LED管脚的输出功能
                       while (1)
                       {
                              //可用单步运行来查看输出结果
                             *AT91C_PIOA_SODR = LED1;//将LED1对应的管脚输出高电平
                             *AT91C_PIOA_CODR = LED1;//将LED1对应的管脚输出低电平
                        }
               }
继承事业,薪火相传
返回列表