卢家顺的笔记 https://bbs.21ic.com/?513681 [收藏] [复制] [RSS]

日志

ARM中B __Main和B Main的区别(转载)

已有 1214 次阅读2009-6-20 10:50 |个人分类:arm7|系统分类:ARM














ARM中B __Main和B Main的区别
 
第一种答案如下:


在软件仿真的情况下,执行“B __main”指令,能使程序跳到C文件的main函数,但用硬件仿真时,还没执行到main函数时就进入了异常中断。


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


第二种答案如下:


IMPORT __main


.... ....


BL TargetResetInit


B __main ------------------------------------------------------------------


1、此后流程将跳转到ADS提供的启动代码__main函数处,负责完成库函数的初始化及相关功能,并最终引导处理器入口用户代码main()函数,其代码流程为: 嵌入式系统在进入应用主程序之前必须有一个初始化的过程,该过程完成系统的启动和初始化功能,初始化过程可以分成两部分来看:


√ _main负责设置运行映像存储器映射;


√ _rt_entry负责库函数的初始化。


_main完成代码和数据的复制,并把ZI数据区清零,这一步当代码和数据区在存储和运行时处于不同的存储器位置时有意义。接着_main跳进_rt_entry,进行STACK和HEAP等的初始化。最后_rt_entry跳进应用程序的入口main()。当应用程序执行完时,_rt_entry又将控制权交还给C库函数,函数main()在ADS中有特殊的意义。当一个程序工程项目中存在main()时,连接器会把_main和_rt_entry中的初始化代码连接进来;如果没有main()函数,初始化过程就不会被连接,初始化过程中一些标准的C库函数失效。而用户应用程序初始化过程并未显式的完成这些堆栈初始化及数据拷贝操作,应用程序将启动不成功。


2、__main()为编译系统提供的一个库函数,使用__main标号引导系统时必须将应用程序的入口数定义为main();


3、若希望系统进入应用程序前自动完成系统调用(如库函数的初始化、RW、ZI数据从Flash到RAM的拷贝(加载映像--->执行映像)等)的初始化过程,必须使用__main标号以跳至ADS提供的初始化函数库,这种情况一般需做一些库函数移植及重定向问题解决;这一点上,应用程序入口必须以main函数标识;


4、若所有的初始化步骤都已显式的完成(如堆栈初始化、加载映像到执行映像RW、ZI数据的拷贝等),应用程序入口函数XXXX()可以任意定义,初始化完成后直接B XXXX即可,这一点上,main()函数并不具有特殊性; 5、若必须的初始化步骤都未显示的完成,一意孤行的B XXXX,程序运行的结果将不可预料。一个典型的例子是:若用户并未显示完成加载映像--->执行映像的数据初始化而直接B XXXX,则应用程序中所有的全局变量并不会被预期的初始化,而所有的ZI变量也不会被预期的清零; 6、本人在调试LPC2294 LCD模块时才认识到上述第五点(5、)的重要性:程序指令流并没有错,但LCD上显示的全部是乱码。我用两种方法解决了这一bug:(1)将所有的字库数据定义为const常量,程序运行正确;(2)将B Main 修改成B __main接着将应用入口改为int main(void) 而非int Main(void),程序也得到正确的执行; Initializing memory required by C code


The initial values for any initialized variables (RW) must be copied from ROM to RAM.


All other ZI variables must be initialized to zero. The library initialization code called


at __main performs the copying and initialization. Using the main


When the compiler compiles a  called main(), it generates a reference to the


symbol __main to force the linker to include the basic C run-time system from the ANSI


C library. (The symbol __main is marked as an entry point.) 建议和我一样的初学者还是乖乖的B __main接着将应用入口设置为main()函数的好。


路过

鸡蛋

鲜花

握手

雷人

评论 (0 个评论)