cortex-m3基礎知識總結


cortex-m3

    • 操作模式
    • 寄存器組
    • 異常類型
    • 堆棧
    • 中斷
    • 參考

 

操作模式

處理器的操作模式:為了區別正在執行代碼的類型。復位后,處理器進入線程模式、特權級。

處理者模式(handler mode):異常服務例程的代碼 ,包括中斷服務例程的代碼。handler 模式總是特權級的。

線程模式(thread mode):普通應用程序的代碼。

特權級:在特權級下,程序可以訪問所有范圍的存儲器、可以執行所有指令。運行主應用程序時(線程模式),既可以使用特權級,也可以使用用戶級;但是異常服務例程必須在特權級下執行。

用戶級:從用戶級到特權級的唯一途徑就是異常:如果在程序執行過程中觸發了一個異常,處理器總是先切換入特權級,並且在異常服務例程執行完畢退出時,返回先前的狀態,也可以手工指定返回的狀態。

用戶級到特權級:執行一條系統調用指令(SVC),觸發 SVC 異常,然后由異常服務例程接管,如果批准了進入,則異常服務例程修改 CONTROL寄存器,才能在用戶級的線程模式下重新進入特權級。

寄存器組

R0‐R12:都是 32 位通用寄存器,用於數據操作。

R0‐R7 ,低組寄存器,所有指令都能訪問它們,字長全是 32 位,復位后的初始值不可預料。

R8‐R12,高組寄存器,只有很少的 16 位 Thumb 指令能訪問它們,32 位的指令則不受限制,它們也是 32 位字長,且復位后的初始值不可預料。

R13:堆棧指針 SP,有兩個堆棧指針MSP、PSP,任一時刻只能使用其中的一個。運行在線程模式的用戶代碼使用 PSP, 而異常服務例程則使用 MSP。

MSP:主堆棧指針(MSP):復位后缺省使用的堆棧指針,用於操作系統內核以及異常處理例程(包括中斷服務例程)。

PSP:進程堆棧指針(PSP):由用戶的應用程序代碼使用。

R14:連接寄存器(LR):當呼叫一個子程序時,由 R14 存儲返回地址。把返回地址直接存儲在寄存器中,提高了子程序調用的效率。

R15:程序計數寄存器(PC):指向當前的程序地址。

在這里插入圖片描述

特殊功能寄存器:它們只能被專用的 MSR 和 MRS 指令訪問,而且它們也沒有存儲器地址。

在這里插入圖片描述

程序狀態字寄存器組(xPSR):記錄 ALU 標志(0 標志,進位標志,負數標志,溢出標志),執行狀態,以及當前正服務的中斷號。

其中的EPSR,它里面含 T 位,在 CM3 中 T 位必須是 1。

在這里插入圖片描述

中斷屏蔽寄存器組(PRIMASK, FAULTMASK, BASEPRI)

這里面的PRIMASK 和 BASEPRI 對於暫時關閉中斷是非常重要的。

MSR BASEPRI, R0 ;寫入 R0 到 BASEPRI 中

在這里插入圖片描述

控制寄存器(CONTROL)

control[1]:handler 模式中,CONTROL[1]總是 0。在線程模式中則可以為 0 或 1。當處於特權級的線程模式下,此位才可寫。

control[0]:僅當在特權級下操作時才允許寫該位。一旦進入了用戶級,唯一返回特權級的途徑,就是觸發一個(軟)中斷,再由服務例程改寫該位。

在這里插入圖片描述

指令集:

Thumb狀態:在 Thumb 狀態下,指令是 16 位的。

異常類型

SVCall:系統服務調用。用戶程序使用 SVC 發出對系統服務函數的呼叫請求,以這種方法調用它們來間接訪問硬件。這使得用戶程序無需在特權級下執行。

SVC 異常通過執行”SVC”指令來產生。該指令需要一個立即數,充當系統調用代號。

SVC 異常是必須立即得到響應的,若無法立即響應,將上訪成硬fault。

PendSV:為系統設備而設的“可懸掛請求”(pendable request)。

PendSV可以像普通的中斷一樣被懸起,OS 可以利用它緩期執行一個異常—直到其它重要的任務完成后才執行動作。懸起 PendSV 的方法是:手工往 NVIC 的 PendSV 懸起寄存器中寫 1。

上下文切換時(在不同任務之間切換)可以用到PendSV。

ISR:中斷服務例程。

IRQ:中斷請求(通常是指外部中斷的請求)

硬fault :總線 fault、存儲器管理 fault 以及用法 fault 上訪的結果。

如下圖所示,在產生 SysTick 異常時正在響應一個中斷請求IRQ,則 SysTick 異常會搶占其 ISR(中斷服務例程)。在這種情況下,OS 不得執行上下文切換(將使中斷請求IRQ被延遲,實時系統不能容忍),OS 在某中斷活躍時嘗試切入線程模式,將觸犯用法 fault 異常。

在這里插入圖片描述

PendSV 異常會自動延遲上下文切換的請求, 直到其它的 ISR (中斷服務例程)都處理完才放行。為實現這個機制,需要把 PendSV 編程為最低優先級的異常。如果 OS 檢測到某 IRQ 正在活動並且被 SysTick 搶占,它將懸起一個 PendSV 異常, 以便緩期執行上下文切換。

下圖,1.任務A叫SVC(系統服務調用)來請求任務切換。2.OS收到請求,做好上下文切換准備,pend一個PendSV異常。3.CPU退出SVC,立即進入PendSV,執行上下文切換。4.PendSV執行完,返回任務B,進入線程模式。5.發生一個IRQ(中斷),ISR(中斷服務程序)開始執行。6.ISR執行過程中,發生SysTick異常,搶占該ISR。7.OS執行必要操作,pend起PendSV異常做好上下文切換准備。8.SysTick退出,回到先前被搶占的ISR中,ISR繼續執行。9.ISR執行完並退出后,PendSV服務例程執行,在里面執行上下文切換。10.PendSV執行完,回到任務A,系統再次進入線程模式。

這個簡而言之,PendSV其實起到了啥作用呢,如果產生 SysTick 異常時(為了進行上下文切換)正在響應一個中斷請求IRQ,則 SysTick 異常會搶占其 ISR,用了PendSV的話,SysTick退出后不會立即執行上下文切換,而是在SysTick退出后繼續執行ISR,執行完ISR之后再執行PendSV服務例程,進行上下文切換。這樣好處就是不會使中斷請求被延遲,有助於增加系統的實時性。

在這里插入圖片描述

Cortex‐M3 一部分異常類型如下。

在這里插入圖片描述

向量表:為了決定 handler 的入口地址,CM3使用了向量表查表機制。

如果發生了異常11(SVC),則NVIC會計算出偏移移量是11x4=0x2C,然后取出服務例程的入口地址並跳入。

在這里插入圖片描述

在這里插入圖片描述

堆棧

堆棧:由一塊連續的內存,以及一個棧頂指針組成。堆棧操作就是對內存的讀寫操作,其地址由 SP 給出。功能就是把寄存器的數據放入內存,以便將來能恢復之。

當 PUSH/POP 指令執行時,SP 指針的值也根着自減/ 自增。

一個例子如下,執行 Fx1 的功能,中途就算改變 R0-R2 的值,回來的時候R0-R2 的值又變回來了,這就是恢復的功效。

在這里插入圖片描述

實現堆棧:棧是后進先出的,使用的是“向下生長的滿棧”模型。堆棧指針 SP 指向最后一個被壓入堆棧的 32 位數值。

入棧時,SP 先自減 4,再存入新的數值。如下圖。

在這里插入圖片描述

出棧時,先讀出上一次被壓入的值,再把 SP 指針自增 4。

在這里插入圖片描述

雙堆棧機制:

當 CONTROL[1]=1 時,進程堆棧指針選用PSP,handler堆棧指針選用MSP。

在這里插入圖片描述

在特權級下,可以指定具體的堆棧指針,而不受當前使用堆棧的限制。

MRS R0, PSP ; 讀取進程堆棧指針到 R0 
MSR PSP, R0 ; 寫入 R0 的值到進程堆棧中

通過讀取 PSP 的值,OS 就能夠獲取用戶應用程序使用的堆棧,進一步地就知道了在發生異常時,被壓入寄存器的內容,而且還可以把其它寄存器進一步壓棧(使用STMDB和LDMIA 的書寫形式)。OS 還可以修改 PSP,用於實現多任務中的任務上下文切換。

中斷

CM3開始響應一個中斷時,進行以下操作:

入棧: 把8個寄存器的值壓入棧。取向量:從向量表中找出對應的服務程序入口地址。 選擇堆棧指針MSP/PSP,更新堆棧指針SP,更新連接寄存器LR,更新程序計數器PC。

入棧:是自動保存現場的必要部分。把xPSR, PC, LR, R12以及 R3‐R0由硬件自動壓入適當的堆棧中。響應異常時,代碼正使用PSP,使用線程堆棧;否則使用主堆棧。進入服務例程,一直使用主堆棧。

入棧順序和入棧后堆棧中的內容如下圖。假設入棧開始時,SP的值為N。下圖的地址從上到下看,是由高到低的。

在這里插入圖片描述

數據總線(系統總線)進行入棧操作,與此同時,指令總線(I‐Code總線)從向量表中找出正確的異常向量,然后找出對應的服務程序入口地址。

入棧和取向量工作做完,執行服務例程之前,會更新一系列的寄存器。

SP,在入棧中把堆棧指針更新到新位置。PSR,IPSR位段更新為新響應的異常編號。PC,向量取完后,PC將指向服務例程入口地址。LR,值更新為EXC_RETURN,在異常返回時使用。在NVIC中,新響應異常的懸起位將被清除,同時其活動位將被置位。

異常服務例程執行完畢后,要啟動中斷返回序列,為的是恢復先前的系統狀態,使被中斷的程序繼續執行。

有3種途徑可以觸發異常返回序列(都需要用到先前儲的LR的值),在CM3中,是通過把EXC_RETURN往PC里寫來識別返回動作的。

在這里插入圖片描述

啟動了中斷返回序列后,就進行下面操作:恢復先前壓入棧中的寄存器,內部的出棧順序與入棧時的相對應,堆棧指針的值也改回去;更新NVIC寄存器,活動位被硬件清除。(倘若中斷輸入再次被置為有效,懸起位也將再次置位,進行新一輪的中斷響應)

EXC_RETURN:這 是一個高28位全為1的值,只有[3:0]的值有特殊含義。當異常服務例程把這個值送往PC時,就會啟動處理器的中斷返回序列。合法的EXC_RETURN值共3個:

在這里插入圖片描述

參考

Cortex-M3 權威指南 Joseph Yiu 著 宋岩 譯


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM