分类: 嵌入式
2009-09-22 14:36:39
一.关于函数__user_initial_stackheap
_rt—stackheap_init()建立C库使用的内存模型--堆和栈。因为ARM库是建立在semihosted执行环境的,它实现的内存模型是基于这个环境的,所以必须修改这个内存模型建立机制。表1列出了需要重新实现的函数,实现了这些函数,应用程序就可以脱离宿主机环境独立运行了。其中,必须重新实现的是_user initial_stackheap(),因为默认的实现是基于semihosted执行环境的,该函数被_n_stackheap_init()调用创建内存模型,其他两个函数没有默认的实现。
-scatter file
这个选项使用在file中包含的分组和定位信息来创建映像内存映射。
注意,如果使用了该选项的话,必须要重新实现堆栈初始化函数_user_initial_stackheap().
即当用户使用分散装载功能的时候,必须重调用_user_initial_stackheap(),否则连接器会报错:
Error: L6218E: Undefined symbol Image$$ZI$$Limit (referred from sys_stackheap.o)
实现该函数,必须满足下面的条件:
◇使用不超过96字节的栈空间;
◇除了R12(ip)外不要污染其他寄存器;
◇将堆基址、栈基址、堆边界和栈边界分别存在RO~R3作为返回参数;
◇堆必须保持8个字节对齐。
ADS帮助附注:
The values returned in r0 to r3 depend on whether you are using the one or two region model:
One region
(r0,r1) is the single stack and heap region. r1 is greater than r0. r2 and r3 are ignored.
Two regions
(r0, r2) is the initial heap and (r3, r1) is the initial stack. r2 is greater than or equal to r0. r3 is less than r1.
二:关于 IMPORT __use_no_semihosting_swi
IMPORT __use_two_region_memory
ADS 提供了两种实时存储器模型。缺省时为one-region,应用程序的堆栈和heap位于同一个存储器区块,使用的时候相向生长,当在heap区分配一块存储器空间时需要检查堆栈指针。另一种情况是堆栈和heap使用两块独立的存储器区域。对于速度特别快的RAM,可选择只用来作堆栈使用。为了使用这种 two-region模型,用户需要导入符号use_two_region_memory,heap使用需要检查heap的长度限制值。
对这两种模型来说,缺省情况下对堆栈的生长都不进行检查。用户可以在程序编译时使用 -apcs/swst 编译器选项来进行软件堆栈检查。如果使用two-region模型,必须得在执行_user_initial_stackheap时指定一个堆栈限制值。
Semihosting
在ADS 的C语言函数库中,某些ANSIC的功能是由主机的调试环境来提供的,这套机制有一个专门术语叫Semihosting。Semihosting通过一组 软件中断(SWI)指令来实现。如图1所示,当一个Semihosting软中断被执行时,调试系统先识别这个SWI请求,然后挂起正在运行的程序,调用 Semihosting的服务,完成后再恢复原来的程序执行。因此,主机执行的任务对于程序来说是透明的。
在C语言库函数中禁用Semihosting
在一个独立的嵌入式应用程序中,应该不存在SemihostingSWI操作。因此,用户必须确定在所有调用到的库函数中没有使用Semihosting。为了保证这一点,在程序中可以引进一个符号关键字_use_no_semihosting:
在C代码中,使用#prgrama #pragmaimport〈_use_no_semihosting_swi〉
在汇编程序中,使用IMPORT
IMPORT_use_no_semihosting_swi
这样,当有使用SWI机制的库函数被连接时,连接器会进行报错:
Error:Symbol_semihosting_swi_guardmultiplydefined
为了确定具体是哪一个函数,连接时打开-verbose选项。这样在结果信息输出时,该库函数上将有一个_I_use_semihosting_swi的标记。
Loadingmembersys_wxit.ofromc_a_un.1.
Definition:_sys_exit
Reference:_I_use_semihosting_swi
用户必须要把这些函数定义成自己的执行内容。
有一点需要注意,连接器只能报告库函数中被调用的Semihosting,对用户自定义函数中使用的Semihosting则不会报错。