Cortex-M3基本知识点(手册)
cortex-M3內核簡單分析
1、cortex - M3內核:只是arm公司提供的一個內核
基于cortex - M3的MCU:包括內核+內存+外設等一些其他的器件。
2、cortex -M3架構的特點:
(1)處理器內核,數據路徑,寄存器,存儲器接口都是32位的。
(2)采用哈佛結構,數據總線和指令總線是獨立的,取指令和讀數據可以同時進行。
(3)支持大端模式和小端模式
3、寄存器R0-R12 通用寄存器, 一般16位的thumb指令能訪問R0-R7 ;
4、異常的概念:
凡是打斷程序執行的事件都被稱為異常。
5、CM3支持兩種操作模式:handler mode 和 thread mode
同時還是支持兩級特權操作: 特權級和用戶級
從用戶級切換到特權級唯一的途徑就是異常。
6、特權級線程模式和用戶級線程模式都可以觸發異常到特權級handler mode,并且會異常返回。
復位進入特權級線程模式,特權級線程模式通過修改控制寄存器進入到用戶級線程模式。
7、內建的嵌套中斷控制器
--*可嵌套中斷支持
當異常發生時,硬件會自動比較異常的優先級是否比當前的優先級高,如果必當前的優先級高就? 會服務新來的中斷,–立即強占
--*向量中斷支持
當中斷響應后,CM3會自動定位到一張向量表,并且根據中斷號從表中找出ISR的入口地址,跳轉過去執行。(節省時間延遲時間縮短)
--*動態優先級調整
軟件運行期間可以更改中斷的優先級,如果修改了當前的優先級,當前中斷是不會自己打斷自己的,從而沒有重入風險。
--*中斷延遲大大縮短
--*中斷可屏蔽
可以任意屏蔽中斷序號,也可以全部屏蔽。是為了讓時間關鍵的任務能在死線到來之前完成,而不被干擾。
8、存儲器映射
存儲器大小是4G,分成6個區間,Cortex-M3內部擁有一個總線基礎設施,在此基礎上,甚至允許這些區間之間“越權使用”。
9、指令流水線
取指令(F)–解碼(D)–執行(X)三級指令,
pc指向預取指令,pc地址與執行的地址相差8 (pc-8=x)
0x1000 mov (執行此處)
0x1004 sub (解碼此處)
0x1008 mul (pc指向此處)
0x100c dev
當發生指令跳轉時:
跳轉到目的地后用LR記錄返回地址,并且將當前的D、X,清空,如果預取指令再一周期將LR的值減去4
10、復位發生后指向默認的MSP,而PC的值是4,
11、UAL(統一匯編語言),但是仍然允許使用傳統的 Thumb 語法。不過有一項必須注意:如果
使用傳統的 Thumb 語法,有些指令會默認地更新 APSR,即使你沒有加上 S 后綴。如果使用
UAL 語法,則必須指定 S 后綴才會更新。
12、在UAL 下,你可以讓匯編器決定用哪個,也可以手工指定是用 16 位的還是 32 位的:
ADDS R0, #1 ;匯編器將為了節省空間而使用 16 位指令
ADDS.N R0, #1 ;指定使用 16 位指令(N=Narrow)
ADDS.W R0, #1 ;指定使用 32 位指令(W=Wide)
13、指令集
名字 功能
ADC 帶進位加法
ADD 加法
AND 按位與(原文為邏輯與,有誤——譯注)。這里的按位與和 C 的”&”功能相同
ASR 算術右移
BIC 按位清 0(把一個數跟另一個無符號數的反碼按位與)
CMN 負向比較(把一個數跟另一個數據的二進制補碼相比較)
CMP 比較(比較兩個數并且更新標志)
CPY 把一個寄存器的值拷貝到另一個寄存器中
EOR 近位異或
LSL 邏輯左移(如無其它說明,所有移位操作都可以一次移動多格——譯注)
LSR 邏輯右移
MOV 寄存器加載數據,既能用于寄存器間的傳輸,也能用于加載立即數
MUL 乘法
MVN 加載一個數的 NOT 值(取到邏輯反的值)
NEG 取二進制補碼
ORR 按位或(原文為邏輯或,有誤——譯注)
ROR 圓圈右移
SBC 帶借位的減法
SUB 減法
TST 測試(執行按位與操作,并且根據結果更新 Z)
REV 在一個 32 位寄存器中反轉字節序
REVH 把一個 32 位寄存器分成兩個 16 位數,在每個 16 位數中反轉字節序
REVSH 把一個 32 位寄存器的低 16 位半字進行字節反轉,然后帶符號擴展到 32 位
SXTB 帶符號擴展一個字節到 32 位
SXTH 帶符號擴展一個半字到 32 位
UXTB 無符號擴展一個字節到 32 位
UXTH 無符號擴展一個半字到 32 位
表 4.3? ? ? ?16 位轉移指令
名字 功能
B 無條件轉移
B 條件轉移
BL 轉移并連接。用于呼叫一個子程序,返回地址被存儲在 LR 中
BLX #im 使用立即數的 BLX 不要在 CM3 中使用
CBZ 比較,如果結果為 0 就轉移(只能跳到后面的指令——譯注)
CBNZ 比較,如果結果非 0 就轉移(只能跳到后面的指令——譯注)
T If‐Then
表 4.4? ? ? ?16 位存儲器數據傳送指令
名字 功能
LDR 從存儲器中加載字到一個寄存器中
LDRH 從存儲器中加載半字到一個寄存器中
LDRB 從存儲器中加載字節到一個寄存器中
LDRSH 從存儲器中加載半字,再經過帶符號擴展后存儲一個寄存器中
LDRSB 從存儲器中加載字節,再經過帶符號擴展后存儲一個寄存器中
STR 把一個寄存器按字存儲到存儲器中
STRH 把一個寄存器存器的低半字存儲到存儲器中
STRB 把一個寄存器的低字節存儲到存儲器中
LDMIA 加載多個字,并且在加載后自增基址寄存器
STMIA 加載多個字,并且在加載后自增基址寄存器
PUSH 壓入多個寄存器到棧中
POP 從棧中彈出多個值到寄存器中
16 數據傳送指令沒有任何新內容,因為它們是 Thumb 指令,在 v4T 時就已經定格了——譯注
表 4.5? ? ? ?其它 16 位指令
名字 功能
SVC 系統服務調用
BKPT 斷點指令。如果調試被使能,則進入調試狀態(停機)。或者如果調試監視器異常被
使能,則調用一個調試異常,否則調用一個 fault 異常
NOP 無操作
CPSIE 使能 PRIMASK(CPSIE i)/ FAULTMASK(CPSIE f)——清 0 相應的位
CPSID 除能 PRIMASK(CPSID i)/ FAULTMASK(CPSID f)——置位相應的位
表 4.6? ? ? ?32 位數據操作指令
名字 功能
ADC 帶進位加法
ADD 加法
ADDW 寬加法(可以加 12 位立即數)
AND 按位與(原文是邏輯與,有誤——譯注)
ASR 算術右移
BIC 位清零(把一個數按位取反后,與另一個數邏輯與)
BFC 位段清零
BFI 位段插入
CMN 負向比較(把一個數和另一個數的二進制補碼比較,并更新標志位)
CMP 比較兩個數并更新標志位
CLZ 計算前導零的數目
EOR 按位異或
LSL 邏輯左移
LSR 邏輯右移
MLA 乘加
MLS 乘減
MOVW 把 16 位立即數放到寄存器的底 16 位, 高 16 位清 0
MOV 加載 16 位立即數到寄存器(其實匯編器會產生 MOVW——譯注)
MOVT 把 16 位立即數放到寄存器的高 16 位, 低 16 位不影響
MVN 移動一個數的補碼
MUL 乘法
ORR 按位或(原文為邏輯或,有誤——譯注)
ORN 把源操作數按位取反后,再執行按位或(原文為邏輯或,有誤——譯注)
RBIT 位反轉(把一個 32 位整數先用 2 進制表達,再旋轉 180 度——譯注)
REV 對一個 32 位整數做按字節反轉
REVH/
REV16
對一個 32 位整數的高低半字都執行字節反轉
REVSH 對一個 32 位整數的低半字執行字節反轉,再帶符號擴展成 32 位數
ROR 圓圈右移
RRX 帶進位的邏輯右移一格(最高位用 C 填充,且不影響 C 的值——譯注)
SFBX 從一個 32 位整數中提取任意的位段,并且帶符號擴展成 32 位整數
SDIV 帶符號除法
SMLAL 帶符號長乘加(兩個帶符號的 32 位整數相乘得到 64 位的帶符號積,再把積加到另一
個帶符號 64 位整數中)
SMULL 帶符號長乘法(兩個帶符號的 32 位整數相乘得到 64 位的帶符號積)
SSAT 帶符號的飽和運算
SBC 帶借位的減法
SUB 減法
SUBW 寬減法,可以減 12 位立即數
SXTB 字節帶符號擴展到 32 位數
TEQ 測試是否相等(對兩個數執行異或,更新標志但不存儲結果)
TST 測試(對兩個數執行按位與,更新 Z 標志但不存儲結果)
UBFX 無符號位段提取
UDIV 無符號除法
UMLAL 無符號長乘加(兩個無符號的 32 位整數相乘得到 64 位的無符號積,再把積加到另一
個無符號 64 位整數中)
UMULL 無符號長乘法(兩個無符號的 32 位整數相乘得到 64 位的無符號積)
USAT 無符號飽和操作(但是源操作數是帶符號的——譯注)
UXTB 字節被無符號擴展到 32 位(高 24 位清 0——譯注)
UXTH 半字被無符號擴展到 32 位(高 16 位清 0——譯注)
表 4.7? ? ? ?32 位存儲器數據傳送指令
名字 功能
LDR 加載字到寄存器
LDRB 加載字節到寄存器
LDRH 加載半字到寄存器
LDRSH 加載半字到寄存器,再帶符號擴展到 32 位
LDM 從一片連續的地址空間中加載多個字到若干寄存器
LDRD 從連續的地址空間加載雙字(64 位整數)到 2 個寄存器
STR 存儲寄存器中的字
STRB 存儲寄存器中的低字節
STRH 存儲寄存器中的低半字
STM 存儲若干寄存器中的字到一片連續的地址空間中
STRD 存儲 2 個寄存器組成的雙字到連續的地址空間中
PUSH 把若干寄存器的值壓入堆棧中
POP 從堆棧中彈出若干的寄存器的值
表 4.8? ? ? ?32 位轉移指令
名字 功能
B 無條件轉移
BL 轉移并連接(呼叫子程序)
TBB 以字節為單位的查表轉移。從一個字節數組中選一個 8 位前向跳轉地址并轉移
TBH 以半字為單位的查表轉移。從一個半字數組中選一個 16 位前向跳轉的地址并轉移
表 4.9? ? ? ?其它 32 位指令
LDREX 加載字到寄存器,并且在內核中標明一段地址進入了互斥訪問狀態
LDREXH 加載半字到寄存器,并且在內核中標明一段地址進入了互斥訪問狀態
LDREXB 加載字節到寄存器,并且在內核中標明一段地址進入了互斥訪問狀態
STREX 檢查將要寫入的地址是否已進入了互斥訪問狀態,如果是則存儲寄存器的字
STREXH 檢查將要寫入的地址是否已進入了互斥訪問狀態,如果是則存儲寄存器的半字
STREXB 檢查將要寫入的地址是否已進入了互斥訪問狀態,如果是則存儲寄存器的字節
CLREX 在本地的處理上清除互斥訪問狀態的標記(先前由 LDREX/LDREXH/LDREXB 做的標記)
MRS 加載特殊功能寄存器的值到通用寄存器
MSR 存儲通用寄存器的值到特殊功能寄存器
NOP 無操作
SEV 發送事件
WFE 休眠并且在發生事件時被喚醒
WFI 休眠并且在發生中斷時被喚醒
ISB 指令同步隔離(與流水線和 MPU 等有關——譯注)
DSB 數據同步隔離(與流水線、 MPU 和 cache 等有關——譯注)
DMB 數據存儲隔離(與流水線、 MPU 和 cache 等有關——譯注)
14、當使用16位指令時,會自動更新APSR標志位,在使用了“.w”指定的32位的指令后,就可以通過手動的增加S進行標志位的更新。
15、寄存器立即數的種類大約有四種
使用偽指令 LDR Rn,=const
系統會自己根據const,自動選擇賦值方法。
16、 Bl (保存返回地址)
BX rd(寄存器) ;轉移到由寄存器rd給出的地址
在 BX中,reg的最低位指示出在轉移后,將進入的狀態是 ARM(LSB=0)還是 Thumb(LSB=1)。
既然 CM3 只在 Thumb 中運行,就必須保證 reg 的 LSB=1
loop
?? ??? ??? ?add r1,r1,#1
?? ??? ??? ?add r2,r2,r1
?? ??? ??? ?subs r3,r1,#100
?? ??? ??? ?beq?? ?step
?? ??? ??? ?b?? ?loop
step
17、對特殊寄存器的操作含義
MRS Move to Register from State register
MSR Move from State registerto Register
18、對寄存器進行串操作
STMIA.W R8!, {r0-R3} ; R8 值變為 0x8010,每存一次增一次,先存儲后自增
STMDB.W R8, {R0-R3} ; R8 值的“一個內部復本”先自減后存儲,但是 R8 的值不變
19、預索引和后索引
ldr r2, [r0, r3]! ;錯誤,寄存器提供偏移量時不支持預索引
ldr r2, [r0], r3 ;錯誤,寄存器提供偏移量時不支持后索引
20、在 CM3 中,下列指令可以更新 PSR 中的標志:
16 位算術邏輯指令
32 位帶 S 后綴的算術邏輯指令
比較指令(如, CMP/CMN)和測試指令(如 TST/TEQ)
直接寫 PSR/APSR (MSR 指令)
21、大小端轉換
例如,記 R0=0x12345678,在執行下列兩條指定后:
REV R1, R0
REVH R2, R0
REV16 R3, R0
則 R1=0x78563412, R2=0x12347856, R3=0x34127856。
比特轉換(翻轉180°)
例如,記 R1=0xB4E10C23(二進制數值為 1011,0100,1110,0001,0000,1100,0010,0011),
RBIT.W R0, R1
執行后,則 R0=0xC430872D(二進制數值為 1100,0100,0011,0000,1000,0111,0010,1101)
22、數據段NOINIT
在數據段只是保留了內存單元,并沒有將各個初始值寫入內存單元,或是初始化為0
————————————————
版權聲明:本文為CSDN博主「Castle_in_sky」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/qq_37689106/article/details/83016963
總結
以上是生活随笔為你收集整理的Cortex-M3基本知识点(手册)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SecureCRT脚本之WaitForS
- 下一篇: 定位ARM Hard Fault 的方法