Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
是否可以在C代码中将链接器脚本符号地址作为编译时常量值?_C_Gcc_Embedded_Linker Scripts_Bare Metal - Fatal编程技术网

是否可以在C代码中将链接器脚本符号地址作为编译时常量值?

是否可以在C代码中将链接器脚本符号地址作为编译时常量值?,c,gcc,embedded,linker-scripts,bare-metal,C,Gcc,Embedded,Linker Scripts,Bare Metal,我希望获得程序结尾的地址,并在编译/链接器时检查代码后是否有足够的空间在执行时放置一些随机数据 但是,由于提供关键字提供的符号类似于C代码中的普通变量,因此我无法在编译时验证它 在链接器脚本中,我有一个符号: PROVIDE (__data_end_rom = _etext + SIZEOF (.data)); 因此,我可以使用此符号获取代码末尾的地址: extern u16 __data_end_rom; 如果我假设结束地址为0xffff,我可以计算可用内存: #define AVAI

我希望获得程序结尾的地址,并在编译/链接器时检查代码后是否有足够的空间在执行时放置一些随机数据

但是,由于提供关键字提供的符号类似于C代码中的普通变量,因此我无法在编译时验证它

在链接器脚本中,我有一个符号:

PROVIDE (__data_end_rom   = _etext + SIZEOF (.data));
因此,我可以使用此符号获取代码末尾的地址:

extern u16 __data_end_rom;
如果我假设结束地址为0xffff,我可以计算可用内存:

#define AVAILABLE_MEM (0Xffff - &__data_end_rom)
我想用GCC4.6中提供的_Static_assert(cond,message)检查可用内存

_Static_assert(SIZE_I_WANT_TO_ASSURE <= AVAILABLE_MEM, "NOT ENOUGH MEMORY!!!");
有没有办法直接以标签或其他方式提供_数据_结束_rom地址

我知道我不能在编译时得到它,因为符号将在链接器时间被链接,所以有办法使链接器失败吗

我可以直接在链接器脚本中检查这一点,但我不希望这样做,因为我希望确保的大小是从配置头中的其他宏计算出来的另一个宏

_Static_assert(SIZE_I_WANT_TO_ASSURE <= AVAILABLE_MEM, "NOT ENOUGH MEMORY!!!");

error: expression in static assertion is not constant
编译器不知道
\u data\u end\u rom
的地址,只有链接器知道


不幸的是,我认为在编译时没有任何方法可以做到这一点,让编译器告诉您数据太大。另一方面,读取二进制文件的附加脚本(例如,使用
size yourprog
和少量
awk
或类似内容)应该能够在
makefile
或类似内容中提供相关信息

您可以创建一个自定义链接器脚本,其中包含断言。看这里


您希望使用“断言”机制。

您可以在链接脚本本身中执行此操作,如下所示:

/* minimum amount of data required at end of .text */
_Min_Data_Left 0Xffff;

.text : 
{
... all the usual stuff ...
PROVIDE (__data_end_rom  = . );
. = . + _Min_Data_Left;
. = ALIGN(4);
} >FLASH
链接器现在会告诉你,如果你超过了限制,FLASH已经溢出,编译就会失败,我知道这是你想要的

这是一种常用的方法,用于确保可用的堆栈和堆数量最少。这里有一个版本-查找堆大小和堆栈大小:


出于好奇,您将如何处理.text中的额外空间?我假设这是在Flash中?

链接器变量的值在链接时才会填充,而静态断言通常在编译时完成。所以不可能从实际程序中的代码中执行。我知道,但是没有办法使链接器失败?或者我可以传递给链接器的命令?检查。我相信你可以在那里找到一些东西…你可以在你的链接器脚本中添加一个检查。请参阅Gnu ld。在int8_t buffer[SIZE_I_WANT_TO_ASSURE]这样的变量中保留空间的问题是,我无法使用flash中的所有可用空间,SIZE_I_WANT_TO_ASSURE是我必须拥有的最小大小,但如果我有更多空间,我想使用它。无论如何,谢谢,我当时决定破解链接器脚本。谢谢你的回答。我知道为什么编译器不知道uu data_end_rom的地址,但我想知道我是否可以在代码中写一些东西给链接器,而不是编译器,比如:#链接器断言(大小(.text)+大小(.data)<20k)。因为我认为没有这样的东西,所以我要破解链接器脚本,谢谢。@Lilás没错,编译器并不知道链接器的实际功能,它只知道如何调用链接器。链接器脚本并没有那么糟糕。如果运行
gcc-v myprog.c
,它将显示默认链接器脚本的样子。因此,您可以复制该文件,并将行添加到复制的文件中,然后使用该副本。@Lilás这已经很旧了,但是您也可以在链接器命令文件中定义
AVAILABLE\u MEM
,这样就可以了。这也不是不合理的,因为链接器脚本是特定于目标平台的。OP希望它作为编译时常量,我认为这是不可能的,正如Mats提到的。这应该是公认的答案。它解决了连接时间的问题。
#define AVAILABLE_MEM (0Xffff - &__data_end_rom)
/* minimum amount of data required at end of .text */
_Min_Data_Left 0Xffff;

.text : 
{
... all the usual stuff ...
PROVIDE (__data_end_rom  = . );
. = . + _Min_Data_Left;
. = ALIGN(4);
} >FLASH