1. 前言
書接上文《ARM_Cortex-M0 DesignStart系列--3rtl仿真過程的詳細分析》,本文基于hello這個case,對Cortex M0的啟動過程做一個詳細的分析,其實整個ARM Cortex M系列的啟動的過程都是很相似的,這對我們理解SoC的啟動過程會很有幫助。
2. Cortex-M0 啟動流程
ARM Cortex-M架構芯片一般帶有片上閃存(flash)。ARM Cortex-M手冊規定在片上閃存(flash)起始地址處需要有一個有效的中斷向量表。芯片上電或復位(會觸發reset_Handler中斷程序)后,cpu首先從中斷向量表中讀出棧指針(MSP)和入口函數地址(復位向量,即程序執行的起始位置)。將棧指針和入口函數地址載入棧指針(cm0_msp)寄存器和尋址寄存器(cm0_pc)后,cpu會從復位向量 (一般是ROM/FLASH)開始執行程序。
2.1 復位序列:
根據上文的描述,復位順序大致如下圖(復位序列)所示:
2.2中斷向量表:
2.2.1 中斷向量表的定義:
上文中提到的中斷向量表(向量表在以后還可以轉移到其它位置),那么什么叫中斷向量表呢?把系統中所有的中斷類型碼(中斷號)及其對應的中斷處理函數按一定的規律存放在一個區域內,這個存儲區域就叫中斷向量表。
如下圖所示,在CM0中,在地址0提供的是MSP的初始值,然后緊跟著的是復位向量。向量表中的數值是32位的地址,不是跳轉指令。向量表的復位向量指向復位后應執行的第一條指令。
2.2.2中斷向量表格式
中斷向量表每一條目為一個32bit的地址。每一個地址對應一個中斷函數的地址(第一個條目除外)。除了第一個條目以外,所有地址的目標都為尋址寄存器(PC)。當相應中斷觸發時,ARM Cortex-M硬件會自動把中斷向量表中相應的中斷函數地址裝載入尋址寄存器(PC)然后開始執行中斷函數。如上所述,前16位(從MSP初始值->SysTick向量)為ARM保留的系統中斷向量,建議大家熟記。之后的中斷為芯片自定義的外部中斷向量,可以在使用時查詢手冊或者廠商提供的驅動程序。
2.2.3 本項目中的中斷向量表
下面的兩副截圖是我從cm0_designstart的啟動文件startup_CMSDK_CM0.s中的截圖,跟上面的圖示解釋是一致的,只是增加了一些外部中斷向量。
通常中斷向量表會放在啟動文件中,那么什么是啟動文件呢?顧名思義,就是mcu上電啟動后要開始執行其中的代碼(當然是編譯后的代碼,或者機器碼指令)。要知道,我們對單片機燒錄程序后,程序是存在NOR FLASH(即NOR閃存,通常用于存儲程序,NAND 閃存通常用于存儲數據)。啟動文件是使用匯編語言編寫的,在堆棧建立之后才可以運行C代碼,因為C函數調用需要把參數函數返回地址入棧,堆棧沒有建立不能運行C代碼。啟動文件主要完成以下工作:1. 初始化堆棧指針MSP和程序指針PC;2.初始化中斷向量表;3.定義Reset_Handler子程序,4.初始化中斷服務程序;5. 初始化用戶堆棧。關于啟動文件的更多細節,可以參考下圖中的code。
2.3程序存儲器和Bootloader
Cortex-M0的程序存儲器,一般使用片上Flash,但是程序也可以存儲在外部或者使用其他類型的存儲器(如外部SPI Flash、EEPROM等)。我們一開始就講了,當CPU從復位中啟動時,會首先訪問0地址的向量表,從而取得MSP的初始值和復位向量,然后從復位向量開始執行程序。但要保證系統正常工作,系統中需要有合法的向量表和合法的程序存儲器,這樣CPU才不會執行惡意軟件代碼。
關于向量表我們前面已經講過了,而程序存儲器(也就是Flash存儲器,因為程序一般存放在Flash中)一般是從地址0開始的。但是,在用戶編程以前,市面上MCU產品的Flash存儲器中可能沒有任何程序。
為了保證CPU可以正確的啟動,有些基于Cortex-M的MCU含有一個bootloader,bootloader是位于MCU芯片上的一小段代碼(程序),bootloader會在CPU上電后執行并跳轉,并且如果Flash存儲器已經編程的話,它會跳轉到Flash中的用戶程序執行。Bootloader是由芯片供應商預先編程,有時它位于片上Flash存儲器并且與用戶程序是分開的(這樣用戶更新程序也不會影響到Bootloader),而更多的時候它是位于和可編程程序存儲器相互獨立的ROM中。
上電以后,CPU會執行bootloader程序,bootloader 主要是給系統一個機會,在上電后是從外部接收程序更新到系統內的flash,然后再執行,其實還是直接執行系統內Flash內的程序。
當然,即使沒有bootloader,即使Flash存儲器中缺少合法的程序映像,debugger也可以通過我們上文講解的SWD接口連接到CPU并重新編程Flash存儲器。
說到這里,又是中斷向量表,又是啟動文件,又是bootloader,是不是有點暈菜的感覺?不過你千萬別犯迷糊,你再看看我們之前的一篇文章《ARM_Cortex-M0 DesignStart系列--3rtl仿真過程的詳細分析》中bootloader.o以及bootloader.lst是怎么產生的,你就明白怎么回事了。下面是反匯編bootloader.lst的截圖。結合下面的截圖以及我們上面的分析,就應該就可以很清楚其中的過程了。
2.4啟動過程的波形分析
2.4.1 AHB協議簡單介紹
由于后面啟動過程的波形分析是基于AHB總線的,多少需要一些AHB協議的基礎,當然了這并不復雜。我從協議里面截了幾張圖,大家看一下就很清楚了。
2.4.2 啟動波形分析
下面是,基于hello這個case的仿真波形,我們這里重點關注復位以后啟動部分的波形。有了上面大量的分析和鋪墊,到這里感覺反而輕松了。大家將下圖中的波形跟bootloader.lst文件做一下對照就很容易理解了。下圖中值得一提的是,從地址4讀出的復位向量是’h199,而程序執行的起始位置是’h198。原因是,程序執行的真正起始位置是’h198,但是在將這個地址放到復位向量處時,將最低位置1,以表示Thumb代碼,即CM0是在Thumb狀態下執行的,僅此而已。
今天暫時先寫到這里了,我們后續不見不散。
-
ARM
+關注
關注
134文章
9057瀏覽量
366873 -
Cortex-M
+關注
關注
2文章
227瀏覽量
29732 -
DesignStart
+關注
關注
1文章
7瀏覽量
6026
發布評論請先 登錄
相關推薦
評論