嵌入式開發(fā)底層——KEIL中啟動文件詳解(匯編語言)

概述

在嵌入式系統(tǒng)中,啟動文件是整個系統(tǒng)非常關(guān)鍵的部分世分,它會進行一些底層的初始化,構(gòu)建程序運行必要的環(huán)境缀辩,比如堆棧初始化臭埋,變量初始化等。如果啟動文件出現(xiàn)錯誤臀玄,則整個系統(tǒng)就跑不起來瓢阴,因此研究啟動文件非常必要。

在keil中健无,啟動文件由匯編代碼編寫荣恐,一般命名為startup_xxx.s,xxx為支持的某種芯片,比如可以是lpc15xx(NXP的LPC15xx系列)叠穆、MK60D10(飛思卡爾)少漆、stm32f10x(意法半導(dǎo)體stm32f10x系列)等Cortext-M0/M3/M4內(nèi)核芯片。它們的代碼格式非常相近硼被,根據(jù)啟動文件代碼由上到下的編寫順序.

可以將其分為以下5個典型部分:
  1. 堆検舅穑空間定義;
  2. 存放中斷向量表嚷硫;
  3. 復(fù)位中斷函數(shù)(Reset_Handler)检访;
  4. 其它中斷異常服務(wù)函數(shù),以及弱[WEAK]聲明仔掸;
  5. 將堆棧地址傳遞給庫函數(shù)脆贵,利用庫函數(shù)初始化堆棧,和庫函數(shù)自身初始化嘉汰。
5個部分具體說明如下:

1 堆椀べ鳎空間定義

如下圖所示,定義了棧大小Stack_Size = 0X200鞋怀,即512字節(jié)双泪;堆大小Heap_Size = 0X100,256字節(jié)。還定義了三個標號:__initial_sp(棧頂)密似、__heap_base(堆起始地址)__heap_limit(堆終止地址)焙矛,它們的空間由SPACE關(guān)鍵字來申請,并記作Stack_MemHeap_Mem残腌。

堆棧大小定義

通過這些我們可以很容易的知道堆棧的大小村斟,但是它們的絕對地址或者說基地址僅僅從這里是得不到的。編譯器編譯完工程后抛猫,根據(jù)生成.bss段(比如未初始化的全局變量)和.data段(比如初始化的全局變量)的大小以及RAM的起始地址蟆盹,來計算堆棧的基地址。

舉個例子:

一個芯片的RAM起始地址為0x0200_0000闺金,RAM大小為0x500字節(jié)逾滥,程序編譯后.bss段為0x100個字節(jié),.data段為0x100個字節(jié)败匹。堆棧大小定義如上圖寨昙。則:

  • A:堆起始地址__heap_base==Heap_Mem==0x0200_0200;

  • B:堆終止地址即棧底__heap_limit==Stack_Mem==0x0200_0300掀亩;

  • C:棧頂?shù)刂?code>__initial_sp==0x0200_0500(棧是向下生長舔哪,棧頂處于RAM最大地址處)。

其實槽棍,我可以在.map文件中查看堆棧的大小和基地址捉蚤,如下圖所示:

.map文件

2 存放中斷向量表

在啟動代碼中抬驴,會見到許多由DCD申請空間存放的一個個函數(shù)入口,即中斷向量表缆巧,如下圖所示怎爵,只列出了部分。

中斷向量表

關(guān)鍵字DCD代表申請一個字的空間盅蝗,后面的函數(shù)名即為中斷服務(wù)函數(shù)入口地址。另外中斷向量表一般存放在Flash0地址姆蘸。

另外墩莫,對于NXP微控制器,均實現(xiàn)了芯片的加密逞敷,加密的設(shè)置在向量表的結(jié)尾處狂秦,具體地址為0x02FC處。通過在此地址存放不同的值實現(xiàn)是否加密或者加密的等級推捐。加密分為三個等級裂问,CRP1:0x12345678;CRP2:0x87654321牛柒;CRP3:0x43218765堪簿。至于每個等級的具體說明請參考芯片用戶手冊。下面說一下加密步驟皮壁,以CRP1為例:

CRP加密

首先將上圖中0xFFFFFFFF椭更,修改為0x12345678。
其次蛾魄,圖中IF :LNOT::DEF:NOCRP表示如果沒有定義宏NOCRP則執(zhí)行下面的代碼虑瀑,那么必須保證匯編中沒有定義NOCRP宏。即保證下圖中Define:一欄中沒有定義NOCRP即可滴须。

是否加密在這里設(shè)置

3 復(fù)位中斷函數(shù)(Reset_Handler)

程序上電后舌狗,首先加載SP和PC,ARM規(guī)定從0地址處加載SP扔水,從偏移為4的地址(0x00000004)處加載PC痛侍。然后將程序控制權(quán)交給程序。我們知道0地址處存放__initial_sp铭污,0x00000004地址處存放Reset_Handler恋日,加載PC后,程序跳轉(zhuǎn)到Reset_Handler開始運行嘹狞。Reset_Handler函數(shù)體如下圖所示:

復(fù)位中斷

首先調(diào)用SystemInit函數(shù)來初始化系統(tǒng)的各種時鐘岂膳,然后調(diào)用__main函數(shù)(由KEIL微庫或者C庫實現(xiàn)),在__main函數(shù)中:.data段數(shù)據(jù)的初始化->.bss段變量清零->設(shè)置堆棧指針->庫函數(shù)初始化(比如常用的malloc函數(shù))->如果必要會設(shè)置main函數(shù)的argc和argv兩個參數(shù)->調(diào)用用戶main函數(shù)->退出磅网。

4 其它中斷異常服務(wù)函數(shù)谈截,以及弱[WEAK]聲明

WEAK弱聲明

如上圖所示,這里的中斷服務(wù)函數(shù)是弱聲明的(由[WEAK]關(guān)鍵字標注)。所謂弱聲明簸喂,即:如果用戶定義了相同的函數(shù)則此處函數(shù)失效而使用用戶定義的中斷服務(wù)函數(shù)毙死。這樣是為了防止用戶使能了中斷而沒有中斷服務(wù)函數(shù),從而造成程序崩潰喻鳄。假設(shè)使能了中斷扼倘,而用戶又沒有定義中斷服務(wù)函數(shù)則會進入默認中斷,如下圖所示除呵,默認中斷為死循環(huán)(死循環(huán)與程序崩潰不是一個概念)再菊。

默認中斷

5 將堆棧地址傳遞給庫函數(shù)

第三步驟中,調(diào)用__main函數(shù)颜曾,然后__main調(diào)用庫函數(shù)初始化堆棧纠拔,但庫函數(shù)并不知道堆棧的大小,因此我們需要告訴它泛豪,具體做法就是傳遞參數(shù)或聲明標號稠诲。

下圖為具體做法,可以看到第一行為:

IF      :DEF:__MICROLIB

是條件編譯選項诡曙,如果定義__MICROLIB臀叙,則編譯圖中紅線上面部分,否則編譯紅線下面部分岗仑。那么就分2種情況匹耕。

微庫選擇

2種情況的選擇可以如下實現(xiàn):
如果勾選【Options for Target】->【Target】->【Use MicroLIB】,如下圖所示。即使用微庫荠雕,則__MICROLIB會被定義稳其,編譯器編譯紅線以上代碼。用EXPORT聲明 __initial_sp炸卑、__heap_base__heap_limit既鞠。

微庫選擇

如果不勾選【Use MicroLIB】,則缺省使用KEIL C庫盖文,上圖紅線以下會參與編譯嘱蛋,KEIL C庫函數(shù)會調(diào)用__user_initial_stackheap,通過R0~R3將堆棧以參數(shù)形式傳遞給KEIL C庫五续。

參考:http://www.cnblogs.com/mddblog/p/4920063.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末洒敏,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子疙驾,更是在濱河造成了極大的恐慌凶伙,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,599評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件它碎,死亡現(xiàn)場離奇詭異函荣,居然都是意外死亡显押,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,629評論 3 385
  • 文/潘曉璐 我一進店門傻挂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來乘碑,“玉大人,你說我怎么就攤上這事金拒∈薹簦” “怎么了?”我有些...
    開封第一講書人閱讀 158,084評論 0 348
  • 文/不壞的土叔 我叫張陵绪抛,是天一觀的道長轿衔。 經(jīng)常有香客問我,道長睦疫,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,708評論 1 284
  • 正文 為了忘掉前任鞭呕,我火速辦了婚禮蛤育,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘葫松。我一直安慰自己瓦糕,他們只是感情好,可當我...
    茶點故事閱讀 65,813評論 6 386
  • 文/花漫 我一把揭開白布腋么。 她就那樣靜靜地躺著咕娄,像睡著了一般。 火紅的嫁衣襯著肌膚如雪珊擂。 梳的紋絲不亂的頭發(fā)上圣勒,一...
    開封第一講書人閱讀 50,021評論 1 291
  • 那天,我揣著相機與錄音摧扇,去河邊找鬼圣贸。 笑死,一個胖子當著我的面吹牛扛稽,可吹牛的內(nèi)容都是我干的吁峻。 我是一名探鬼主播,決...
    沈念sama閱讀 39,120評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼在张,長吁一口氣:“原來是場噩夢啊……” “哼用含!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起帮匾,我...
    開封第一講書人閱讀 37,866評論 0 268
  • 序言:老撾萬榮一對情侶失蹤啄骇,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后辟狈,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體肠缔,經(jīng)...
    沈念sama閱讀 44,308評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡夏跷,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,633評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了明未。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片槽华。...
    茶點故事閱讀 38,768評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖趟妥,靈堂內(nèi)的尸體忽然破棺而出猫态,到底是詐尸還是另有隱情,我是刑警寧澤披摄,帶...
    沈念sama閱讀 34,461評論 4 333
  • 正文 年R本政府宣布亲雪,位于F島的核電站,受9級特大地震影響疚膊,放射性物質(zhì)發(fā)生泄漏义辕。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,094評論 3 317
  • 文/蒙蒙 一寓盗、第九天 我趴在偏房一處隱蔽的房頂上張望灌砖。 院中可真熱鬧,春花似錦傀蚌、人聲如沸智末。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,850評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至爷狈,卻和暖如春侍芝,著一層夾襖步出監(jiān)牢的瞬間眯分,已是汗流浹背荤胁。 一陣腳步聲響...
    開封第一講書人閱讀 32,082評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留艺谆,地道東北人酱虎。 一個月前我還...
    沈念sama閱讀 46,571評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像擂涛,于是被迫代替她去往敵國和親读串。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,666評論 2 350

推薦閱讀更多精彩內(nèi)容