在GCC中获取指针的低16位编译时间

问题描述:

我正在开发一个嵌入式项目。我正在尝试使用GNU链接器来布局存储在外部eeprom中的一些变量。我用在GCC中获取指针的低16位编译时间

int __attribute__ ((section (".eeprom"))) eeprom_var1; 

分配EEPROM变量做到这一点我也将定义初始化变量的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位地址空间

但是这给了FO llowing错误

foo.c:4:1: error: initializer element is not constant 
    unsigned short __attribute__ ((section (".eeprom"))) eeprom_var2 = (unsigned short)&eeprom_var1; 

^

这是因为流延到(无符号短)被读作为一个初始值设定,其未在允许C.在C++然而上述表达式是确定的操作。

任何人都可以想办法解决上述错误吗?

/安德斯

+0

你可以使用'asm' – 2014-12-08 09:32:26

+0

你能只是0xFFFF的面膜呢,还是有同样的结果? – nchen24 2014-12-08 10:28:00

+0

我试过了,这是一样的 – aes79 2014-12-11 13:03:44

  • 当将变量片上EEPROM,它们总是需要const type类型。
  • 将指针放入片内eeprom时,它们始终需要为type* const(恒定指针指向非常数数据)或const type* const(指向常数数据的常量指针)类型。

这似乎是你的问题的真正源头。当然,一旦它们被声明为const,你不应该抛弃这个常量。另外,如果它是片上eeprom,是不是有直接访问存储单元的原因?在大多数系统中,您可以执行此操作,但访问时间可能比等效访问RAM变量要慢。作为一个方面说明,铸造到uint16_t(或无符号短)只会给你一个小端机上的16个最低有效位。该代码不能移植到大端。便携式代码将是((uint32_t)pointer >> 16)

+1

在系统中我使用的eeprom没有直接映射到主机的内存空间(它是一个SPI连接的设备)。链接器仅用于布局变量。我看到你关于const类型*成本的观点,但是关于这个问题的问题是它会创建一个32位指针,而我真的只想存储16位。 – aes79 2014-12-11 13:02:42

In C++ however the above expression is ok.

的初始化是由C++编译器所接受,但在运行时进行(见Spurious error: initializer element is not computable at load time),这可能不是你想要的。

Can any one think of way to get around the error above?

即使在得到该错误后, 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/…