深入理解 Cortex-M3 特殊寄存器

在上一篇文章中分享了 Cortex-M3 內核寄存器組的相關知識,實際上除了內核寄存器組外,CM3 處理器中還存在多個特殊寄存器,它們分別為?程序狀態寄存器中斷/異常屏蔽寄存器?和?控制寄存器

圖片

需要注意的是,特殊寄存器未經過存儲器映射,即沒有對應的存儲器地址,也只能使用專門的 MSR 和 MRS 等特殊寄存器訪問指令來進行訪問:

MRS <reg> <special_reg>  ;將特殊寄存器讀入寄存器
MSR <special_reg> <reg>  ;寫入特殊寄存器

CMSIS-Core 也提供了幾個用于訪問特殊寄存器的 C 函數,其本質也是以上兩個指令的封裝。如在 gcc 環境下(cmsis_gcc.h),對 CONTROL 寄存器的操作如下:

__STATIC_FORCEINLINE?uint32_t?__get_CONTROL(void)
{uint32_t?result;__ASM?volatile?("MRS?%0,?control"?:?"=r"?(result)?);return(result);
}__STATIC_FORCEINLINE?void?__set_CONTROL(uint32_t?control)
{__ASM?volatile?("MSR?control,?%0"?:?:?"r"?(control)?:?"memory");
}

接下來我們看一下這些特殊寄存器的具體含義。

程序狀態寄存器(PSRs 或 xPSR)

程序狀態寄存器包含以下三個狀態寄存器:

  • 應用 PSR(APSR)

  • 執行 PSR(EPSR)

  • 中斷 PSR(IPSR)

通過上面提到的 MRS 和 MSR 指令,這三個 PSRs 可以單獨訪問:

MRS?r0,?APSR??;將應用狀態讀入?R0
MRS?r0,?IPSR??;將中斷/異常狀態讀入?R0
MSR?APSR,?R0??;寫應用狀態

也可以組合訪問(兩個組合或三個組合都可以)。當使用三合一方式訪問時,應使用?“xPSR” 或 “PSR” 這兩個名字。

MRS?r0,?PSR??;讀組合程序狀態字
MSR?PSR,?r0??;寫組合程序狀態字

需要注意的是,軟件代碼無法直接使用 MRS (讀出為 0)或 MSR 直接訪問 EPSR。同時 IPSR 為只讀,可以從組合 PSR 中讀出。

這三個寄存器的位域結構如下:

圖片

組合形式:

圖片

其中每個位域字段的含義如下:

  • N:負標志。

  • Z:零標志。

  • C:進位(或非借位)標志。

  • V:溢出標志。

  • Q:飽和標志(ARMv6-M 中不存在)。

  • ICI/IT:中斷繼續指令狀態位(ICI),用于條件執行的 IF-THEN 指令狀態位(ARMv6-M 中不存在)。

  • T:Thumb 狀態,總是 1,嘗試清除此位會引起錯誤異常。

  • Exception Number:表示處理器正在處理的異常對應的編號。

PRIMASK,?FAULTMASK 和 BASEPRO

PRIMASK、FAULTMASK 和 BASEMASK 寄存器都用于異常或中斷的屏蔽,每個異常(包括中斷)都有一個優先等級,數值越小優先級越高,反之數值越大優先級越低。以上三個特殊寄存器可以基于優先級屏蔽異常,只有在特權訪問等級才能對它們進行操作(非特權狀態下的寫操作會被忽略,而讀取則會返回 0)。它們的默認值都為 0,即不屏蔽任何異常或中斷。這些寄存器的編程模型如下圖所示:

圖片

PRIMASK 寄存器是位寬為 1 的中斷屏蔽寄存器。在置位時,它會阻止不可屏蔽中斷(NMI)和 HardFault 異常之外的所有異常(包括中斷)。實際上,它的原理是將當前異常優先級提升為 0,這也是可編程異常/中斷的最高優先級。PRIMASK?最常見的用途是在一些時間要求很嚴格的進程中禁止所有中斷,在該進程完成后,需要將 PRIMASK 清除以重新使能中斷。

FAULTMASK 和 PRIMASK 非常相似,不過它還能屏蔽 HardFault 異常,它實際上是將異常優先級提升到了 -1。錯誤處理代碼可以使用 FAULTMASK 以免在錯誤處理期間再次觸發其他錯誤(只有幾種)。例如, FAULTMASK 可用于旁路 MPU 或屏蔽總線錯誤(這些都是可配置的),這樣,錯誤處理代碼執行修復措施也就更容易了。與 PRIMASK 不同, FAULTMASK 在異常返回時會被自動清除。

BASEPRI 會根據優先級屏蔽異常或中斷。BASEPRI 的寬度取決于設計中實際實現的優先級數量,這通常是由微控制器供應商決定的。大多數 Cortex-M3 或 Cortex-M4 微控制器都有 8 個或 16 個可編程的異常優先級,此時 BASEPRI 的寬度就相應地為 3 位或者 4 位。BASEPRI 為 0 時不會起作用,當被設置為非 0 數值時,他就會屏蔽具有相同或更低優先級的異常(包括中斷),而更高優先級的則仍然會被處理器接受。

CMSIS-Core 提供了多個 C 函數用于訪問 PRIMASK、FAULTMASK、及 BASEPRI 寄存器。(這些寄存器只能在特權等級下訪問)

x?=?__get_BASEPRI();?//?讀?BASEPRI?寄存器
x?=?__get_PRIMARK();?//?讀?PRIMASK?寄存器
x?=?__get_FAULTMASK();?//?讀?FAULTMASK?寄存器
__set_BASEPRI(x);?//?設置?BASEPRI
__set_PRIMASK(x);?//?設置?PRIMASK
__set_FAULTMASK(x);?//?設置?FAULTMASK
__disable_irq();?//?設置?PRIMASK,?禁用?IRQ
__enable_irq();?//?清除?PRIMASK,?使能?IRQ

同時也可以使用匯編代碼訪問這些寄存器:

MRS r0, BASEPRI ; 將 BASEPRI 寄存器的值讀入 R0
MRS r0, PRIMASK ; 將 PRIMASK 寄存器的值讀入 R0
MRS r0, FAULTMASK ; 將 FAULTMASK 寄存器的值讀入 R0
MSR BASEPRI, r0 ; 將 R0 寄存器的值寫入 BASEPRI 
MSR PRIMASK, r0 ; 將 R0 寄存器的值寫入 PRIMASK 
MSR FAULTMASK, r0 ; 將 R0 寄存器的值寫入 FAULTMASK

此外,利用修改處理器狀態(CPS)指令,可以非常方便地設置或清除 PRIMASK 和 FAULTMASK 的值:

CPSIE i ; 使能 interrupt (清除 PRIMASK)
CPSID i ; 禁用 interrupt (設置 PRIMASK)
CPSIE f ; 使能 interrupt (清除 FAULTMASK)
CPSID f ; 禁用 interrupt (設置 FAULTMASK)

CONTROL 寄存器

CONTROL 寄存器中包含了如下兩個主要信息:

  • 棧指針的選擇(主棧指針 MSP 和 進程棧指針 PSP)。

  • 線程模式的訪問等級(特權級和非特權級)。

其編程模型如下:

圖片

具體的位域描述為:

位? ? ?描述

CONTROL[1]

(SPSEL)

定義棧指針的選擇?

0=選擇主棧指針 MSP(復位后缺省值)?

1=選擇進程棧指針 PSP?

在線程或基礎級(沒有在響應異常),可以使用 PSP。在 handler 模式下, 只允許使用 MSP,所以此時不得往該位寫 1。

CONTROL[0]

(nPRIV)

定義線程模式中的特權等級

0=特權級的線程模式?

1=用戶級的線程模式?

Handler 模式永遠都是特權級的。

復位后,CONTROL 寄存器默認為 0,這意味著處理器此時處于線程模式,具有特權訪問權限并且使用主棧指針。通過寫 CONTROL 寄存器,特權線程模式的程序可以切換棧指針的選擇或進入非特權訪問等級,如下圖所示:

圖片

不過,nPRIV(CONTROL[0])置位后,運行在線程模式的程序就不能訪問 CONTROL 寄存器了。

運行在非特權等級的程序一般情況下無法再切換回特權訪問等級,這樣就提供了一個基本安全的模型。例如,嵌入式系統中可能會具有運行在非特權等級且不受信任的應用,這些應用的訪問權限就需要受到限制,以免不可靠的程序引起系統的崩潰。

若需要在線程模式切換回特權訪問等級,則需要借助于異常機制。在異常處理期間,處理程序可以清除 nPRIV 位。在返回到線程模式后,處理器就會進入特權訪問等級。

圖片

若使用嵌入式 OS,每次上下文切換時都可以重新編程 CONTROL 寄存器,以滿足應用間不同特權訪問等級的需要。

nPRIV 和 SPSEL 的設置有 4 種組合方式,其中 3 種在實際應用中較為常見:

nPRIVSPSEL應用場景
00簡單應用,整個應用運行在特權訪問等級,主程序和中斷處理只會使用一個棧,即主棧 MSP
01具有嵌入式 OS 的應用,當前執行的任務運行在特權級線程模式,當前任務選擇使用進程棧指針 PSP,而 MSP 則用于 OS 內核以及異常處理
11具有嵌入式 OS 的應用,當前執行的任務運行在非特權級線程模式,當前任務選擇使用進程棧指針 PSP,而 MSP 則用于 OS 內核以及異常處理
10線程模式運行在非特權訪問等級,且使用 MSP,在 Handler 模式下可以觀察到,而在用戶任務中一般不會使用,這是因為在多數嵌入式 OS 中,應用任務的棧和 OS 內核以及異常處理使用的棧是相互獨立的

對于未使用嵌入式 OS 的多數簡單應用,無須修改 CONTROL 寄存器的數值,整個應用可以運行在特權訪問等級并且只使用 MSP:

圖片

要利用 C 語言訪問 CONTROL 寄存器,可以使用符合 CMSIS 的設備驅動庫提供的以下函數:

x?=?__get_CONTROL();?//?讀取當前?CONTROL?寄存器的值
__set_CONTROL(x);?//?設置?CONTROL?寄存器的值為?x

如果使用匯編,則可以借助于 MRS 和 MSR 指令:

MRS r0, CONTROL   ;將 CONTROL 寄存器的值讀到 r0
MSR CONTROL, r0   ;將 r0 中的值寫到 CONTROL 寄存器

最后,你可以通過檢查 CONTROL 和 IPSR 的數值來確定當前是否為特權等級:

int?in_privileged(void)?{if?(__get_IPSR()?!=?0)return?1;??//?Trueelse?if?((__get_CONTROL()?&?0x1)?==?0)return?1;??//?Trueelsereturn?0;??//?False
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/80439.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/80439.shtml
英文地址,請注明出處:http://en.pswp.cn/web/80439.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

標準庫、HAl庫和LL庫(PC13初始化)

標準庫 (Standard Peripheral Library) c #include "stm32f10x.h"void GPIO_Init_PC13(void) {GPIO_InitTypeDef GPIO_InitStruct;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);GPIO_InitStruct.GPIO_Pin GPIO_Pin_13;GPIO_InitStruct.GPIO_Mode GPIO_…

基于開源鏈動2+1模式AI智能名片S2B2C商城小程序的低集中度市場運營策略研究

摘要&#xff1a;本文聚焦于行業市場集中度問題&#xff0c;探討在低集中度市場中&#xff0c;如何利用開源鏈動21模式AI智能名片S2B2C商城小程序開展有效運營。分析了高集中度市場的競爭劣勢&#xff0c;闡述了開源鏈動21模式、AI智能名片以及S2B2C商城小程序的功能特點及其在…

一文讀懂-嵌入式Ubuntu平臺

現在直接在一些嵌入式Soc上移植ubuntu來用到產品上&#xff0c;剛開始感覺還挺臃腫的&#xff0c;后來細聊了下感覺還是有一定的優勢。 ubuntu相信大家在熟悉不過了&#xff0c;幾乎無處不在&#xff0c;小到咖啡機&#xff0c;大到火星車&#xff0c;為什么ubuntu如此廣泛&am…

箭頭函數及其與普通函數區別的詳細解釋

一、箭頭函數的基本特性 語法簡潔性 箭頭函數使用 > 符號定義&#xff0c;省略 function 關鍵字&#xff0c;適合快速定義匿名函數或簡單表達式。 // 普通函數 function sum(a, b) { return a b; } // 箭頭函數 const sum (a, b) > a b;若函數體為單行表達式&#x…

el-scrollbar 獲取滾動條高度 并將滾動條保持在低端

首先我們用ref綁定一個 scrollbar <el-scrollbar style"height: 100%;" ref"chatScrollRef" scroll"scrollTest">用scroll觸發滾動事件&#xff0c;一路滾到最底下&#xff0c;觀察三個屬性 const scrollTest ({scrollTop}) > {conso…

MyBatis-Plus 的 updateById 方法不更新 null 值屬性的問題

項目場景&#xff1a; 使用Mybatis-plus的updateById去更新實體類的時候&#xff0c;如果設置實體類中的某個字段為null&#xff0c;會導致為null的字段不做更新操作 問題描述 updateById方法 不會更新null值 解決方案&#xff1a; 在字段上加上 TableField(updateStrategy …

STC89C52單片機模擬實現洗衣機控制 Proteus仿真

用直流電機轉動模擬洗衣機。要求有弱洗、普通洗、強洗三種模式,可通過按鍵選擇相應模式。要求能夠設置洗衣時長,可以通過按鍵選擇15、30、45、60、90分鐘。定時結束時蜂鳴器報警提示。LCD顯示相關信息。 基本功能描述用單片機模擬實現洗衣機控制。用直流電機轉動模擬洗衣機運…

游戲引擎學習第290天:完成分離渲染

game_sim_region.cpp&#xff1a;在BeginSim中移除EntityOverlapsRectangle調用 現在我們接近一個關鍵點&#xff0c;雖然還沒完全結束&#xff0c;但我們已經把所有東西遷移到了一個新概念上——即那些臨時創建的控制器結構&#xff0c;稱為“腦”&#xff08;brains&#xf…

JavaScript性能優化實戰(12):大型應用性能優化實戰案例

在前面的系列文章中,我們探討了各種JavaScript性能優化技術和策略。本篇將聚焦于實際的大型應用場景,通過真實案例展示如何綜合運用這些技術,解決復雜應用中的性能挑戰。 目錄 電商平臺首屏加載優化全流程復雜數據可視化應用性能優化案例在線協作工具的實時響應優化移動端W…

Linux 安裝 Unreal Engine

需要對在unreal engine官網進行綁定github賬號&#xff0c;然后到unreal engine github倉庫中進行下載對應的版本&#xff0c;并進行安裝unreal engine官網 github地址

2.2.4

import pandas as pd from sklearn.model_selection import train_test_split from sklearn.linear_model import LinearRegression from sklearn.metrics import mean_squared_error, r2_score import joblib from xgboost import XGBRegressor # 加載數據集 file_path 大學…

使用IDEA創建Maven版本的web項目以及lombok的使用

1.新建項目 2.修改pom.xml 3.修改項目結構 4.在main/java下面寫一個Servlet測試一下 然后當前頁面往下滑 -Dfile.encodingUTF-8編寫一句輸出語句&#xff0c;測試是否成功部署配置&#xff0c;并選擇到正確的位置&#xff1a; 回車以后 再回到idea里面&#xff0c;發現控…

【數據結構】1-3 算法的時間復雜度

數據結構知識點合集&#xff1a;數據結構與算法 ? 知識點 ? 時間復雜度的定義 1、算法時間復雜度 事前預估算法時間開銷T(n)與問題規模 n 的關系&#xff08;T 表示 “time”&#xff09; 2、語句頻度 算法中語句的執行次數 對于以上算法&#xff0c;語句頻度&#xff1a;…

【Python 算法零基礎 3.遞推】

壓抑與痛苦&#xff0c;那些輾轉反側的夜&#xff0c;終會讓我們更加強大 —— 25.5.16 一、遞推的概念 遞推 —— 遞推最通俗的理解就是數列&#xff0c;遞推和數列的關系就好比 算法 和 數據結構 的關系&#xff0c;數列有點像數據結構中的線性表(可以是順序表&#xff0c;也…

淘寶扭蛋機系統開發前景分析:解鎖電商娛樂化新藍海

在電商行業競爭日益白熱化的當下&#xff0c;如何通過創新玩法提升用戶粘性、激活消費潛力&#xff0c;成為平臺突破增長瓶頸的關鍵。淘寶扭蛋機系統作為“電商娛樂”的跨界融合產物&#xff0c;正憑借其趣味性、隨機性和社交屬性&#xff0c;成為撬動年輕消費市場的潛力工具。…

NHANES指標推薦:UHR

文章題目&#xff1a;Elevated log uric acid-to-high-density lipoprotein cholesterol ratio (UHR) as a predictor of increased female infertility risk: insights from the NHANES 2013-2020 DOI&#xff1a;10.1186/s12944-025-02521-w 中文標題&#xff1a;對數尿酸與高…

【c庫主要功能】

1 stdio.h 功能&#xff1a;處理文件和標準輸入/輸出流的各種函數和類型 包含變量&#xff1a; size_t&#xff1a;無符號整形&#xff0c;sizeof關鍵字的結果FILE&#xff1a;文件流類型&#xff0c;適合存儲文件流信息的對象類型 庫宏&#xff1a; stderr、stdin、stdout&a…

npm 報錯 gyp verb `which` failed Error: not found: python2 解決方案

一、背景 npm 安裝依賴報如下錯&#xff1a; gyp verb check python checking for Python executable "python2" in the PATH gyp verb which failed Error: not found: python2 一眼看過去都覺得是Python環境問題&#xff0c;其實并不是你python環境問題&#xf…

常見的請求頭(Request Header)參數

1. Accept 作用&#xff1a;告知服務器客戶端支持的響應數據格式&#xff08;如 JSON、XML、HTML&#xff09;。示例&#xff1a;Accept: application/json&#xff08;優先接收 JSON 格式數據&#xff09;。 2. Content-Type 作用&#xff1a;說明請求體的數據格式&#xff08…

計算機網絡:移動通信蜂窩網絡指的是什么?

無線基站的蜂窩網絡(Cellular Network)是現代移動通信系統的核心架構,其核心思想是通過蜂窩狀小區劃分和頻率復用,實現廣域覆蓋、高效頻譜利用和動態資源管理。以下從設計原理、網絡架構、關鍵技術及實際挑戰等方面深入解析蜂窩網絡。 一、蜂窩網絡的設計原理 1. 蜂窩結構…