6

我在我的 C 文件中创建了一个名为 .co_stack 的部分,并有一个名为 pulStack 的数组来定义该区域。

#define STACK_SIZE       0x00003000      /*!< Stack size (in Words)           */
__attribute__ ((section(".co_stack")))
unsigned long pulStack[STACK_SIZE];

我定义堆栈部分的 gcc 链接器脚本如下所示

.co_stack : {
    _fstackptr = ORIGIN(ram) + LENGTH(ram) - 4;
    _fstacksize = 0x00003000 * 4;       
    . = (_fstackptr - _fstacksize);
    *(.co_stack .co_stack.*)
}

如您所见,我最终在 2 个位置定义了堆栈大小。一个在我的 .c 文件中作为 STACK_SIZE ,在我的 .ld 文件中作为 _fstacksize 。

我怎样才能在一个地方定义它?

例如,我想创建一个变量 pulStackSize,如下所示。

const unsigned long pulStackSize = sizeof(pulStack);

我想将 .ld 文件中的 _fstacksize 定义为

_fstacksize = STACK_SIZE * 4;

如果这样做,我会收到一条错误消息,提示堆栈溢出 48K 字节。

如何将符号从 .c 导入到我的 .ld 文件?

4

1 回答 1

10

一些解决方案(针对更普遍的问题“如何在 C 和 LD 脚本之间共享值?”):

1)(注意:对于这个解决方案,我假设您使用的是最新版本的 GNU ld,此处的文档:http: //www.math.utah.edu/docs/info/ld_3.html

您可以通过在节化合物外部定义绝对值(例如在脚本的最开始处)将绝对值与脚本内部的符号相关联。您可以通过将符号定义为 extern 来导入 C 中的符号。请注意,您在 C 中需要的值是符号的地址:

脚本:

StackSize = 0x00003000 * 4; /* the size */
.co_stack : {  
    _fstackptr = ORIGIN(ram) + LENGTH(ram) - 4;
    _fstacksize = StackSize;       
    . = (_fstackptr - _fstacksize);
    *(.co_stack .co_stack.*)
}

C:

extern long StackSize;
#define STACK_SIZE (((size_t)&StackSize)/sizeof(long))

此解决方案可能会限制使用获得的值,例如大多数编译器不会接受这样的行:

long my_stack[STACK_SIZE];

但是您不再需要它,因为您可以在脚本中定义符号“my_stack”并将其导入为“extern long my_stack[];”。我认为无论如何这是一个可以接受的限制。

2)另一种方法是在脚本中定义两个符号位于节的开头和和,并将它们导入为C中的“extern char”。节的大小(以字节为单位)是它们两个地址的差。此解决方案具有与 (1) 相同的限制

3) 如果您的链接器不够智能,您可以使用 C 预处理器在编译时生成合适的脚本,方法是像在 C 中一样扩展宏 STACK_SIZE。您必须

a)创建文件“stacksize.h”包含

#define STACK_SIZE 0x3000

b) 在脚本开头添加 #include "stacksize.h" 行,并在需要时使用 STACK_SIZE。将脚本另存为“ldscript.c”。

c) 在您的 makefile(或等效的编译过程)中调用预处理器。如果你有 GCC,命令是:

gcc -P -E ldscript.c -o ldscript.ld

请注意,某些 gcc 版本对输入文件的扩展名赋予了特殊含义。所以我建议使用“.c”,这是最安全的方式。

d) 使用 C 预处理器生成的文件“ldscript.ld”作为链接脚本

于 2013-06-08T00:00:31.730 回答