2014-12-08 48 views
1

我正在開發一個嵌入式項目。我正在嘗試使用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

回答

0
  • 當將變量片上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

0

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/…