IMPORT __main .... .... 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
function When the compiler compiles a function 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()函数的好。 |