2014-01-08 35 views
2

我正在使用gcc編譯ARM Cortex-M4F微控制器的一些代碼。我的應用程序使用我已經方便地寫入C文件的大量數據集合:整數和浮點數的大數組,循環鏈表指向各種數組,各種結構體等等。將C文件中的所有數據強制爲.text(或其他)部分

當我編譯它時,它加起來約爲500K的數據,再加上幾百K的實際應用程序。 gcc將所有這些數據方便地放入.data部分;然後,ld嘗試構建將.data部分放入RAM並將.text(code)部分放入FLASH的精靈。我使用的單元沒有500K的RAM,所以它不能構建ELF,但它確實有1M的FLASH。我嘗試改變我的鏈接器腳本,以便將.data和.text放入「正常工作」的FLASH中,但還有一些代碼需要將其數據放入RAM中,因此最終執行失敗;我無法徹底改變。

我需要的是告訴gcc把這個C文件中的每一個對象都放到.text段中,這樣它就可以和其他非可變內容一起進入FLASH,或者至少我可以在其他部分然後指示我的鏈接器腳本如何處理,以便它不會干擾RAM中沒有問題的現有斑點。我不知道該怎麼做。下面是它鏈接到的我有什麼

/* data.c */ 
static char* option_array_0_0[] = 
{ 
    "O=0.40", 
    "K=FOO", 
    "JAR=JAR", 
}; 

static int width_array_0_0[] = 
{ 
    0, 
    1, 
    1, 
}; 

Window window_array_0[] = 
{ 
    { 
     option_array, 
     width_array, 
    }, 
}; 

/* main.c */ 
extern Window window_array_0[]; 
int main() 
{ 
    /* Do stuff */ 
} 

在data.c,window_array_0一切東西(或大多數的一切,也許是字符串數組會與.text區段?)非常精簡下來例如,正在把我的鏈接器腳本放入RAM中的.data。我想把它放在不同的部分,然後我可以放入FLASH中。在那裏有數以千計的這些類型的數組,以及數百個結構和數十個其他信息位。這有可能改變嗎?作爲一個測試,我用一個char [500000]的隨機數據取代了我的「window_array_0」,並且編譯時沒有抱怨,所以我假設它把所有內容都放到了.text中(如我們所預料的那樣),我只是不知道如何製作它爲任意對象這樣做。 感謝您的幫助。

回答

1

大多數編譯器/鏈接器,如果你聲明一個變量爲static const,它會將它放在文本部分而不是數據。顯然,這些必須預先初始化,並且不會在運行時修改,但這是閃存中唯一有意義的方法。

+0

確認! 「靜態常量」實際上是我正在尋找的魔法詞。我不知道我是如何錯過的。我現在可以用這個工作。非常感謝! – DavidG

1

IIRC,閃存中的代碼通常需要是ROPI(只讀位置無關)。因此option_array_0_0width_array_0_0需要const限定符(只讀)。但是:

Window window_array_0[] = 
{ 
    { 
     option_array, 
     width_array, 
    }, 
}; 

需要以某種方式改變(我假設option_arraywidth_array確實陣列)。這使得window_array_0不是獨立的位置。

0

所有不平凡的嵌入式項目應該有一個linker script。它定義了不同的符號(函數,全局變量,調試符號等)在內存中的位置。這裏有一些關於gcc linker script的教程。

強制全部要放在一個部分的數據可能不是最好的解決方案!

注:由於這些陣列常數,它沒有任何意義將它們存儲在數據部分!因爲這意味着你將最終以代碼覆蓋代碼段(這是危險的PRETTY)。請將它們設爲const或創建一個未由加載程序初始化的no-init部分,並在復位時對其進行初始化。

+0

您可以詳細說明如何使用鏈接腳本完成強制所有數據(或大部分)到.text部分? – BullyWiiPlaza

2

正如其他評論者所指出的那樣,'靜態常量'項通常以.rodata節結束,該節可能會緊挨着.text放在潛在的只讀內存中。需要注意的是,它可能會也可能不會是真的,因爲這是針對特定目標的,並且可能會因特定的構建過程而改變(例如,鏈接器選項,通過C代碼中的__attribute__((section("name")))指定的特定部分,鏈接器腳本,構建後調整的二進制文件與各種binutils等)。

如果您需要精確控制內存中的佈局,並且知道自己在做什麼,則可以使用LD script來完成此操作。除其他外,它會讓你指定.rodata文件data.o應該放在/ .text之前,從所有其他鏈接到可執行文件的.o文件中。

您可以使用arm-<your toolchain variant>-ld -verbose轉儲默認鏈接腳本並將其用作調整的起點。

+0

指出引用'section'屬性 - 這是正確佈置圖像數據的正確起點。另一種選擇是將'.rodata'重新映射(合併)爲'.text'(或該特定體系結構中的等價物)。 – alecov

相關問題