ARM入门笔记(2)

发布时间:2010-8-26 17:23    发布者:绝对好文
关键词: ARM入门笔记
第二章 我的第一个实验 ――将程序执行到C文件的main函数

二.实验目的

运用ADS编写一个小程序,使程序能够从起始的汇编代码运行到C程序的main()函数(这也可称作非常简单的起动代码),并通过仿真器连接目标板,最终能够在AT91SAM7S64里正确运行。

三.实验程序和参数设置

1>连接器的选项设置

选项设置如图2-1所示。因为在AT91SAM7S64中FLASH存储器的地址是以0x0开始,而SRAM的地址是以0x00200000开始,所以我将下图中的RO Base和RW Base分别设置成了0x0和0x00200000。其它设置请参考有关书籍。
            
1.jpg
图2-1. 选项设置图

2>启动代码

ARM应用系统中,芯片复位后,在进入C语言的main()函数前,都要执行一段启动代码。该代码一般都是用汇编语言编写,用来完成系统运行环境和应用程序的初始化,详情请参考有关书籍。由于本实验的目的很简单,就是想让程序复位后,进入main()函数,所以有些初始化代码尽量精简,留下了下述代码。另外,__main是C语言的内部库函数,可以在进入用户main()之前完成内部RAM的初始化工作,类似KeilC51中的startup.a51。当执行完__main这段代码后,再跳转到main()函数。

AREA init,CODE,READONLY
CODE32
Mode_USR  EQU  0x10 ;CPSR中各种处理器模式对应的控制位
I_Bit   EQU  0x80 ;CPSR中的中断禁止位
F_Bit   EQU  0x40
USR_Stack  EQU  0x00203000 ;定义RAM的最高地址,无重映射
ENTRY
                B           InitReset        ; 0x00 Reset handler
undefvec         B           undefvec        ; 0x04 Undefined Instruction
swivec           B           swivec          ; 0x08 Software Interrupt
pabtvec          B           pabtvec          ; 0x0C Prefetch Abort
dabtvec          B           dabtvec          ; 0x10 Data Abort
rsvdvec          B           rsvdvec          ; 0x14 reserved
irqvec           B   irqvec   ; 0x18 IRQ
fiqvec      B   fiqvec        ; 0x1c FIQ
InitReset
MSR CPSR_c,#Mode_USR | I_Bit | F_Bit ;改成用户模式且禁止IRQ和FIQ中断
LDR SP,=USR_Stack
IMPORT  __main                  
b         __main  ;跳转到__main执行,它位于C运行时库中                                
END
3>C语言主函数
在C语言主函数中做了一个死循环,如下述所示。
int main(void)
{
  while (1);
}

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

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

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

2.jpg
图2-2

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()函数。
本文地址:https://www.eechina.com/thread-23766-1-1.html     【打印本页】

本站部分文章为转载或网友发布,目的在于传递和分享信息,并不代表本网赞同其观点和对其真实性负责;文章版权归原作者及原出处所有,如涉及作品内容、版权和其它问题,我们将根据著作权人的要求,第一时间更正或删除。
长话短说 发表于 2010-9-4 11:25:56
谢了
您需要登录后才可以发表评论 登录 | 立即注册

厂商推荐

关于我们  -  服务条款  -  使用指南  -  站点地图  -  友情链接  -  联系我们
电子工程网 © 版权所有   京ICP备16069177号 | 京公网安备11010502021702
快速回复 返回顶部 返回列表