介紹介紹IAR的icf配置文件,其實這算是一篇知識深刻擴展,初手在用IAR簡單開發一款片子的時候不多有人去關心該配置文件的,由於該配置文件通常在用IAR新建工程選型目標芯片的時候系統自動添加了(固然kinetis的官方例程裏給出的配套的配置文件須要另行本身添加了),會以爲這是IDE系統的事。可是若是你是要作深刻研究或者說真正掌握瞭解一款片子,而不是霧裏看花知其然而不知其因此然,那麼配置文件則是你的必修內容,怎麼樣,好奇了吧,呵呵,下面深刻了解一番吧,進入正題:函數
1.首先說說什麼是icf文件(即ILINK連接器的配置文件)的做用,其實在IAR5.x以前,IAR是採用的叫XLINK的連接器(它相應的配置文件爲xcl文件),5.x以後才採用了新版ILINK連接器,因此我們開發Kinetis的IAR6.x天然也採用的是ILINK連接器,配置文件爲icf文件,咳咳,若是有人問什麼是連接器,先谷歌一下補補,我這裏就引用IAR官方手冊裏的一句話簡要說明一下什麼是連接器及其相應配置文件的做用吧:工具
」EWARM 5.xx 中的連接器稱爲ILINK。ILINK 能夠從 ELF/DWARF 格式的目標文件中提取代碼和數據, 並生成可執行的輸出鏡像。對於 ELF/DWARF 格式而言,基本的連接單元是section,section 的類型有code和data,屬性能夠是readonly (ro),readwrite (rw)和zeroinit (zi)。ILINK 根據 ILINK Configuration File(*.icf)來分配和定位這些sections。「設計
exported 導出該symbol,使其對可執行鏡像可用
name 符號名
expr 符號值
舉例:
define symbol RAM_START_ADDRESS = 0x40000000; /* 定義 RAM 起始地址 */
define symbol RAM_END_ADDRESS = 0x4000FFFF; /* 定義 RAM 結束地址 */
-------------------------------------------------------------------
(2)define memory name with size = expr [, unit-size];
做用:
定義一個可編址的存儲地址空間(memory)。
參數:
name memory的名稱
expr 地址空間的大小
unit-size expr的單位,能夠是位(unitbitsize),缺省是字節(unitbytesize)
舉例:
define memory MEM with size = 4G;
-----------------------------------------------------------------
(3)define region name = region-expr;
做用:
定義一個存儲地址區域(region)。一個區域可由一個或多個範圍組成,每一個範圍內地址必須連續,但幾個範圍之間沒必要是連續的。
參數:
name region的名稱
region-expr memory:[from expr { to expr | size expr}],能夠定義起止範圍,也能夠定義起始地址和region的大小
舉例:
define region ROM = MEM:[from 0x0 size 0x10000];
/* 定義 ROM region,位於地址空間MEM 中,起始地址爲0x0,大小爲0x10000 字節 */
define region ROM = MEM:[from 0x0 to 0xFFFF];
/* 定義 ROM region,位於地址空間MEM 中,起始地址爲0x0,結束地址爲0xFFFF */
---------------------------------------------------------------------------------------------
(4)
define block name [ with param, param... ]
{
extended-selectors
};
做用: 定義一個地址塊(block);它能夠是個只保留指定大小的地址空間的空塊,好比棧、堆;也能夠包含一系列的sections,由extended-selectors 選擇。
參數:
name block 的名稱
param 能夠是: size = expr (塊的大小)
maximum size = expr (塊大小的上限)
alignment = expr (最小對齊字節數)
fixed order (按照固定順序放置sections)
extended-selector [ first | last ] { section-selector | block name | overlay name }
first 最早存放
last 最後存放
section-selector [ section-attribute ][ section sectionname ][object filename ]
section-attribute [ readonly [ code | data ] | readwrite [ code | data ] | zeroinit ]
sectionname section的名稱
filename 目標文件的名稱
name block或overlay的名稱
注:這裏能夠按照section的屬性,名稱及其所在目標文件這三個過濾條件中,任意選取一個條件或多個條件進行組合,來圈定所要求的sections。
舉例:
define block HEAP with size = 0x1000, alignment = 4 { };
/* 定義 HEAP block,大小爲0x1000,4 字節對齊,沒有內容 */
define block MYBLOCK1 = { section mysection1, section mysection2, readwrite };
/* 定義 MYBLOCK1 block,含有mysection1,mysection2,以及全部readwrite 屬性的sections */
define block MYBLOCK2 = { readwrite object myfile2.o };
/* 定義 MYBLOCK2 block,含有目標文件myfile2.o 中全部readwrite 屬性的sections */
define block MYBLOCK3 = { readonly code object myfile3.o };
/* 定義 MYBLOCK3 block,含有目標文件myfile3.o 中全部readonly 屬性的code sections */
(5)
initialize { by copy | manually } [ with param, param... ]
{
section-selectors
};
做用: 初始化sections
參數:
by copy 在程序啓動時自動執行初始化
manually 在程序啓動時不自動執行初始化
param 能夠是: packing = { none | compress1 | compress2 | auto } copy routine = functionname
packing表示是否壓縮數據,缺省是auto
functionname表示是否使用本身的拷貝函數來取代缺省的拷貝函數
section-selector 同上
舉例:
initialize by copy { readwrite }; /* 在啓動時初始化全部屬性爲 readwrite 的sections */
--------------------------------------------------------------
(6)
do not initialize
{
section-selectors
};
做用: 規定在程序啓動時不須要初始化的sections;通常用於__no_init 聲明的變量段(.noinit)
參數:
section-selector 同上
舉例:
do not initialize { .noinit }; /* 在啓動時不要初始化.noinit section */
(7)
place at { address memory [:expr] | start of region_expr | end of region_expr }
{
extended-selectors
};
做用: 把section 或 block 放置在某個具體的起始地址處,或者一個 region 的開始或結束處
參數:
memory memory 的名稱
expr 地址值,該地址必須在 memory 所定義的範圍內
region_expr region 的名稱
extended-selector 同上
舉例:
place at end of ROM { section .checksum }; /* 把.checksum 放在 ROM region 的最後 */
place at address MEM:0x0 { section .intvec }; /* 把.intvec 放在地址 0x0 */
place at address MEM:0x1000 { section .text object myfile.o }; /* the .text section of myfile.o */
place at address MEM:0x1000 { readonly object myfile.o }; /* all read-only sections of myfile.o */
place at address MEM:0x1000 { readonly data object myfile.o }; /* all read-only data sections of myfile.o */
(8)
place in region-expr
{
extended-selectors
};
做用: 把section 或 block (按任意順序)放置在某個region 中
參數:
region-expr region 的名稱
extended-selector 同上
舉例:
place in ROM { readonly }; /* all readonly sections */
place in RAM { readwrite }; /* all readwrite sections */
place in RAM { block HEAP, block CSTACK, block IRQ_STACK }; /* heap and stacks */
place in ROM { section .text object myfile.o }; /* the .text section of myfile.o */
place in ROM { readonly object myfile.o }; /* all read-only sections of myfile.o */
place in ROM { readonly data object myfile.o }; /* all read-only data sections myfile.o */
下面爲系統預約義(即你是找不到其定義的,因此不要浪費時間去找了,呵呵)的section和block描述,上圖:
4.相關命令知曉了,也就是大好基礎了,下面就俺就根據上面個的指令獨家解析下飛思卡爾提供的Kinetis例程包裏自帶的icf配置文件,以512KB_Pflash.icf爲例介紹一下(當初本身上傳的開發框架代碼裏沒有做相關注釋,這裏就算是補充了吧,哈哈):
(1)首先找到該文件,打開(咳咳,雖然這步算是廢話,不過爲了嚴謹,仍是不能少的,呵呵),採用從上到下的順序解讀;
(2)
先定義了一些可讀性的符號,包括異常向量表的起始地址,ROM、RAM 的起止地址和堆、棧的大小等(該地址分配咱們能夠在Kinetis的datasheet裏找到),之前綴__ICFEDIT_開頭的符號是由圖形化編輯工具 ICF Editor自動定義的,可能會有些人不懂,其實上面部分代碼是體如今IAR的Options->Linker選項裏的(本身去探索一下便可發現)。
(3)
這部分仍然是定義一些符號,由Kinetis的內存映射能夠知道,其實其內部是由兩部分RAM塊組成的,因此第一步出現RAM_start這一步出現了RAM2_start,另外也定義了中斷向量表在ROM中的地址和在RAM中的地址。code_start定義爲0x00000410是緊鄰前面向量表的,也就是說向量表佔用了0x00000410大小的空間。
(4)
到了這一步就設計到具體操做內容了,32位地址總線選址4G空間,而後定義了kinetis(512k型號的哈)的ROM區的地址範圍和RAM區(含RAM1和RAM2)的地址範圍。接着下面定義了堆和棧的屬性,8字節對齊方式,大小爲前面定義的大小即分別爲0x1000和0x200。
(5)
對屬性爲readwrite的sections,.data和.textrw的sections不自動初始化,對.noinit屬性的sections(即用__no_init修飾的全局和靜態變量),定義重定位代碼區爲.textrw_init,定義重定位RAM區爲.textrw。
(6)
對全部的sections 和 blocks 在地址空間中所處的位置進行了配置。首先將只讀的異常向量表.intvec放置在_intvec_start地址處(前面已定義),而後將餘下的只讀sections以任意順序存放在ROM_region中,將可讀寫的sections和棧、堆這些blocks以任意順序存放在RAM_region中。