Cortex-M系列中断和异常(三)

2023-05-16

文章目录

  • Cortex-M系列中断和异常
    • 1.1 SCB中的寄存器
      • 1.1.1 中断控制和状态寄存器(SCB->ICSR)
      • 1.1.2 向量表偏移寄存器(SCB->VTOR)
      • 1.1.3 应用中断和复位控制寄存器(SCB->AIRCR)
      • 1.1.4 系统处理优先级寄存器(SCB->SHP[0~11])
      • 1.1.5 系统控制和状态寄存器(SCB->SHCSR)
    • 1.2 用于屏蔽异常和中断的三个特殊寄存器
      • 1.2.1 PRIMASK寄存器
      • 1.2.2 FAULTMASK寄存器
      • 1.2.3 BASEPRI寄存器


Cortex-M系列中断和异常

     在CMSIS-Core中,中断和异常的相关寄存器不止存在于NVIC数据结构中,还有一部分在系统控制块(SCB)的数据结构中。

1.1 SCB中的寄存器

     下面是SCB中的寄存器一览表,这些是所有的寄存器,这里面只有一部分与中断和异常有关:
在这里插入图片描述
在这里插入图片描述

1.1.1 中断控制和状态寄存器(SCB->ICSR)

     ICSR=>Interrupt Control State Register,此寄存器的主要作用:

  • 设置和清除系统异常的挂起状态,和NVIC中断挂起寄存器差不多,异常包括Systick、PendSV、NMI;
  • 通过读取VECTACTIVE=>Vector Active域,可以确定当前执行的异常/中断编号,VECTACTIVE域和上一节提到的IPSR相同;
    在这里插入图片描述

1.1.2 向量表偏移寄存器(SCB->VTOR)

     向量表偏移寄存器地址为0xE000ED0C,可由CMSIS-Core中的SCB->VTOR来访问。这个寄存器里面始终存着要使用的向量表。具体说明如下:
在这里插入图片描述

1.1.3 应用中断和复位控制寄存器(SCB->AIRCR)

     AIRCR=>Application Interrupt Reset Control Register。多数情况下,可以使用CMSIS-Core函数NVIC_SetPriorityGrouping和NVIC_GetPriorityGrouping来访问PRIGROUP,如下图。VECTRESET和VECTCLRACTIVE位域是为调试器设计的,尽管软件可以利用VECTRESET触发一次处理器复位,不过由于它不会复位外设等系统中的其他部分,因此多数应用程序是不大会用到它的。若想产生一次系统复位,多数情况下(取决于芯片设计和应用复位需求)应该使用SYSRESETREQ。
     有一点要注意,VECTRESET和VECTCLRACTIVE不应同时置位,非要这么做的话会导致Cortex-M3/M4设备的复位电路出错,这是因为VECTRESET信号会复位SYSRESETREQ。根据微控制器复位电路设计,将1写入SYSRESETREQ后,处理器可能会在复位实际产生前继续执行几条指令,因此,通常要在系统复位请求后加上一个死循环,保证不会执行后面的代码。
在这里插入图片描述

1.1.4 系统处理优先级寄存器(SCB->SHP[0~11])

     这个寄存器组和中断优先级寄存器组类似,但是SHP寄存器是用于系统的异常,配置系统异常优先级同样可以用CMSIS-Core的接口,NVIC_SetPriority和NVIC_GetPriority。具体的寄存器如下:[
在这里插入图片描述
     注意这一组寄存器都是一个字节8bit的,在很多的操作系统中会把systick和pendsv系统异常配置为最低的优先级,具体的代码如下:

// FreeRTOS
#define configKERNEL_INTERRUPT_PRIORITY 		255

#define portNVIC_PENDSV_PRI					( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) // 0xe000ed22
#define portNVIC_SYSTICK_PRI				( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) // 0xe000ed23

#define portNVIC_SYSPRI2_REG				( * ( ( volatile uint32_t * ) 0xe000ed20 ) ) 

/* Make PendSV and SysTick the lowest priority interrupts. */
portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI;
portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI;

     此处为什么要配置0xe000ed20寄存器呢?因为代码中把0xe000ed20当做是一个32bit的寄存器,操作它就可以操作0xe0xe000ed21, 0xe000ed22, 0xe000ed23。

1.1.5 系统控制和状态寄存器(SCB->SHCSR)

     使用错误、存储器管理错误和总线错误异常的使能由此寄存器(0xe000ed24)来操作,错误的挂起状态和多数系统异常的活跃状态也可以从这个寄存器中得到。多数情况下,该寄存器仅用于应用代码使能可配置的错误处理,但是在操作寄存器的时候要多加小心,因为这些系统异常的活跃状态位是可读可写的,因此千万不能把活跃状态位意外地修改掉,不然,若一个已经被激活的系统异常的活跃状态被意外清掉,当系统异常处理产生异常退出时就会出现错误异常。具体的寄存器如下:
在这里插入图片描述

1.2 用于屏蔽异常和中断的三个特殊寄存器

1.2.1 PRIMASK寄存器

     很多应用中,为了保护临界区代码的安全,需要暂时关闭中断,以执行一些关键的任务,此时就可以使用PRIMASK寄存器。PRIMASK寄存器只能在特权模式下访问
     PRIMASK寄存器可以理解为一个bit位,或者一个开关,置1就会禁止NMI和HardFault外所有异常,它实际上是将当前优先级改为0(即最高的可编程优先级),此时其他的中断都无法被响应,但是是可以被pending住。将PRIMASK置0就重现使能被禁止的中断和异常。具体的代码如下:
     可以使用CMSIS-Core提供的函数来操作寄存器:

void _enable_irq();                      // 清除PRIMASK 置0使能中断
void _disable_irq();                     // 设置PRIMASK 置1禁止中断
void _set_PRIMASK(uint32_t priMask);     // 设置PRIMASK为特定值
uint32_t _get_PRIMASK(void);             // 读取PRIMASK的数值

     同样可以利用汇编语句CPS(修改处理器状态)指令来修改PRIMASK寄存器的数值,具体代码如下:

CPSIE I   ;清除PRIMASK 置0使能中断 E=>Enable
CPSID I   ;设置PRIMASK 置1禁止中断 D=>Disable

     PRIMASK寄存器还可以通过MRS和MSR指令访问,具体代码如下:

MOV R0, #1        ;1写入R0寄存器中
MSR PRIMASK, R0   ;将R0写入到PRIMASK寄存器中,即将1写入到PRIMASK中,禁止中断

MOV R0, #0        ;0写入R0寄存器中
MSR PRIMASK, R0   ;将R0写入到PRIMASK寄存器中,即将0写入到PRIMASK中,使能中断

     当PRIMASK置位时,所有的错误事件都会触发HardFault异常,而不论相应的可配置错误异常(如MemManage、总线错误和使用错误)是否使能

1.2.2 FAULTMASK寄存器

     如下表是异常和中断的相关优先级,FAULTMASK和PRIMASK类似,只是它把当前优先级修改为-1,此时连硬件错误hardfault都无法被响应,只有NMI异常处理才能执行,因为它的优先级为-2。
在这里插入图片描述
     FAULTMASK寄存器只能在特权状态访问,不过不能再NMI和Hardfault处理中设置。若在C编程中使用符合CMSIS的设备驱动,可以使用如下函数来设置和清除FAULTMASK寄存器:

void _enable_fault_irq(void);            // 清除FAULTMASK 置0使能中断
void _disable_fault_irq(void);           // 设置FAULTMASK 置1禁止中断
void _set_FAULTMASK(uint32_t faultMask);
uint32_t _get_FAULTMASK(void);     

     同样FAULTMASK寄存器同样可以用汇编语句来操作:

CPSIE F   ;清除FAULTMASK 置0使能中断 E=>Enable   F=>FAULTMASK
CPSID F   ;设置FAULTMASK 置1禁止中断 D=>Disable

MOV R0, #1        ;1写入R0寄存器中
MSR FAULTMASK, R0   ;将R0写入到FAULTMASK寄存器中,即将1写入到FAULTMASK中,禁止中断

MOV R0, #0        ;0写入R0寄存器中
MSR FAULTMASK, R0   ;将R0写入到FAULTMASK寄存器中,即将0写入到FAULTMASK中,使能中断

     FAULTMASK会在退出异常处理是自动被清除,但是从NMI处理中退出时除外。根据这个特点就可以实现在低优先级中断中触发一个高优先级中断,但这个高优先级中断不会抢占当前的低优先级中断,要等当前的低优先级中断处理完成之后再去执行,具体的操作如下:

  • 在低优先级中设置FAULTMASK禁止所有的中断和异常(除NMI异常除外)
  • 设置高优先级中断或异常的挂起状态
  • 退出处理
         由于FAULTMASK被置位之后中断被禁止了,此时高优先级中断被挂起也无法执行,当当前的低优先级中断执行完退出异常处理,此时FAULTMASK会被自动清除,但是高优先级中断还被挂起,所以就会执行被挂起的高优先级中断。

1.2.3 BASEPRI寄存器

     有些情况下,只想禁止特定优先级的中断,此时就可以使用BASEPRI寄存器。使用方法就是将想要屏蔽的优先级写入到BASEPRI寄存器中。例如:如果想屏蔽优先级小于等于0x60的所有异常(数值越小中断优先级越高),就将0x60写入到BASEPRI寄存器中。具体代码如下:

_set_BASEPRI(0x60);  // 利用CMSIS-Core函数禁止优先级在0x60~0xff之间的中断

uint32_t x;
x = _get_BASEPRI(void); // 读出BASEPRI的数值

_set_BASEPRI(0x00);  // 写0取消BASEPRI屏蔽

     同样的操作也可以用汇编来实现:

MOVS R0, #0x60
MSR BASEPRI, R0      ;禁止优先级在0x60~0xff之间的中断

MRS R0, BASEPRI      ;将BASEPRI的值写入R0寄存器中

MOVS R0, #0x0
MSR BASEPRI, R0      ;取消BASEPRI屏蔽

     BASEPRI寄存器还可以通过另一个名字来访问,BASPRI_MAX。这两个名字指示的是统一个寄存器,就好像同一个人一个大名一个小名。但是使用BASEPRI_MAX这个名字的时候,会得到一个条件写操作,即处理器会自动比较当前值和新的数值,不过只有新的优先级更高(即数值越小)时才会允许修改,否规是不会的,具体的指令如下:

MOVS R0, #0x60
MSR BASEPRI_MAX, R0         ;禁止优先级小于等于0x60的中断

MOVS R0, #0xf0
MSR BASEPRI_MAX, R0         ;由于数值大于0x60,即优先级低于0x60,所以本次操作无效

MOVS R0, #0x40
MSR BASEPRI_MAX, R0         ;由于数值小于0x60,即优先级高于0x60,所以BASEPRI寄存器被修改为0x40

     BASEPRI/BASEPRI_MAX寄存器无法在非特权状态设置。 与其他的优先级寄存器类似,BASEPRI寄存器的格式受实际的优先级寄存器宽度影响。例如如果优先级寄存器值实现了3位,BASEPRI只能被设置为0x00、0x20、0x40···、0xC0和0xE0。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Cortex-M系列中断和异常(三) 的相关文章

  • 详谈高大上的图片加载框架Glide -应用篇

    在Android设备上 xff0c 加载网络图片一直是一个头疼的问题 xff0c 因为Android设备种类繁多 xff08 当然最主要的是配置 xff09 xff0c 处理的稍不周到轻则应用卡顿 xff0c 严重者就会出现OOM的 xff
  • 微信小程序开发环境搭建

    微信小程序可谓是今天最火的一个名词了 xff0c 一经出现真是轰炸了整个开发人员 xff0c 当然很多App开发人员有了一个担心 xff0c 微信小程序的到来会不会给移动端App带来一个寒冬 xff0c 身为一个Android开发者我是不相
  • 实现APP定位功能

    源码传送门 若你不小心点击进入GitHub了捎带给个star 前言 最近更新项目中用的百度定位SDK时遇见了一个奇葩的问题 当升级SDK后百度定位一直返回505 通过百度定位官网查看该码表示AK非法或者不存在 很纠结 于是自己又写了一个de
  • Linux系统命令行创建新文件

    linux命令行创建文件 方法有许多 xff0c 下面简单介绍一下 方法1 使用cat命令 cat span class token operator gt span sample1 span class token punctuation
  • Java利器之UML类图详解

    前言 UML xff08 Unified Modeling Language xff09 中文统一建模语言 xff0c 是一种开放的方法 xff0c 用于说明 可视化 构建和编写一个正在开发的 面向对象的 软件密集系统的制品的开放方法 UM
  • 从零开始学习Linux部署Java web项目

    前言 最近越来越发现需要学习的东西太多了 xff0c 前几天公司服务器出现问题 xff0c 需要对服务器硬件进行维护 xff0c 当然服务器上的服务需要部署到另一个服务器上 这对于我来说是很陌生的 xff0c 虽然这件工作没有让我去做 xf
  • 致敬我奋起直追的2016

    前言 其实当用奋起直追这个词语形容我的2016时 xff0c 自己一度怀疑是不是配得上这个词语 虽然2016成长了不少 xff0c 但是依然没有达到我想要的效果 在学习过程中不断出现越学越倒退的感觉 还偶尔会出现一些恐惧感 不过庆幸的是 x
  • 微信小程序分页加载

    分页加载功能大家遇到的应该会经常遇到 xff0c 应用场景也很多 xff0c 例如微博 xff0c QQ xff0c 微信朋友圈以及新闻类应用 xff0c 都会有分页加载的功能 xff0c 这不仅节省了我们用户的流量 xff0c 还提升了用
  • ReactNative ViewPageAndroid组件详解

    源码传送门 在我们开发Android的时候 xff0c ViewPage这个控件的使用频率还是很高的 xff0c 最简单的就是制作引导页 xff0c 应用程序的主界面等 xff0c 在ReactNative开发中实现该功能的组件是ViewP
  • Android自定义数字键盘

    好久没有写Android的文章了 xff0c 有两三个月多了吧 xff0c 刚开始搞微信小程序 xff0c 后来又开搞ReactNative 现在又兴奋的开搞AI机器学习的东西 xff0c 感觉挺有意思的 xff0c 不过AI与其它的东西相
  • ConstraintLayout基础介绍

    自去年Google I O 大会发布ConstraintLayout至今 xff0c 已有一年多的时间 xff0c 但是并没有普及开来 xff0c 了解过ConstraintLayout布局的人知道 xff0c 它的性能的确提升了不少 在前
  • 嵌入式Linux实战开发之项目总体概述(基于IMX6ULL)

    文章目录 前言 xff08 一 xff09 开发环境 xff08 二 xff09 项目基本概述 xff08 三 xff09 程序框架 xff08 四 xff09 参考资料 前言 现在越来越多的智能设备融入到我们的生活 xff0c 然而 xf
  • Jetson Xavier NX安装opencv3.4.5(小白教程)

    作为小白 xff0c 近期开始上手嵌入式设备Jetson Xavier NX xff0c 系统为Ubuntu 18 04 6 xff0c 而因项目开发环境需要Opencv3 4 5版本 xff0c 预装系统内安装的是Opencv4 1 1
  • tortoisegit安装及实用操作

    TortoiseGit安装及实用操作 TortoiseGit安装TortoiseGit配置TortoiseGit基本操作Git Clone 克隆远程仓库到本地Git Commit 提交改动到本地的版本库Git Push 将本地修改提交到远程
  • linux系统如何开启和关闭core dump

    概述 大多数Linux系统默认开始core dump 我们一方面咱们想要收集信息以提升稳定性 排除故障 xff1b 另外一方面 xff0c 我们又想要限制debug的数据 避免泄漏一些敏感数据 第一个选择适合于研究不稳定的程序的机器 第二个
  • cartographer输出机器人相对地图位姿

    cartographer xff08 0 3 0版本 xff09 中机器人位姿是以tf的格式发布的 cartographer在关于位姿的tf tree为 xff1a map gt odom gt base footprint 其中odom
  • SUMO跟车模型之IDM模型

    IDM 智能交通模型Intelligent Driver Model 优点 xff1a IDM模型的参数数量少 意义明确 xff0c 并且能用统一的模型描述从自由流到完全拥堵流的不同状态 缺点 xff1a 缺乏随机项 xff0c 也就是输入
  • 《Python程序设计与算法基础教程(第二版)》江红 余青松 课后选择题 课后填空题答案

    目录 第一章一 选择题二 填空题 第二章一 选择题二 填空题 第三章一 选择题二 填空题 第四章一 选择题二 填空题 第五章一 选择题二 填空题 第八章一 选择题二 填空题 第一章 一 选择题 Python语言属于 C A 机器语言 B 汇
  • TensorFlow学习(二):变量常量类型

    更新时间 xff1a 2017 2 27 tensorflow 1 0出来了 xff0c API和以前有了一些不一样 xff0c 所以这里把把之前的代码迁移到新的上面去 更新时间 xff1a 2017 5 4 对于一些性质有了新的认识 补充
  • CAN总线的数据校验

    题目来源 有很多网友在QQ上问关于CAN总线上数据需不需要加校验 xff0c 换句话说 xff0c CAN总线支不支持校验 xff0c 我们需要在我们的数据场 xff08 数据域 xff09 加上校验码吗 xff1f 答案是否定的 CAN总

随机推荐

  • TensorFlow中报错 module ‘tensorflow_core._api.v2.train‘ has no attribute ‘GradientDescentOptimize

    原来函数是这样写的 xff1a optimizer 61 tf train GradientDescentOptimizer 报错 xff1a AttributeError module 39 tensorflow core api v2
  • 有趣的黑客网站 | 伪装成黑客高手,像电影黑客一样打字如飞

    当黑客 xff0c 门槛太高 xff1b 装黑客 xff0c 那就太容易了 今天刷知乎的时候无意中看到一个非常神奇的网站 xff0c 能让你瞬间变身成电影中的黑客 xff0c 操作出一系列看起来非常牛逼且装逼的功能 你只管噼里啪啦打字 xf
  • win10共享打印机(连接共享打印机的两种方法,IP地址变化的连接方法)

    一 首先电脑连接打印机 xff0c 把所连接的打印机设置为共享 xff0c 如下图所示 xff1a 先打开电脑设置 xff0c 然后点击设备 打印机和扫描仪 xff0c 打开如下界面 点击管理 打印机属性 xff0c 会出现如下界面 点击共
  • (Python)Pandas reset_index()用法总结

    Pandas是一个数据处理的库 xff0c 今天我们来学习reset index 这个函数的用法 pandas DataFrame reset index 函数作用 xff1a 重置索引或其level 重置数据帧的索引 xff0c 并使用默
  • 用Python批量修改图片名称(后缀)

    当我们需要修改批量即几百幅图片的名称或后缀时 xff0c 如果一个一个图片名称去重命名或是修改的话工作量就会很大 作为一名程序员 xff0c 当然是要通过代码去解决这些繁琐的事情 下面是用python代码来实现批量修改图片名称的代码 xff
  • git基本操作介绍

    简介 本文会简单介绍git的基本操作 这篇文章适合对git的安装 使用 运行环境 工作原理有一定了解的人员阅读 xff1b 对于初学者 xff0c 可以先参考以下文章 xff1a 最新git安装教程 windows系统git安装教程 git
  • Anaconda创建跟别人环境配置一样的虚拟环境(coda env creat -f environment.yml)

    当我们跑别人在github上的代码时 xff0c 往往需要配置跟作者一样的环境 当作者导出自己的环境配置时 xff0c 一般都是 yml文件 xff0c 这时候需要输入命令行来实现配置一模一样的环境 导出的yml文件一般配置如下 xff1a
  • 计算机视觉代码学习

    前言 自从2012年Hinton提出Alexnet以来 xff0c 深度学习 计算机视觉 xff08 CV xff09 就成为一个非常热门的赛道 从学术界到工业界 xff0c 纷纷掀起一股人工智能的浪潮 特别是学术界 xff0c 计算机视觉
  • 如何准备大学生电子设计竞赛

    大学生电子设计竞赛难度中上 xff0c 一般有好几个类型题目可以选择 xff0c 参赛者可以根据自己团队的能力 优势去选择合适自己的题目 xff0c 灵活自主空间较大 参赛的同学们可以在暑假好好学习相关内容 xff0c 把往年的题目拿来练练
  • 聊聊ChatGPT

    ChatGPT 这几周科技圈最火的当属ChatGPT xff0c 自媒体中十篇有九篇都是关于ChatGPT的 ChatGPT上可知天文 xff0c 下可知地理 xff0c 还可写论文 搞代 写小说 xff0c 可谓 全能型选手 自从去年11
  • 修改简历有用吗

    看情况 xff0c 一般都是很有用哒 xff01 简历修改会突出你的重点和优点 xff0c 优化你的简历内容 xff0c 让面试官一眼看到简历就被吸引了 xff01 如以上图片所示
  • 运行Python时出现SyntaxError: EOL while scanning string literal解决方法

    当运行Python时 xff0c 出行SyntaxError EOL while scanning string literal 一般是语法出现错误 xff0c 看一下是不是哪里忘记添加符号或是分号 xff1a 这些没打
  • 数据结构选择练习题(有解析)

    前言 已经到期末了 xff0c 昨天进行了一次马原考试 xff0c 那时候挺紧张的 xff0c 那时候虽然写完了试卷 xff0c 但是有4道题是乱写的 xff0c 因为我刚好没有背 xff0c 希望不会挂科吧 然后今天呢 xff0c 就开始
  • 论文阅读_异常检测综述

    英文题目 xff1a Anomaly Detection A Survey 中文题目 xff1a 异常检测综述 论文地址 xff1a https readpaper com paper 2122646361 领域 xff1a 异常检测 发表
  • 解决Mybatis-Plus分页插件无效

    1 导入依赖 span class token tag span class token tag span class token punctuation lt span dependencies span span class token
  • 一、FreeRTOS任务调度相关函数详解

    文章目录 1 FreeRTOS任务调度及相关函数分析1 1 任务创建过程分析1 1 1 任务创建函数分析1 1 2 任务初始化函数分析1 1 3 任务堆栈初始化分析1 1 4 添加任务到就绪列表 1 2 任务删除过程分析1 3 任务挂起过程
  • linux的exit和_exit

    进程退出 退出一个进程有多种方式 xff1a 正常退出 xff1a 在main函数里return 在进程里面调用exit exit 在进程的最后一个子线程调用pthread exit 异常退出 xff1a 被信号 xff08 9 15 xf
  • 三、任务切换之PendSV异常

    文章目录 PendSV异常1 没有PendSV异常的任务切换2 有PendSV异常的任务切换2 1 系统调用引起的任务切换2 2 systick中断引起任务切换2 3 PendSV异常处理函数2 4 寻找下一个要运行的任务2 5 时间片调度
  • Cortex-M系列中断和异常(一)

    文章目录 1 中断与异常1 1 异常的类型1 2 异常及中断的管理1 2 1 中断的一般使用方法 1 3 优先级的定义1 4 向量表和向量表的重定义1 4 1 向量表重定向的应用场景 1 5 中断输入和挂起行为1 5 1 中断请求的类型 1
  • Cortex-M系列中断和异常(三)

    文章目录 Cortex M系列中断和异常1 1 SCB中的寄存器1 1 1 中断控制和状态寄存器 xff08 SCB gt ICSR xff09 1 1 2 向量表偏移寄存器 xff08 SCB gt VTOR xff09 1 1 3 应用