1. 程式人生 > >icf檔案,連結配置檔案

icf檔案,連結配置檔案

icf是連結配置檔案(Linker configuration file)字尾名。

 

stm32韌體庫中存放路徑為:

STM32F0xx_StdPeriph_Lib_V1.5.0\Projects\STM32F0xx_StdPeriph_Templates\EWARM\

如下圖所示:;

檔案配置內容有:

  • ROM地址空間、大小和sections
  • RAM地址空間、大小和sections
  • 中斷向量表地址空間
  • 堆地址空間和大小
  • 棧地址空間和大小

舉例如下:

  • ROM地址空間、大小和sections
    /*-Memory Regions-*/
    define symbol __ICFEDIT_region_ROM_start__ = 0x08000000 ;
    define symbol __ICFEDIT_region_ROM_end__   = 0x0800FFFF;

     

  • RAM地址空間、大小和sections
    define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
    define symbol __ICFEDIT_region_RAM_end__   = 0x20001FFF;

     

  • 中斷向量表地址空間
    /*-Specials-*/
    define symbol __ICFEDIT_intvec_start__ = 0x08000000;

     

  • 堆地址空間和大小
    define symbol __ICFEDIT_size_heap__   = 0x100;

     

  • 棧地址空間和大小
    /*-Sizes-*/
    define symbol __ICFEDIT_size_cstack__ = 0x200;

    以上幾部分本來由ICF editor編輯的,在程式碼中也有禁止編輯的提示,完整程式碼如下:

/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x08000000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__ = 0x08000000 ;
define symbol __ICFEDIT_region_ROM_end__   = 0x0800FFFF;
define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
define symbol __ICFEDIT_region_RAM_end__   = 0x20001FFF;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x200;
define symbol __ICFEDIT_size_heap__   = 0x100;
/**** End of ICF editor section. ###ICF###*/

這些起始、結束地址、大小也可以在IAR工程中進行配置,配置地方如下截圖:

對於每個晶片器件,iar有預設的icf目錄對應每一種器件,但是可以由使用者自行配置,勾選Override default之後即可覆蓋預設icf檔案。

  • 預設icf配置檔案如下截圖所示:

配置不同資料塊有大有小,由小到大為sectionblock、region 。

將section放在block裡,將block放在region裡。

以下region配置程式碼ROM和RAM的大小:

define region ROM_region   = mem:[from __ICFEDIT_region_ROM_start__   to __ICFEDIT_region_ROM_end__];
define region RAM_region   = mem:[from __ICFEDIT_region_RAM_start__   to __ICFEDIT_region_RAM_end__];

以下block配置程式碼定義了堆和棧的大小:

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

以下程式碼定義了region的讀寫屬性,以及包含的block,ROM為只讀,RAM為讀寫幷包含CSTACK和HEAP:

place in ROM_region   { readonly };
place in RAM_region   { readwrite, block CSTACK, block HEAP };

IAR連結過程

1、連結需要的檔案

2、完成RAM中的程式碼和變數的初始化。初始化指令可以讓連結器產生額外的程式碼能夠copy ROM中的內容到RAM中。每個通過copy完成初始化的段被分成了兩個段,一個在ROM,一個在RAM。如果沒有人工初始化的話。連結器回自動產生啟動程式碼來完成初始化。

3、通過 icf檔案的段放置指令來決定每個section存放的位置。

4、生成最終的包含可執行映像和除錯資訊的最終檔案。

5、最後生成map檔案,包括了各個section的的在儲存器中的最終地址,global symbol的地址和用到的儲存器和庫彙總。

完整icf檔案註釋,以stm32f051_flash.icf為例

/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */

/*-Specials-*/
/* 符號常量定義,定義中斷向量表地址 */
define symbol __ICFEDIT_intvec_start__ = 0x08000000;

/*-Memory Regions-*/
/* 符號常量定義,ROM和RAM的起始結束地址 */
define symbol __ICFEDIT_region_ROM_start__ = 0x08000000 ;
define symbol __ICFEDIT_region_ROM_end__   = 0x0800FFFF;
define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
define symbol __ICFEDIT_region_RAM_end__   = 0x20001FFF;

/*-Sizes-*/
/* 符號常量定義,定義棧和堆的大小 */
define symbol __ICFEDIT_size_cstack__ = 0x200;
define symbol __ICFEDIT_size_heap__   = 0x100;
/**** End of ICF editor section. ###ICF###*/

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

/* 定義ROM region和RAM region */
define region ROM_region   = mem:[from __ICFEDIT_region_ROM_start__   to __ICFEDIT_region_ROM_end__];
define region RAM_region   = mem:[from __ICFEDIT_region_RAM_start__   to __ICFEDIT_region_RAM_end__];

/* 匯出符號常量,在.c .h原始檔中可使用 */
export symbol __ICFEDIT_region_RAM_start__;
export symbol __ICFEDIT_region_RAM_end__;

/* 定義棧block和堆block的大小,8位元組對齊 */
define block CSTACK    with alignment = 8, size = __ICFEDIT_size_cstack__   { };
define block HEAP      with alignment = 8, size = __ICFEDIT_size_heap__     { };

/* section處理,RW型別資料複製到RAM中,即啟動時資料初始化 */
initialize by copy { readwrite };

/* .noinit型別的section不需要初始化  */
do not initialize  { section .noinit };

/* 定義中斷向量表地址及屬性,屬於section,只讀,放在ROM中,需要初始化 */
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };

/* 定義ROM_region region只讀,放在ROM中 */
place in ROM_region   { readonly };

/* 定義RAM_region,讀寫屬性,放在RAM中,包括block CSTACK和block HEAP */
place in RAM_region   { readwrite, 
                        block CSTACK, block HEAP };

新增額外的region

  • 比如我要新增另一個名為ROM2的ROM區域,大小是256bytes,起始地址是0x80000.

define region ROM = Mem:[from 0x80000 size 0x100];

  • 放置section

define region CONST_region = Mem:[from 0x100 size 0x100];

place in CONST_region{readonly section .rodata}

/* 這段語句相當於一個標誌位,使的以 ILOADER  宣告的程式碼放在如下空間內,具體宣告方式如下:
#pragma location = "ILOADER"
__root const unsigned char RBL_Code[] = {
  0x00, 0x04, 0x00, 0x20, 0x85, 0x2C, 0x00, 0x08, 0x9D, 0x2C, 0x00, 0x08, 0x9F, 0x2C, 0x00, 0x08,
  0xA1, 0x2C, 0x00, 0x08, 0xA3, 0x2C, 0x00, 0x08, 0xA5, 0x2C, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA7, 0x2C, 0x00, 0x08,
};
*/
define region ILOADER_region         = mem:[from 0x08000000 to 0x08003FFF];      
place in ILOADER_region         { readonly section ILOADER };