IAR 鏈接

基本概念

section與section屬性
section是包含數據段或者代碼段可放置在存儲器內的最小邏輯單位,section即可放在RAM也可放在ROM內。在通常的嵌入式應用中,放置在RAM中的section沒有任何內容,只是佔有該存儲空間。section具有如下屬性:
這裏寫圖片描述

編譯器內部自定義section即屬性
這裏寫圖片描述

iar中關於block的概念
The block directive defines a named set of sections. By defining a block you can create
empty blocks of bytes that can be used。

通過系統icf文件模板對堆棧快的定義

    define block CSTACK    with alignment = 8, size = __ICFEDIT_size_cstack__   { };

可以看出,block定義的是一個地址快,對於大括號裏可以放置不同的section。創建一個block的目的在於能夠得到一個地址,大小等詳細信息的存儲空間。通常用來組織sections。也可以向STACK block一樣,像內存要了這麼一個空間,至於我要幹什麼編譯器你就不要管了。

IAR鏈接過程

  1. 決定哪些模塊需要包含到應用程序中。目標文件提供的模塊通常包含進去。
  2. 選擇鏈接目標文件用到的標準庫文件。
  3. 決定目標文件哪些section需要包含進來,沒有用到的自然不會包含進來。當然也可以通過特殊的編譯器指令如__root來使section鏈接到目標文件(及時程序中沒有用到)。
  4. 完成RAM中的代碼和變量的初始化。初始化指令可以讓鏈接器產生額外的代碼能夠copy ROM中的內容到RAM中。每個通過copy完成初始化的段被分成了兩個段,一個在ROM,一個在RAM。如果沒有人工初始化的話。鏈接器回自動產生啓動代碼來完成初始化。
  5. 通過 lcf文件的段放置指令來決定每個section存放的位置。
  6. 生成最終的包含可執行映像和調試信息的最終文件。在重定位輸入文件中,每個用到的section的內容是通過文件中的重定位信息和放置塊時的地址計算出來的。
  7. 最後生成map文件,包括了各個section的的在存儲器中的最終地址,global symbol的地址和用到的存儲器和庫彙總。

下圖是鏈接過程圖
這裏寫圖片描述

icf文件

一個標準的icf文件內容
1、可編址的存儲空間(memory)
2、不同的存儲地址區域(region)
3、不同的地址塊(block)
4、已創建的section
5、section的存儲空間中的放置

icf示例
示例爲Energy Micro公司EFM32單片機EFM32G289F128提供的icf文件。EFM32G280F128單片機基於Cortex-M3內核。flash:128K, RAM:16K,

/* ---定義可編址的存儲空間 ---*/
define memory Mem with size = 4G;

/*--- 不同的存儲地址區域---*/
define region ROM = Mem:[from 0x00000 size 0x20000-1];
define region RAM = Mem:[from 0x20000000 size 0x4000-1];

/*--- 不同的地址塊:堆與棧 ---*/
define block  CSTACK with size = 0x200, alignment = 8 { };
define block  HEAP   with size = 0x100, alignment = 8 { };

/* ---section 處理 ---*/
do not initialize { section .noinit };
initialize by copy { readwrite }; 

/* section的存儲空間中的放置 */
place at start of ROM { readonly section .cstartup };
place in ROM { readonly }; 
place in RAM { readwrite, 
                block STACK,
                block HEAP }; /* Place .data, .bss, and .noinit  and STACK */

編寫自己一個section

假如系統要存儲許多關鍵參數,我們把它們存儲在一個指定的ROM空間。

1、在icf文件定義自己的region,即參數存儲的固定位置

define symbol __ICFEDIT_region_MYREGION_start__ = (0X0001F000);
define symbol __ICFEDIT_region_MYREGION_end__   = (0x0001f000+0x00000FFF-1);
define region My_region    = mem:[from __ICFEDIT_region_MYREGION_start__ to __ICFEDIT_region_MYREGION_end__];

2、在函數中聲明自己的section和定義變量或函數

變量

#pragma section ="MY_SECTION"       
    const char *pMyval = "password"; //---只能是全局變量

或者

#pragma section ="MY_SECTION"    
#pragma location = "MY_SECTION" 
const int alpha;                      //----只能是全局變量

—————————————————————————–
函數

void f(void) @ "MY_SECTION";
viod g(void) @ "MY_SECTION"
{

}

或者

#pragma location="MY_SECTION"
void h(void)

3、在icf文件中放置 MY_SECIOTN

place in  My_region {
                        readonly section MY_SECTION,
                    };

4、在程序中獲得MY_SECTION的地址

char *p
#pragma section ="MY_SECTION"    
p = __section_begin("MY_SECTION");
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章