有一个项目成功编译链接并在设备上运行。 但在告诉链接器它应该将应用程序代码的一部分放入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;
/ -Memory Regions - /
/ -FLASH ROM - /
定义符号FLASH_ROM_start = 0x00000000;
定义符号FLASH_ROM_end = 0x0007FFFF;
/ * 内部RAM * /
定义符号RAM_start = 0x10000000;
定义符号RAM_end = 0x10017FFF;
/ * SDRAM * /
定义符号SDRAM_start = 0xA0000000;
定义符号SDRAM_end = 0xA1FFFFFF;
/ -Sizes - /
定义符号size_stack = 0x4000;
定义符号size_heap = 0x2000;
定义大小= 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];
使用alignment = 8定义块CSTACK,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}
除了{readonly section FILEOP};
放入SDRAM_region {readwrite};
放入SDRAM_region {block 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;
}
答案 0 :(得分:1)
我已经解决了这个问题。 使用IAR Embedded工作台时: 项目选项 - &gt; C / C ++编译器 - &gt;语言1选项卡。 在“C ++方言”中有一个名为“with exceptions”的复选框被检查。 选中“with exceptions”复选框时,会发生链接阶段的错误。 所有使用异常的代码都必须加载到ROM。否则,应取消选中“with exceptions”。