有一个项目成功编译链接并在设备上运行。但是在告诉链接器它应该将应用程序代码的一部分放到 ROM 内存而不是 SDRAM 之后,我在链接步骤中收到以下错误:
错误[Lp002]:重定位失败:值超出范围或非法:0x60000545 种类:R_ARM_PREL31[0x2a] 位置:0xa0000030 模块:I:\Project\Debug\Obj\fileOper.o 部分:128 (.ARM.exidx) 偏移量: 0x0 目标:0x00000574 “SECTION_FILEOP_87”模块:I:\Project\Debug\Obj\fileOper.o 部分:104 (SECTION_FILEOP) 偏移量:0x4f4
我已阅读 IAR 的 C/C++ 指南。但它没有提供关于这个错误的足够好的解释。所以即使阅读手册我也无法得到这个错误的原因。任何人都可以帮助解决这个问题吗?实际上 IAR C/C++ 开发人员指南说:
对于每条不能正确重定位的指令,ILINK 都会产生一个重定位错误。这可能发生在目标无法触及或类型不兼容或许多其他原因的指令中。然后它提供了一个错误作为示例,这与我的情况不同。
编辑 1:我创建了一个重现相同错误的小项目,它仅包含 fileOper.cpp 和 main.cpp 文件。
用于告诉链接器如何将节放入内存的 ICF 文件:
定义符号 intvec_start = 0x10000000;
/ -内存区域- /
/ -闪存-/
定义符号 FLASH_ROM_start = 0x00000000;
定义符号 FLASH_ROM_end = 0x0007FFFF;
/*内部内存*/
定义符号 RAM_start = 0x10000000;
定义符号 RAM_end = 0x10017FFF;
/* SDRAM */
定义符号 SDRAM_start = 0xA0000000;
定义符号 SDRAM_end = 0xA1FFFFFF;
/ -尺寸- /
定义符号 size_stack = 0x4000;
定义符号 size_heap = 0x2000;
定义 size = 4G 的内存 mem;
定义区域 FLASH_region = mem:[从 FLASH_ROM_start 到 FLASH_ROM_end];
定义区域 RAM_region = mem:[从 RAM_start 到 RAM_end];
定义区域 SDRAM_region = mem:[从 SDRAM_start 到 SDRAM_end];
定义块 CSTACK 对齐 = 8, size = size_stack { };
定义块 HEAP 对齐 = 8, size = size_heap { };
用packing = zeros { readwrite }复制初始化;
不要初始化 { section .noinit };
放在地址 mem: intvec_start { section .intvec };
放置在 FLASH_region { readonly section .cstartup } 的开头;
放置在 RAM_region { block CSTACK };
放置在 SDRAM_region { 只读 }
除了 {readonly section FILEOP };
放置在 SDRAM_region { 读写 };
放入 SDRAM_region {块 HEAP};
放置在 FLASH_region { readonly section FILEOP };
fileOper.cpp:我已经更改了它,但它仍然重现相同的错误。
#include "fileOperbug.h"
#include <string>
char *fgets( char *str, int num, std::string *stream ) {
char *pointer = 0;
return pointer;
}
std::string *fopen(const char *name, const char *mode) {
std::string *str = new std::string();
str->assign("");
return str;
}