RealView 编译工具 库和浮点支持指南

转载来源于: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0349bc/Cihhdahf.html

 

2.10.5. __user_initial_stackheap()

如果您使用的是旧式源代码,则可能会看到 __user_initial_stackheap()。这是旧函数,支持它只是为了与旧式源代码向后兼容。 其当前等效项是 __user_setup_stackheap()

从 RVCT v2.x 及更低版本移植到 RVCT v4.0

在 RVCT 2.x 及更低版本中,__user_initial_stackheap() 的缺省实现使用符号 Image$$ZI$$Limit 的值。如果链接器使用分散加载描述文件(使用 --scatter 命令行选项指定),则不会定义该符号;因此,如果使用的是分散加载描述文件,则必须重新实现 __user_initial_stackheap(),否则,链接步骤将会失败。

另外,您也可以使用 __user_setup_stackheap()(而不是 __user_initial_stackheap())来升级源代码。

从 RVCT v3 移植到 RVCT v4.0

在 RVCT v3.x 和更高版本中,库包含更多的 __user_initial_stackheap() 实现,并且可通过分散加载描述文件中提供的信息自动选择正确的实现。这意味着,如果使用的是分散加载文件,则不需要重新实现该函数。 有关详细信息,请参阅使用分散加载描述文件

语法

extern __value_in_regs struct __user_initial_stackheap __user_initial_stackheap(unsigned R0, unsigned SP, unsigned R2, unsigned SL);

用法

__user_initial_stackheap() 返回:

  • r0 中的堆基址

  • r1 中的堆栈基址,即堆栈区中的最高地址

  • r2 中的堆限制

  • r3 中的堆栈限制,即堆栈区中的最低地址。

如果重新实现了此函数,则必须满足下列条件:

  • 最多使用堆栈中的 88 个字节

  • 不能破坏 r12 (ip) 以外的寄存器

  • 保持堆的 8 字节对齐方式。

对于缺省单区模型,将忽略 r2r3 中的值,并且 r0r1 之间的所有内存始终可供堆使用。对于双区模型,堆限制是由 r2 设置的,堆栈限制是由 r3 设置的。

调用 __main() 时的 sp (r13) 值将作为 r1 中的自变量进行传递。 __user_initial_stackheap() 的缺省实现(使用半主机 SYS_HEAPINFO)是由 sys_stackheap.o 模块中的库提供的。

要创建从执行环境中继承 sp 并且不使用堆的 __user_initial_stackheap() 版本,请将 r0r2 设置为 r3 的值并返回。有关详细信息,请参阅__user_setup_stackheap()

rt_misc.h 中的 __initial_stackheap 的定义是:

struct __initial_stackheap{
    unsigned heap_base, stack_base, heap_limit, stack_limit;
}; 

Note

stack_base 的值比堆栈使用的最高地址大 0x1,这是因为使用的是满降序堆栈。

有关该函数的重新实现示例,请参阅示例目录。

返回值

r0r3 中返回的值取决于是使用单区内存模型,还是使用双区内存模型:

单区

(r0,r1) 是单个堆栈和堆区。r1 大于 r0,并忽略 r2 r3

双区

(r0, r2) 是初始堆,(r3, r1) 是初始堆栈。r2 大于或等于 r0r3 小于 r1

使用分散加载描述文件

__user_initial_stackheap() 的缺省实现使用 Image$$ZI$$Limit 符号的值。如果链接器使用分散加载描述文件,则不会定义此符号。 不过,C 库提供了替代实现,可通过分散加载描述文件中的信息来使用这些实现。

自动选择单区模型

在分散加载描述文件中定义一个特殊执行区,即 ARM_LIB_STACKHEAP。该区具有 EMPTY 属性。

这导致库选择一个 __user_initial_stackheap() 实现,它将该区用作复合堆/堆栈区。它使用 Image$$ARM_LIB_STACKHEAP$$Base Image$$ARM_LIB_STACKHEAP$$ZI$$Limit 符号的值。

自动选择双区模型

在分散加载描述文件中定义两个特殊执行区: ARM_LIB_HEAP ARM_LIB_STACK。两个区均具有 EMPTY 属性。

这导致库选择一个使用以下符号值的 __user_initial_stackheap() 实现:Image$$ARM_LIB_HEAP$$BaseImage$$ARM_LIB_HEAP$$ZI$$LimitImage$$ARM_LIB_STACK$$BaseImage$$ARM_LIB_STACK$$ZI$$Limit

Example 2.10 显示了一个用于定义 ARM_LIB_HEAPARM_LIB_STACK 的分散加载描述文件示例。(它是在主示例目录 install_directory\RVDS\Examples 中作为 Cortex-M3.scat 提供的。)

Example 2.10. ARM_LIB_HEAP 和 ARM_LIB_STACK 分散加载描述

FLASH_LOAD 0x0000 0x00200000
{
  ;; Maximum of 256 exceptions (256*4 bytes == 0x400)
  VECTORS 0x0 0x400
  {
    ; Exception table provided by the user in exceptions.c
    exceptions.o (exceptions_area, +FIRST)
  }
  
  ;; Code is placed immediately (+0) after the previous root region
  ;; (so code region will also be a root region)
  CODE +0
  {
    * (+RO)
  }

  DATA 0x20000000 0x00100000
  { 
    * (+RW, +ZI)
  }

  ;; Heap starts at 1MB and grows upwards
  ARM_LIB_HEAP 0x20100000 EMPTY 0x100000-0x8000
  {
  }
  ;; Stack space starts at the end of the 2MB of RAM
  ;; And grows downwards for 32KB
  ARM_LIB_STACK 0x20200000 EMPTY -0x8000
  {
  }
}

将从 ARM_LIB_STACKHEAP(对于单区模型)或 ARM_LIB_STACK(对于双区模型)中对 sp 进行相应的初始化。

错误消息

如果使用分散文件,而没有指定任何特殊区名称,并且没有重新实现 __user_initial_stackheap(),库将生成一条错误消息。

 

你可能感兴趣的:(RealView 编译工具 库和浮点支持指南)