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

news2025/5/16 4:21:07

在上一篇文章中分享了 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;  // True
    else if ((__get_CONTROL() & 0x1) == 0)
        return 1;  // True
    else
        return 0;  // False
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2376576.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[Java实战]Spring Boot 3 整合 Ehcache 3(十九)

[Java实战]Spring Boot 3 整合 Ehcache 3&#xff08;十九&#xff09; 引言 在微服务和高并发场景下&#xff0c;缓存是提升系统性能的关键技术之一。Ehcache 作为 Java 生态中成熟的内存缓存框架&#xff0c;其 3.x 版本在性能、功能和易用性上均有显著提升。本文将详细介绍…

建筑物渗水漏水痕迹发霉潮湿分割数据集labelme格式1357张1类别

数据集中有增强图片详情看图片 数据集格式&#xff1a;labelme格式(不包含mask文件&#xff0c;仅仅包含jpg图片和对应的json文件) 图片数量(jpg文件个数)&#xff1a;1357 标注数量(json文件个数)&#xff1a;1357 标注类别数&#xff1a;1 标注类别名称:["water&qu…

第二十二天打卡

数据预处理 import pandas as pd from sklearn.model_selection import train_test_splitdef data_preprocessing(file_path):"""泰坦尼克号生存预测数据预处理函数参数:file_path: 原始数据文件路径返回:preprocessed_data: 预处理后的数据集""&quo…

解锁性能密码:Linux 环境下 Oracle 大页配置全攻略​

在 Oracle 数据库运行过程中&#xff0c;内存管理是影响其性能的关键因素之一。大页内存&#xff08;Large Pages&#xff09;作为一种优化内存使用的技术&#xff0c;能够显著提升 Oracle 数据库的运行效率。本文将深入介绍大页内存的相关概念&#xff0c;并详细阐述 Oracle 在…

Spark,在shell中运行RDD程序

在hdfs中/wcinput中创建一个文件&#xff1a;word2.txt在里面写几个单词 启动hdfs集群 [roothadoop100 ~]# myhadoop start [roothadoop100 ~]# cd /opt/module/spark-yarn/bin [roothadoop100 ~]# ./spark-shell 写个11测试一下 按住ctrlD退出 进入环境&#xff1a;spa…

SAP学习笔记 - 开发11 - RAP(RESTful Application Programming)简介

上一章学习了BTP架构图&#xff0c;实操创建Directory/Subaccount&#xff0c;BTP的内部组成&#xff0c;BTP Cockpit。 SAP学习笔记 - 开发10 - BTP架构图&#xff0c;实操创建Directory/Subaccount&#xff0c;BTP的内部组成&#xff0c;BTP Cockpit-CSDN博客 本章继续学习S…

数据防泄密安全:企业稳健发展的守护盾

在数字化时代&#xff0c;数据已成为企业最核心的资产之一。无论是客户信息、财务数据&#xff0c;还是商业机密&#xff0c;一旦泄露&#xff0c;都可能给企业带来不可估量的损失。近年来&#xff0c;数据泄露事件频发&#xff0c;如Facebook用户数据泄露、Equifax信用数据外泄…

MySQL之基础索引

目录 引言 1、创建索引 2、索引的原理 2、索引的类型 3、索引的使用 1.添加索引 2.删除索引 3.删除主键索引 4.修改索引 5.查询索引 引言 当一个数据库里面的数据特别多&#xff0c;比如800万&#xff0c;光是创建插入数据就要十几分钟&#xff0c;我们查询一条信息也…

拉丁方分析

本文是实验设计与分析&#xff08;第6版&#xff0c;Montgomery著傅珏生译)第4章随机化区组&#xff0c;拉丁方&#xff0c;以及有关的设计第4.2节的python解决方案。本文尽量避免重复书中的理论&#xff0c;着于提供python解决方案&#xff0c;并与原书的运算结果进行对比。您…

软考软件设计师中级——软件工程笔记

1.软件过程 1.1能力成熟度模型&#xff08;CMM&#xff09; 软件能力成熟度模型&#xff08;CMM&#xff09;将软件过程改进分为以下五个成熟度级别&#xff0c;每个级别都定义了特定的过程特征和目标&#xff1a; 初始级 (Initial)&#xff1a; 软件开发过程杂乱无章&#xf…

5.5.1 WPF中的动画2-基于路径的动画

何为动画?一般只会动。但所谓会动,还不仅包括位置移动,还包括角度旋转,颜色变化,透明度增减。动画本质上是一个时间段内某个属性值(位置、颜色等)的变化。因为属性有很多数据类型,它们变化也需要多种动画类比如: BooleanAnimationBase\ ByteAnimationBase\DoubleAnima…

Andorid之TabLayout+ViewPager

文章目录 前言一、效果图二、使用步骤1.主xml布局2.activity代码3.MyTaskFragment代码4.MyTaskFragment的xml布局5.Adapter代码6.item布局 总结 前言 TabLayoutViewPager功能需求已经是常见功能了&#xff0c;我就不多解释了&#xff0c;需要的自取。 一、效果图 二、使用步骤…

26考研——中央处理器_指令流水线_流水线的冒险与处理 流水线的性能指标 高级流水线技术(5)

408答疑 文章目录 六、指令流水线流水线的冒险与处理结构冒险数据冒险延迟执行相关指令采用转发&#xff08;旁路&#xff09;技术load-use 数据冒险的处理 控制冒险 流水线的性能指标流水线的吞吐率流水线的加速比 高级流水线技术超标量流水线技术超长指令字技术超流水线技术 …

酒店旅游类数据采集API接口之携程数据获取地方美食品列表 获取地方美餐馆列表 景点评论

携程 API 接入指南 API 地址&#xff1a; 调用示例&#xff1a; 美食列表 景点列表 景点详情 酒店详情 参数说明 通用参数说明 请谨慎传递参数&#xff0c;避免不必要的费用扣除。 URL 说明&#xff1a;https://api-gw.cn/平台/API类型/ 平台&#xff1a;淘宝&#xff0c;京…

Lora原理及实现浅析

Lora 什么是Lora Lora的原始论文为《LoRA: Low-Rank Adaptation of Large Language Models》&#xff0c;翻译为中文为“大语言模型的低秩自适应”。最初是为了解决大型语言模在进行任务特定微调时消耗大量资源的问题&#xff1b;随后也用在了Diffusion等领域&#xff0c;用于…

【设计模式】- 创建者模式

单例模型 饿汉式 静态方法创建对象 public class Singleton {// 私有构造方法private Singleton(){}private static Singleton instance new Singleton();// 提供一个外界获取的方法public static Singleton getInstance(){return instance;} }静态代码块创建对象 public …

南审计院考研分享会 经验总结

汪学长 – 中科大 计科专硕 初试准备 数学先做真题&#xff0c;模拟题刷的越多分越高&#xff1b;408真题最重要&#xff0c;模拟题辅助&#xff1b;英语只做真题&#xff1b;政治9月份开始背 代码能力在低年级培养的重要性和路径 考研不选择机构原因 因为机构里面学习的框…

牛客练习赛138(首篇万字题解???)

赛时成绩如下&#xff1a; 1. 小s的签到题 小s拿到了一个比赛榜单&#xff0c;他要用最快的速度找到签到题&#xff0c;但是小s脑子还是有点晕&#xff0c;请你帮帮小s&#xff0c;助力他找到签到题。 比赛榜单是一个 2 行 n 列的表格&#xff1a; 第一行是 n 个大写字母&#…

用git下载vcpkg时出现Connection was reset时的处理

用git安装vcpkg时出现Connect was rest&#xff08;如上图&#xff09;。多谢这位网友的博文解决了问题&#xff1a; 通过:http.sslVerify false全局来设置&#xff0c;执行以下命令&#xff1a; git config --global http.sslVerify "false" 原文链接&#xff1a…

leetcode - 滑动窗口问题集

目录 前言 题1 长度最小的子数组&#xff1a; 思考&#xff1a; 参考代码1&#xff1a; 参考代码2&#xff1a; 题2 无重复字符的最长子串&#xff1a; 思考&#xff1a; 参考代码1&#xff1a; 参考代码2&#xff1a; 题3 最大连续1的个数 III&#xff1a; 思考&am…