将函数映射到其他内存段时GCC中的链接错误
目的:将函数映射到其他内存段时GCC中的链接错误,c,gcc,compiler-errors,linkage,C,Gcc,Compiler Errors,Linkage,目的: void __attribute__ ((noinline, section ("msmc_program"))) my_func1(unsigned int param0) { //function body } 我正在尝试将某些功能从DDR重新映射到L3缓存,该缓存被编程为SRAM。我使用GNU嵌入式工具GCC4.7.4作为编译器 我所做的(这将引出我的问题): void __attribute__ ((noinline, section ("msmc_program"))) my
void __attribute__ ((noinline, section ("msmc_program"))) my_func1(unsigned int param0) {
//function body
}
我正在尝试将某些功能从DDR重新映射到L3缓存,该缓存被编程为SRAM。我使用GNU嵌入式工具GCC4.7.4作为编译器
我所做的(这将引出我的问题):
void __attribute__ ((noinline, section ("msmc_program"))) my_func1(unsigned int param0) {
//function body
}
这适用于大多数功能。它编译成功,我可以从映射文件确认映射
然而,我的问题是,我未能使用其他一些函数进行编译。存在链接错误:
arm none eabi/bin/ld.exe:最终链接失败:节没有内容
collect2.exe:错误:ld返回1个退出状态
问题:
void __attribute__ ((noinline, section ("msmc_program"))) my_func1(unsigned int param0) {
//function body
}
此链接错误的原因是什么(最终链接失败:节没有内容)?我在下面提供了一些额外的信息
当我检查代码时,我看到这些函数在常量表中使用,并作为回调函数调用
我就是这么做的:
常数表文件.h:
struct job_element_info_table_s
{
const unsigned int (* jeit_job_exec_func)();
};
常数表文件.c:
extern void __attribute__ ((externally_visible, long_call, noinline, section ("msmc_program"))) my_func_2(unsigned int param0);
const struct job_element_info_table_s job_info_table[] =
{
{
(const unsigned int (* )())my_func_2,
}
};
另一个_c_文件.c:
void __attribute__ ((externally_visible, long_call, noinline, , section ("msmc_program"))) my_func_2(unsigned int param0) {
//function_body
}
“外部可见”和“长调用”是我对这种情况的实验,因为DDR和L3缓存地址彼此相距很远。但不管有没有他们,我都不走运
我还试图将常量表“job_info_table”映射到msmc_程序部分,但仍然得到相同的错误
另一个有趣的地方是,如果我将函数映射到任意DDR部分,它将成功编译。例如:
void __attribute__ ((externally_visible, long_call, noinline, , section ("arbitrary_sec_123"))) my_func_2(unsigned int param0) {
//function_body
}
在本例中,它会自动在DDR中创建一个名为Arbitral_sec_123的部分,并将函数映射到此部分
我的编译选项是:
# Compile options.
C_OPTS = -Wall \
-Werror=uninitialized \
-Werror=maybe-uninitialized \
-Werror=overflow \
-mcpu=cortex-a15 \
-mtune=cortex-a15 \
-mabi=aapcs \
-mapcs \
-mfpu=neon \
-ftree-vectorize \
-ftree-vectorizer-verbose=2 \
-mfloat-abi=hard \
-O3 \
-g \
-flto \
-marm \
-fno-gcse \
-fno-strict-aliasing \
-fno-delete-null-pointer-checks \
-fno-strict-overflow \
-fuse-linker-plugin \
-falign-functions=64
# Linker options.
L_OPTS = -nostartfiles \
-static \
-Wl,--gc-sections \
-Wl,-Map,$(BUILD_DIR)/$(PROJ).map \
-mcpu=cortex-a15 \
-mtune=cortex-a15 \
-mabi=aapcs \
-mapcs \
-mfpu=neon \
-ftree-vectorize \
-ftree-vectorizer-verbose=2 \
-mfloat-abi=hard \
-O3 \
-g \
-flto \
-marm \
-fno-gcse \
-fno-strict-aliasing \
-fno-delete-null-pointer-checks \
-fno-strict-overflow \
-fuse-linker-plugin \
-falign-functions=64
LIBS = -lgcc -lc -lm -lrdimon
不能像普通内存那样使用缓存。它由硬件自动管理,一条缓存线可以保存不同地址的内容(当然不是同时保存)。这实际上是一个称为多核共享内存的内存单元,我可以像SRAM一样使用它。我已经将一些数据结构映射到此内存。但是我试着使用它的一个空闲部分,就像程序内存一样。无论如何,在某些架构中,如果将缓存配置为SRAM,则可以像“常规内存”一样使用缓存。但必须将其配置为SRAM。所以关于这个问题,它不再是缓存了。假设您的问题不是配置,在这种情况下,需要更多信息。还要注意,您的gcc已经过时了。尤其是ARM支持在较新版本中已经相当先进,但是LTO在这个版本中也有一些问题。我将尝试使用新版本,并在这里分享结果。我只是说得很清楚:我没有说这会解决问题。一般来说,这只是一个好主意。你不能像普通内存那样使用缓存。它由硬件自动管理,一条缓存线可以保存不同地址的内容(当然不是同时保存)。这实际上是一个称为多核共享内存的内存单元,我可以像SRAM一样使用它。我已经将一些数据结构映射到此内存。但是我试着使用它的一个空闲部分,就像程序内存一样。无论如何,在某些架构中,如果将缓存配置为SRAM,则可以像“常规内存”一样使用缓存。但必须将其配置为SRAM。所以关于这个问题,它不再是缓存了。假设您的问题不是配置,在这种情况下,需要更多信息。还要注意,您的gcc已经过时了。尤其是ARM支持在较新版本中已经相当先进,但是LTO在这个版本中也有一些问题。我将尝试使用新版本,并在这里分享结果。我只是说得很清楚:我没有说这会解决问题。总的来说,这只是个好主意。