1. 程式人生 > >STM32F系列ARM Cortex-M3核微控制器基礎之儲存系統一

STM32F系列ARM Cortex-M3核微控制器基礎之儲存系統一

STM32F系列ARM Cortex-M3核微控制器基礎之儲存系統 線索一:CM3的儲存器系統對映是預定義的,並且規定好了哪個位置使用哪條匯流排。         CM3只有一個單一固定的儲存器對映。CM3的地址空間是4GB,程式可以在 程式碼區內部SRAM區以及 外部RAM 區執行。                  儲存空間的一些位置用於除錯元件等私有外設,這些段被稱為私有外設區。私有外設區的元件包括:快閃記憶體地址過載及斷點單元,資料觀察點單元,指令跟蹤單元,嵌入式跟蹤巨集單元,跟蹤埠介面單元,ROM表。私有外設區包含外部私有外設區和內部私有外設區。私有外設匯流排有兩條:一是AHB私有外設匯流排,只用於CM3內部的AHB外設,他們是:NVIC,FPB,DWT和ITM。二是APB私有外設匯流排,既用於CM3內部的APB裝置,也用於外部裝置(外部是相較於核心而言)。CM3允許製造商新增APB裝置到APB私有總線上。

NVIC所處的區域叫做系統控制空間(SCS)。



線索二:CM3匯流排 I-Code匯流排:I-Code匯流排是一條基於AHB-Lite匯流排協議的32位匯流排,負責在0x0000 0000-0x1FFF FFFF之間的取指操作。取指以字的長度執行,即使是對於16位指令也是如此,因此 CPU核心可以一次取出兩條16位Thumb指令。 D-Code匯流排:D-Code匯流排是一條基於AHB-Lite匯流排協議的32位匯流排,負責在0x0000 0000-0x1FFF FFFF之間的資料訪問操作。儘管CM3支援非對齊訪問,但是總線上不會有非對齊的地址(處理器的匯流排介面會把非對齊的資料傳送都轉換成對齊的資料傳送)。
系統匯流排:系統匯流排是一條基於AHB-Lite匯流排協議的32位匯流排,負責在0x2000 0000-0xDFFF FFFF和0xE010 0000-0xFFFF FFFF之間的所有資料傳送(取值和資料訪問)。和D-Code匯流排一樣,所有的資料傳送都是對齊的。
外部私有外設匯流排:外部私有外設匯流排是一條基於APB匯流排協議的32位匯流排,負責在0xE004 0000-0xE00F FFFF之間的私有外設訪問。但是,由於APB儲存空間的一部分已經被TPIU、ETM以及ROM表用掉了,就只剩下0xE004 2000-0xE00F F000這個區間用於配接附加的私有外設。 除錯訪問埠匯流排:除錯訪問埠匯流排是一條基於增強型APB規格的32位匯流排,它專門用於掛接除錯介面(如SWJ-DP和SW-DP)。
問題一:系統上電後發生了什麼?

復位序列:在離開復位狀態後, CM3 做的第一件事就是讀取下列兩個 32 位整數的值:從地址 0x0000,0000 處取出 MSP 的初始值, 從地址 0x0000,0004 處取出 PC 的初始值——這個值是復位向量,LSB 必須是 1。然後從這個值所對應的地址處取指。這與傳統的 ARM 架構不同——其實也和絕大多數的其它微控制器不同。傳統的ARM 架構總是從 0 地址開始執行第一條指令。它們的 0 地址處總是一條跳轉指令。在 CM3中, 0 地址處提供 MSP 的初始值,然後就是向量表(向量表在以後還可以被移至其它位置)。向量表中的數值是 32 位的地址,而不是跳轉指令。向量表的第一個條目指向復位後應執行的第一條指令。


因為 CM3 使用的是向下生長的滿棧,所以 MSP 的初始值必須是堆疊記憶體的末地址加 1。堆疊區域在 0x20007C00‐0x20007FFF,MSP 的初始值就必須是0x20008000。CM3 是在 Thumb態下執行,所以向量表中的每個數值都必須把 LSB 置 1(也就是奇數)。圖中使用 0x101 來表達地址 0x100。當 0x100 處的指令得到執行後,就正式開始了程式的執行。在此之前初始化 MSP 是必需的,因為可能第 1 條指令還沒執行就會被 NMI 或是其它 fault 打斷。 MSP 初始化好後就已經為它們的服務例程準備好了堆疊。


我們從一個實際例程的反彙編程式碼來看看上述情況:

這段程式碼是復位handler

; Reset handler
Reset_Handler   PROC
                EXPORT  Reset_Handler             [WEAK]
                IMPORT  __main
                IMPORT  SystemInit
                LDR     R0, =SystemInit
                BLX     R0               
                LDR     R0, =__main
                BX      R0
                ENDP

這裡Reset handler = 0x0800 01D4,我們去檢視0x0000 0000處的情況:

0x00000000 0760      DCW      0x0760
0x00000002 2000      DCW      0x2000
0x00000004 01D5      DCW      0x01D5
0x00000006 0800      DCW      0x0800

記憶體0x0000 0004和0x0000 0006存放的是復位向量0x0800 01D5。由於CM3 是在 Thumb態下執行,所以向量表中的每個數值都必須把 LSB 置 1(也就是奇數),所以這裡的復位向量值比Reset Handler加了1。而0x0000 0000和0x0000 0002處存放的是0x2000 0760就是MSP的初始值。