前言
開發一款芯片,首先我們需要確定制造它想要實現的目的,也就是想要實現的功能,以及功能與功能間溝通的接口;這也就是我們常說的架構;
當架構確定好后,下一步就是確定這些功能與接口的實現執行方式;
這些功能與接口的具體實現流程就是芯片的核心,所以我們將這些具體實現流程稱之為芯片的內核;
STM32系列芯片采用ARM架構下的cortex-M系列內核來具體執行和實現芯片的功能;
1 ARM架構
ARM(Advanced RISC Machine)高級 精簡指令集 處理器,簡稱ARM架構;也是ARM公司起名的由來;為主流芯片架構之一;
CPU架構 | 代表芯片 | 指令集架構 | 功能 |
ARM | ARM | RISC指令集 | 主要用於移動,嵌入式領域;邏輯門少,發熱低,so功耗低;搭配哈佛存儲結構使用; |
X86 | intel,AMD | CISC指令集 | 主要是用在電腦CPU上,性能高,速度快;搭配馮諾依曼存儲結構使用; |
MIPS | 龍芯 | RISC指令集 | 用於部分音頻處理器和網絡設備上,市場極小;后來 |
ARM公司作為IP核提供商,專注於ARM處理器的IP核出售業務;在推出ARM11內核之后,之后推出的內核分為三類,分別如下
1.1 cortex-A系列內核:application系列,專注於高端消費類電子,諸如高通,MTK等的手機芯片;
1.2 cortex-R系列內核:real-time系列,專注於要求實時性的領域,諸如航空航天之類的;
1.3 cortex-M系列內核:micro-controller系列,專注於中低端的嵌入式產品,也就是本文接下來要說的系列了;
2 CPU的存儲結構
cortex-m3為cortex系列推出的第一個內核,發布於2005年;本文就以cortex-m3舉例把;
cortex-m3為32位處理器內核,支持小端模式(常用)和大端模式(不建議);有些指令只使用小端模式且不可更改;
endian模式 | 功能 | data[31:0]=0x87654321, 地址:0x10,0x11,0x12,0x13 |
小端模式 | 數據的低位存放在地址低位中 | data[7:0]存放在0x10中 |
大端模式 | 數據的高位存放在地址低位中 | data[31:24]存放在0x10中 |
cortex-m3的數據總線,指令總線,寄存器都是32位的,采用哈佛結構總線;
那么什么是哈佛總線結構呢?既然遇到了,就在這里補充一下溫馨小提示把;
2.1 CPU的存儲結構
2.1.1 哈佛結構:指令寄存器和數據寄存器存放在不同的內存里,需要分別尋址的CPU結構;
1)代碼編譯之后相當於指令,這些指令通常會固定存放在單片機的rom的寄存器里,使用指令總線來順序尋址 指令寄存器;
相當於指令寄存器全部划分在一塊固定的區域,指令總線和數據總線同時操作該區域的指令寄存器;
2)單片機執行過程中的數據存放在ram的寄存器里,使用地址總線對需要操作的數據寄存器進行尋址,然后使用數據總線傳遞數據;
相當於數據寄存器全部划分在一塊固定的區域,地址總線和數據總線可以同時操作該區域的數據寄存器;
優勢:代碼安全性較高,效率較高;
2.1.2 馮諾依曼結構:指令寄存器和數據寄存器存放在相同的內存里,不需要分別尋址的CPU結構;
代碼A編譯之后存放在內存中,該代碼A使用的數據A存放在代碼A地址后;新的代碼B繼續放在數據A之后,然后再存放數據B...
指令寄存器的存儲區域和數據寄存器的存儲區域混在一塊區域,也就是說指令總線和地址總線是相同的總線,需要分時復用;
馮諾依曼是早期的cpu結構,執行的速度受存儲器速度的限制;優勢的話。。。可能在存儲器速度很快的情況下很快把。。。
2.2 ARM存儲器地址映射
ARM的地址總線為32bits;所以存儲器的尋址空間為4G;尋址內存單位約定俗成為byte;
CM3存儲器地址映射在所有的cortex-m3內核的芯片上都是相同的,方便了不同芯片程序的裁剪和移植;
地址 | 大小 | 類型 | 功能 |
0x0000 0000-0x1fff ffff | 512M bytes | ROM | 代碼存儲區 |
0x2000 0000-0x3fff ffff | 512M bytes | SRAM | |
0x4000 0000-0x5fff ffff | 512M bytes | 用於存儲片上外設 | |
0x6000 0000-0x9fff ffff | 1G bytes | 外部RAM | 擴展外部存儲器的尋址 |
0xa000 0000-0xdfff ffff | 1G bytes | 擴展片外的外設 | |
0xe000 0000-0xffff ffff | 512M bytes | 內核相關寄存器,片上調試組件等,AHB總線,APB總線 |
AHB總線只用於CM3內部的AHB外設,如NVIC,FPB,DWT和ITM;
APB總線既用於CM3內部的APB外設,也用於片外擴展的外設;
3 cortex-M3內核
3.1 cortex框圖
cortex-m3只使用thumb-2指令集;thumb-2指令集包含32bit指令和16bit指令;thumb指令集只包含16bit指令;
對於M3內核,橙色是內核主要的功能執行框圖,紫色為調試組件,綠色為存儲保護單元,藍色為內部總線與外設的接口;
下面的框圖應該有各種總線;I-code總線負責指令,D-code總線負責查表等操作;按最佳執行速度進行優化;
3.1.2 CMSIS 軟件接口標准
CMSIS全稱Cortex-Mx software interface standard,是API接口標准;以下為STM32芯片的core cm3內核的代碼架構示意圖;
Libraries目錄下內核代碼,將底層寄存器操作封裝成API函數,函數格式符合CMSIS標准的格式;
3.2 register bank寄存器
CM3內核擁有一個寄存器組,該寄存器組內共有16個寄存器;以及一些特殊功能寄存器;
3.2.1 寄存器組
寄存器 | 寄存器名稱 | 可訪問指令 | 功能 |
R0,...,R7 | 通用寄存器 | thumb, thumb-2 | 數據操作,Low registers復位后初始值不定 |
R8,...,R12 | 通用寄存器 | thumb-2 | 數據操作,High registers復位后初始值不定 |
R13 | 主堆棧指針 MSP | thumb-2 | main_SP,復位后缺省使用的堆棧指針,用於操作系統內核以及異常處理例程(包括中斷服務例程); |
進程堆棧指針 PSP | thumb-2 | process_SP,由用戶的應用程序代碼使用(用戶代碼不處於中斷時); | |
R13寄存器的最低兩位被硬件置0,所以內存的地址總是4字節對齊;堆棧指針的切換由硬件自動完成; | |||
R14 | 連接寄存器 LR | thumb-2 | 調用子函數時,用來存儲主調函數的地址;多級調用時會將主調函數的地址存到堆棧中; |
R15 | 程序計數器 PC | thumb-2 | 存儲當前程序運行到的程序地址。如果修改它的值,就能改變程序的執行流; |
3.2.2 特殊功能寄存器
特殊功能寄存器組沒有存儲器地址,只能使用MRS(讀)和MSR(寫)指令訪問;
寄存器 | 寄存器名稱 | 功能 |
|||
xPSR
|
程序狀態字
寄存器組
|
APSR
|
APSR 應用程序狀態寄存器:記錄 ALU 標志,
IPSR 中斷號狀態寄存器:當前正服務的中斷號,
EPSR 執行狀態寄存器:程序執行狀態
|
||
IPSR
|
|||||
EPSR | |||||
PRIMASK
|
中斷屏蔽
寄存器組
|
1bit | 除能所有中斷,NMI和hard fault除外; 缺省為0,不除能; |
目的:讓實時性要求高的任務能夠順利執行 |
|
FAULTMASK
|
1bit | 除能所有fault,NMI不可屏蔽中斷除外; 缺省為0,不除能; |
|||
BASEPRI
|
9bit
|
除能所有優先級不高於某個閾值的所有中斷
|
|||
CONTROL
|
控制
寄存器
|
CONTORL[1]
|
1bit |
為0時,都使用MSP堆棧指針;為缺省值;
為1時,thread使用PSP堆棧指針,
handler使用MSP指針;
|
handler模式時,為0,都是使用MSP堆棧, thread模式時,為0或1,分別復用為MSP/PSP堆棧; |
CONTROL[0] |
1bit
|
0:thread模式處於privileged特權級權限; 1:thread模式處於user級權限 |
當模式處於thread時,使用CONTROL[0]來配置權限 |
3.3內核模式
操作模式 | 操作權限 | 操作程序 | 使用的堆棧指針 | 操作配置 |
thread 線程模式 | 特權級,用戶級 | 普通應用程序的操作模式 | PSP/MSP | 根據操作模式和操作權限配置CONTROL[1:0]來修改狀態 |
handler 處理模式 | 特權級 | 異常服務程序的操作模式 | MSP |

編號 | 類型 | 優先級 | NVIC表偏移地址 | 功能 |
0 |
NA
|
NA
|
0x00
|
表示沒有異常在運行,當前地址初始值為MSP復位后的初始值;
|
1 | Reset_Handler | -3(最高) | 0x04 | 上電復位 |
2 | NMI | -2 | 0x08 | 不可屏蔽中斷(外部NMI引腳輸入) |
3 | hard fault | -1 | 0x0C | 使能所有被除能的fault中斷為hard fault |
4 | MemManage fault | 可編程 | 0x10 |
存儲器管理fault,MPU 訪問犯規以及訪問非法位置
|
5 |
總線 fault
|
0x14 |
總線錯誤(預取流產(Abort)或數據流產)
|
|
6 |
用法(usage)
Fault
|
0x18 |
程序錯誤的異常 ,通常為指令無效或非法狀態轉換
|
|
7-10 |
保留
|
NA
|
0x1C-0x28
|
NA
|
11 |
SVCall
|
可編程
|
0x2C
|
系統服務調用
|
12 |
調試監視器
|
0x30 |
調試監視器 (斷點,數據觀察點,或者是外部調試請求)
|
|
13 |
保留
|
NA
|
0x34
|
NA
|
14 |
PendSV
|
可編程 | 0x38 |
為系統設備而設的“可懸掛請求”(pendable request)
用來實現中斷嵌套時,應把PendSV的優先級編程為最低;
|
15 |
SysTick
|
0x3C |
系統滴答定時器
|
|
16 |
IRQ #0
|
0x40 |
外中斷#0
|
|
17 |
IRQ #1
|
0x44 |
外中斷#1
|
|
... | ... | ... | ... | ... |
255 |
IRQ #239
|
可編程 | 0x3FF |
外中斷#239
|
CM3支持11個系統異常中斷,5個保留類型,240個外部中斷;具體使用看芯片廠商的配置; | ||||
Cortex‐M3 在進入異常服務例程時,自動壓棧了 R0‐R3, R12, LR, PSR 和 PC,並且在返回時自動彈出它們
|