標籤:微處理器 memory
一、啟動模式,決定向量表的位置
當CPU上電後,首先代碼區(Flash)應該從地址為0x00000000開始,而資料區(SRAM)應該從0x20000000開始,Cortex - M3 CPU總是通過代碼區獲得複位向量。STM32F10XXX微處理器中運用了特殊的機制使得STM32不僅可以通過Flash(主快閃記憶體和系統快閃記憶體)啟動,同時還可以從SRAM中啟動。
STM32 有下面3種啟動方式:
650) this.width=650;" alt="\"2016年05月06日" src="%5C" />
關於Main Flash/System Memory/SRAM 可以參見下面記憶體映射:
650) this.width=650;" alt="\"2016年05月06日" src="%5C" />
從可以看出 0x00000000 - 0x08000000 之間這128M空間是預留的,該區稱為Boot Memory Space(Aliased to Flash or systen memory depending on BOOT pins)。
(1)從Main Flash 啟動:Boot Space 是Main Flash 的別名。以0x08000000 對應的記憶體為例,則該塊記憶體既可以通過0x00000000 操作也可以通過0x08000000 操作,且都是操作的同一塊記憶體
(2)從System Memory啟動:Boot Space 是System Memory的別名。以0x1FFFFFF0對應的記憶體為例,則該塊記憶體既可以通過0x00000000 操作也可以通過0x1FFFFFF0操作,且都是操作的同一塊記憶體
(3)從SRAM 啟動:SRAM 只能通過0x20000000進行操作,與上述兩者不同 。從SRAM 啟動時,需要在應用程式初始化代碼中重新設定向量表的位置。
eg:void SystemInit (void)
{
......#ifdef VECT_TAB_SRAM
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */#elseSCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH.*/#endif
}
二、向量表解析
分析STM32的開機檔案startup_stm32f10x_hd.s(大容量)主要做了以下事情:
(1)設定初始堆棧指標(SP)
(2)設定初始程式計數器(PC)為複位向量,並在執行main函數前初始化系統時鐘
(3)設定向量表入口為例外狀況事件的入口地址
(4)複位之後處理器為線程模式,優先順序為特權級,堆棧設定為MSP主堆棧
650) this.width=650;" title="\"捕獲.PNG\"" src="%5C" alt="wKiom1daKlWSpQlnAACYE9q6i28575.png-wh_50" />
三、開機實際運行過程
通過模擬器模擬,發現開機後程式就直接跳轉到Reset_Handler,從.map檔案看Reset_Handler的地址是0x080003a5並不是0x08000000(因為此時是從Flash中啟動的,故應該是0x08000000)。那麼STM32是如何從0x08000000過渡到0x080003a5?
查看Cortex - M3權威指南中文版本中複位序列中相應的說明:
650) this.width=650;" alt="\"2016年05月06日" src="%5C" />
也就是說上電複位的時候,剛開始CPU的主動權還是掌握在CM3中。CM3執行了寄存器的初始化及取複位向量表並執行!
這個絕大多數單片機不同,傳統的ARM架構總是從0地址開始執行,並且0地址是有一條跳轉指令的。在CM3中0地址處存的是MSP的位置,這並不是執行指令只是一個資料表。
另外還有一個問題,如何進入到複位序列?
觸發STM32進入複位序列的有以下條件:
(1)System reset
(2)Power reset
(3)Backup domain reset
剛上電時就是通過Power reset 進入到複位序列!
STM32 開機流程分析