關(guān)于MCU上電啟動(dòng)應(yīng)用程序的準(zhǔn)備論述
嵌入式微控制器(Embedded Microcontroller Unit,EMCU),又稱單片機(jī),顧名思義,就是將整個(gè)計(jì)算機(jī)系統(tǒng)集成到一塊芯片中。嵌入式微控制器一般以某一種微處理器內(nèi)核為核心,芯片內(nèi)部集成R0M/EPRQM、RAM、總線、總線邏輯、定時(shí)/計(jì)數(shù)器、WatchDog、I/O、串行口、脈寬調(diào)制輸出、A/D、D/A、Flash、RAM、EEPROM等各種必要功能和外設(shè)。為適應(yīng)不同的應(yīng)用需求,一般一個(gè)系列的單片機(jī)具有多種衍生產(chǎn)品,每種衍生產(chǎn)品的處理器內(nèi)核都是一樣的,不同的是存儲(chǔ)器和外設(shè)的配置及封裝。這樣可以使單片機(jī)最大限度地和應(yīng)用需求相匹配,功能不多不少,從而減少功耗和成本。
MCU整體工作流程可總結(jié)如下:上電——》主時(shí)鐘起振——》啟動(dòng)代碼——》用戶程序(main函數(shù))。對(duì)于我們應(yīng)用開(kāi)發(fā)來(lái)說(shuō),大部分工作重點(diǎn)是在應(yīng)用程序編寫這塊。特別是高級(jí)MCU的出現(xiàn),如ARM系列的STM32、LPC等32位MCU,以及芯片原廠的完善底層代碼,啟動(dòng)代碼已經(jīng)固化在芯片內(nèi)部flash(稱為BootLoader),或者已經(jīng)提供完整的匯編啟動(dòng)源碼。因此,啟動(dòng)過(guò)程這塊,我們比較陌生,但基本的原理還需了解,不排除面試或者使用到實(shí)時(shí)系統(tǒng)(RTOS)時(shí)需要修改啟動(dòng)匯編代碼。
MCU上電(復(fù)位)時(shí),從固定的地址啟動(dòng),一般是地址0x00000000,如ARM7;個(gè)別特殊的如STM32默認(rèn)啟動(dòng)地址為0x8000000(flash區(qū)啟動(dòng))。啟動(dòng)過(guò)程主要完成兩部分工作,一個(gè)是硬件執(zhí)行環(huán)境,如中斷向量表、寄存器、看門狗等,另一個(gè)是軟件環(huán)境,如C庫(kù)環(huán)境、ZI(未初始化的內(nèi)存變量)等。
一、硬件環(huán)境工作
1.初始時(shí)鐘
初始化內(nèi)核時(shí)鐘,主時(shí)鐘,各個(gè)外設(shè)的時(shí)鐘。
2.關(guān)閉看門狗
看門狗是用來(lái)監(jiān)控應(yīng)用程序的異常跑飛而復(fù)位CPU,在初始化階段,由于沒(méi)有“喂狗”這一動(dòng)作,有可能導(dǎo)致CPU不斷復(fù)位,因此,首先會(huì)關(guān)閉看門狗,初始化完,再開(kāi)啟。
3.建立中斷向量表
中斷向量表,中斷源的識(shí)別標(biāo)志,可用來(lái)形成相應(yīng)的中斷服務(wù)程序的入口地址,或者中斷服務(wù)程序入口地址的偏移量和段基值。CPU利用中斷向量表轉(zhuǎn)入中斷服務(wù)程序處理相關(guān)事務(wù)。
4.初始化堆棧寄存器
堆棧的作用一個(gè)就是保存現(xiàn)場(chǎng)(上下文),如函數(shù)調(diào)用或者中斷發(fā)送時(shí),將當(dāng)前執(zhí)行地址壓棧,調(diào)用完成再返回此處執(zhí)行程序。另一個(gè)作用就是保存參數(shù),如臨時(shí)變量。因此,在啟動(dòng)階段需初始化堆棧寄存器、堆棧的大小、起始地址等。
5.內(nèi)存初始化
選擇內(nèi)部或者外部RAM。
二、軟件環(huán)境工作
1.把RO,RW從它們的加載域復(fù)制到它們的運(yùn)行域中去。
2.初始化(清零)ZI域。
3.初始化堆棧指針
4.初始化C庫(kù)環(huán)境
包括C庫(kù)所需的內(nèi)存空間、程序執(zhí)行所需資源、C庫(kù)初始化。
三、Cortex M3啟動(dòng)
CortexM3有3種啟動(dòng)方式
1、 BOOT1=1 BOOT0=1 ,中斷向量表定位于SRAM區(qū),即起始地址為0x2000000,同時(shí)復(fù)位后PC指針位于0x2000000處。
2、 BOOT1=x BOOT0=0,中斷向量表定位于FLASH區(qū),即起始地址為0x8000000,同時(shí)復(fù)位后PC指針位于0x8000000處。
3、 BOOT1=0 BOOT0=1 ,中斷向量表定位于內(nèi)置Bootloader區(qū),此時(shí)可通過(guò)串口下載程序的二進(jìn)制文件到flash區(qū)。
而Cortex-M3內(nèi)核規(guī)定,起始地址必須存放堆頂指針,而第二個(gè)地址則必須存放復(fù)位中斷入口向量地址,這樣在Cortex-M3內(nèi)核復(fù)位后,會(huì)自動(dòng)從起始地址的下一個(gè)32位空間取出復(fù)位中斷入口向量,跳轉(zhuǎn)執(zhí)行復(fù)位中斷服務(wù)程序。對(duì)比ARM7/ARM9內(nèi)核,Cortex-M3內(nèi)核則是固定了中斷向量表的位置而起始地址是可變化的。即是對(duì)于flash啟動(dòng)來(lái)說(shuō)(正常工作也是flash啟動(dòng)),0x8000000地址存放的是棧頂?shù)刂穇_initial_sp,0x8000004地址存放的是復(fù)位中斷向量Reset_Handler入口地址(STM32使用32位總線,存儲(chǔ)空間為4字節(jié)對(duì)齊);在編寫多段程序時(shí),偏移地址空間需注意,如編寫一個(gè)BootLoader,從BootLoader到應(yīng)用程序段的相互跳轉(zhuǎn)。