1

我正在做一个嵌入式项目。我正在尝试使用 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++ 中,上面的表达式是可以的。

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

/安德斯

4

2 回答 2

0
  • 在片上 eeprom 中放置变量时,它们总是需要是const type.
  • 在片上 eeprom 中放置指针时,它们总是需要是类型type* const(指向非常量数据的常量指针)或const type* const(指向常量数据的常量指针)。

这似乎是您问题的真正根源。当然,一旦它们被声明为 const,你就不应该抛弃 const-ness。

此外,如果它是片上 eeprom,是否有不能直接访问存储单元的原因?在大多数系统上,您都可以做到这一点,尽管访问时间可能比对 RAM 变量的等效访问要慢。

附带说明一下,强制转换为uint16_t(或无符号短)只会在小端机器上为您提供 16 个最低有效位。该代码不能移植到大端。可移植代码将是((uint32_t)pointer >> 16).

于 2014-12-08T11:00:52.923 回答
0

然而,在 C++ 中,上面的表达式是可以的。

C++ 编译器接受初始化,但在运行时执行(请参阅Spurious error: initializer element is not computable at load time),这可能不是您想要的。

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

即使在绕过该错误之后,例如

__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/…
于 2017-04-06T06:24:20.770 回答