我正在从事嵌入式项目。我试图使用GNU链接器来布局存储在外部eeprom中的一些变量。我这样做是通过使用
分配eeprom变量int __attribute__ ((section (".eeprom"))) eeprom_var1;
我还将为eeprom定义初始化变量,例如:
int __attribute__ ((section (".eeprom"))) eeprom_var2 = 0x42;
然后就是这个想法;在初始化eeprom时,正在运行的应用程序将初始化变量从.text部分的某个地方复制到eeprom,就像初始化数据部分一样。显然,eeprom变量无法读/写,但必须通过以下函数访问:
eeprom_read(data, &eeprom_var,sizeof(eeprom_var)).
到目前为止一切顺利,
现在我想用另一个变量的指针初始化一个eeprom变量:
unsigned long long __attribute__ ((section (".eeprom"))) eeprom_var1 = 0x42;
unsigned short __attribute__ ((section (".eeprom"))) eeprom_var2 = (unsigned short )&eeprom_var1;
注意,eeprom使用16位地址空间
但这会产生以下错误
foo.c:4:1: error: initializer element is not constant
unsigned short __attribute__ ((section (".eeprom"))) eeprom_var2 = (unsigned short )&eeprom_var1;
^
这是因为转换为(unsigned short)作为初始化程序读取操作,C中不允许使用。在C ++中,上面的表达式是正确的。
任何人都可以想办法解决上面的错误吗?
/安德斯
答案 0 :(得分:0)
const type
类型。type* const
(指向非常量数据的常量指针)或const type* const
(常量数据的常量指针)。 这似乎是您问题的真正根源。当然,一旦它们被宣布为常量,你就不应该抛弃常量。
另外,如果它是片上eeprom,是否有理由不能直接访问存储单元?在大多数系统上,您可以执行此操作,但访问时间可能比对RAM变量的等效访问速度慢。
作为旁注,转换为uint16_t
(或无符号短整数)只会在小端机器上提供16个最低有效位。代码不能移植到big endian。可移植代码为((uint32_t)pointer >> 16)
。
答案 1 :(得分:0)
但是在C ++中,上面的表达式还可以。
C ++编译器接受初始化,但是在运行时执行(参见Spurious error: initializer element is not computable at load time),这可能不是你想要的。
任何人都可以想办法解决上面的错误吗?
即使在解决了这个错误之后,e。 G。与
__asm__(".section .eeprom,\"aw\"\n"
".globl eeprom_var2\n"
"eeprom_var2: .short eeprom_var1");
extern unsigned short eeprom_var2;
链接器以错误退出:
…: relocation truncated to fit: R_386_16 against symbol `eeprom_var1' defined in .eeprom section in /tmp/…