2012-12-07 30 views
3

有沒有人知道如何處理以下問題:
我有一個IAR Embedded工作臺。該項目正在使用SDRAM來運行它的代碼和Flash ROM。 SDRAM的代碼從SD卡加載。但是,在SDRAM中也存儲了一些數據,如全局或靜態變量。其中一些必須初始化。初始化步驟iar_data_init3函數調用在low_level_init函數之後。所以問題在於初始化SDRAM中的一些變量時,初始化函數從iar_data_init3調用,其代碼位於SDRAM自身內部。這是錯誤的,因爲從SD卡加載SDRAM代碼尚未完成。IAR初始化函數的放置

我嘗試了C/C++開發指南中描述的手動初始化,但這並沒有幫助。

被調用的函數是__sti__routine,它提供變量的初始化。所有這些功能都是由IAR生成的。有什麼辦法可以告訴鏈接器將初始化函數放入Flash ROM嗎?

編輯1: 這是來自IAR手冊C/C++的信息。 這是一個如何使用手動初始化的例子。

在連接配置文件:

initialize manually { section MYSECTION }; 

然後IAR文件說:

您可以使用此源代碼示例初始化部分:

#pragma section = "MYSECTION" 
#pragma section = "MYSECTION_init" 
void DoInit() 
{ 
char * from = __section_begin("MYSECTION_init"); 
char * to = __section_begin("MYSECTION"); 
memcpy(to, from, __section_size("MYSECTION")); 
} 

我無法理解然而,首先, MYSECTION_init和MYSECTION有什麼區別。 ASLO,如果我有一個全局變量:

SomeClass myclass; 

它應該放在SDRAM, 那麼如何初始化爲它做了什麼?我想手動初始化變量, 並將初始化函數放到閃存ROM中。 (問題是通過將變量放置到SDRAM中,它的初始化函數也被放置到SDRAM中)。

回答

4

您可以通過使用pragma預處理器指令來指定變量和函數的位置。您需要使用其中一個預定義的部分或定義您自己的部分。

你沒有提到你正在使用的IAR的具體口味。以下內容來自Renesas IAR Compiler Reference Guide,但您應該檢查正確的參考指南以確保語法完全相同,並瞭解預定義的部分。

使用@運營商或#pragma位置指令放置 組的功能或全局和靜態變量的命名片段, 而不必每個對象的明確的控制。變量必須是 ,或者__no_initconst。對於 示例,這些段可以放置在特定的存儲器區域中,或者使用段開始和結束操作符以受控方式進行初始化或複製。 如果您需要單獨的 鏈接單元(例如應用程序項目和引導加載程序 項目)之間的接口,這也很有用。當對單個變量的放置位置進行絕對控制時,不需要或不需要使用命名段。將功能命名片段

void f(void) @ "FUNCTIONS"; 

void g(void) @ "FUNCTIONS" 
{ 
} 

#pragma location="FUNCTIONS" 
void h(void); 

要覆蓋默認段分配的

例子,你可以明確地指定 內存比默認屬性之外:

__code32 void f(void) @ "FUNCTIONS"; 


編輯

根據您的意見,您應該有一個名爲generic_cortex.icf的鏈接器文件,它定義了您的內存區域。在它應該是說明有點類似以下內容:

/* Define the addressable memory */ 
define memory Mem with size = 4G; 

/* Define a region named SDCARD with start address 0xA0000000 and to be 256 Mbytes large */ 
define region SDCARD = Mem:[from 0xA0000000 size 0xFFFFFFF ]; 

/* Define a region named SDRAM with start address 0xB0000000 and to be 256 Mbytes large */ 
define region SDRAM = Mem:[from 0xB0000000 size 0xFFFFFFF ]; 

/* Place sections named MyCardStuff in the SDCARD region */ 
place in SDCARD {section MyCardStuff }; 

/* Place sections named MyRAMStuff in the SDRAM region */ 
place in SDRAM {section MyRAMStuff }; 

/* Override default copy initialization for named section */ 
initialize manually { section MyRAMStuff }; 

的實際名稱,地址和大小會有所不同,但應該類似。我只是使用datasheet前兩個動態存儲區域的全部大小。這裏發生的是,您正在爲不同類型的內存(即您的SD卡和SDRAM)分配地址空間的名稱,以便在編譯期間命名的部分將被鏈接器放置在正確的位置。

所以,首先你必須定義與define memory地址空間:

可能的可尋址存儲器

define memory指令定義給定大小的存儲空間的最大容量, 這是最大可能可尋址內存量,而不是 必須物理可用。

然後告訴它的芯片與define region去的地方:

可用物理內存

define region指令定義中的可用內存區域 中的應用程序代碼和部分特定部分可以放置應用程序數據的 。

下一頁鏈接器需要在什麼region知道的地方命名sectionplace in

配售部分在區域

place atplace into指令地方臺部分與 相似屬性進入之前定義的區域。

並告訴你要覆蓋部分的它的初始化與initialize manually鏈接:

初始化應用程序

的指令initializedo not initialize控制 應用應該如何被啓動。通過這些指令,應用程序 可以在啓動時初始化全局符號,並複製代碼段。

最後,在你的C文件中,告訴編譯器什麼部分以及如何初始化聲明manually的部分。

SomeClass myClass @ "MyCardStuff"; 

#pragma section = "MyCardStuff" 
#pragma section = "MySDRAMStuff" 
void DoInit() 
{ 
    /* Copy your code and variables from your SD Card into SDRAM */ 
    char * from = __section_begin("MyCardStuff"); 
    char * to = __section_begin("MySDRAMStuff"); 
    memcpy(to, from, __section_size("MySDRAMStuff")); 

    /* Initialize your variables */ 
    myClass.init(); 
} 

爲了定製多個不同存儲設備之間的啓動初始化,您需要非常仔細地研究IAR Development Guide for ARM。也請嘗試打開--log initialization選項並研究日誌和地圖文件,以確保獲得您所需的內容。

+0

在上面的例子中,你正在處理函數 但是如果在開始時需要初始化變量,上面的方法將是usefuk將變量放置到某個地方,但是如何初始化那些函數變量?我想控制將初始化函數放在哪裏。 – maximus

+0

@maximus我引用的例子是專門針對函數的,因爲這是你在你的問題中提出的問題。但是同樣的方法適用於函數和變量。請參閱鏈接的參考指南或參考指南中適用於您的特定芯片的標題爲「控制內存中的數據和功能放置」的小節。 –

+0

我已閱讀手冊。我已經更新了這個問題。你能再請參閱嗎? – maximus