―将程序履行到C文件的main函数
二.试验意图
运用ADS编写一个小程序,使程序能够从开端的汇编代码运转到C程序的main()函数(这也可称作十分简略的起动代码),并经过仿真器衔接方针板,终究能够在AT91SAM7S64里正确运转。
三.试验程序和参数设置
1>衔接器的选项设置
选项设置如图2-1所示。因为在AT91SAM7S64中FLASH存储器的地址是以0x0开端,而SRAM的地址是以0x00200000开端,所以我将下图中的RO Base和RW Base别离设置成了0x0和0x00200000。其它设置请参阅有关书本。
图2-1. 选项设置图
2>发动代码
在ARM运用体系中,芯片复位后,在进入C言语的main()函数前,都要履行一段发动代码。该代码一般都是用汇编言语编写,用来完结体系运转环境和运用程序的初始化,详情请参阅有关书本。因为本试验的意图很简略,便是想让程序复位后,进入main()函数,所以有些初始化代码尽量精简,留下了下述代码。别的,__main是C言语的内部库函数,能够在进入用户main()之前完结内部RAM的初始化作业,相似KeilC51中的startup.a51。当履行完__main这段代码后,再跳转到main()函数。
AREA init,CODE,READONLY
CODE32
Mode_USREQU0x10 ;CPSR中各种处理器形式对应的操控位
I_Bit EQU0x80 ;CPSR中的中止制止位
F_Bit EQU0x40
USR_StackEQU0x00203000 ;界说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 ; 0x18IRQ
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: Cant set point”。
原因是仿真器在ROM中设置的断点数是有限的,且单步运转时内部还要占用断点。能够运用“Option->Config Processor”翻开“Processor Properties-ARM7TDMI”窗口,且依照下图设置以关断相的断点。
图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()函数。