Cortex-M0中断控制和系统控制

news2024/11/16 15:55:22

目录

  • 1.NVIC和系统控制块特性
  • 2.中断使能和清除使能
  • 3.中断挂起和清除挂起
  • 4.中断优先级
  • 5.中断控制的通用汇编代码
    • 使能和禁止中断
    • 设置和清除中断挂起状态
    • 设置中断优先级
  • 6.异常屏蔽寄存器(PRIMASK)
  • 7.中断输入和挂起行为
  • 8.中断等待
  • 9.系统异常的控制寄存器
  • 10.系统控制寄存器

1.NVIC和系统控制块特性

嵌套向量中断控制器(NVIC)集成在Cortex-M0处理器里,它与处理器内核紧密相连,并且提供了中断控制功能以及对系统异常的支持。

除了NVIC,系统控制块(SCB)位于系统控制空间(SCS)地址区域。SCB具有的特性可以给操作系统提供支持,例如SysTick异常对应的内部定时器。

NVIC的特性如下:

  • 灵活的中断管理:使能/禁止,优先级配置。
  • 硬件嵌套中断支持。
  • 向量化的异常入口。
  • 中断屏蔽。

Cortex-M0处理器中的NVIC支持最多32个外部中断和一个不可屏蔽中断(NMI),中断输入请求可以是电平触发的,也可以是最小一个时钟周期的脉冲信号。每个外部中断都可以独立地使能或禁止,并且其挂起状态也可以手动地设置和清除。

NVIC的寄存器经过了存储器映射,并且用C语言访问也很容易,其寄存器的起始地址为0xE000E100。对于Cortex-M0处理器,对NVIC寄存器的访问必须是每次一个字。

同NVIC 寄存器类似,SCB寄存器也是按照字来访问的,起始地址为0xE000E010。SCB寄存器涉及的特性包括SysTick定时器操作、系统异常管理、优先级控制和休眠模式控制。

2.中断使能和清除使能

中断控制寄存器为可编程的,用于控制中断请求(异常编号16及以上)的使能和禁止。寄存器的宽度根据支持的中断数量而不同,最大为32位,最小为1位。可以通过两个独立的地址编程这个寄存器,使能中断时使用SETENA地址,而禁止中断时则使用CLRENA地址:
在这里插入图片描述
将设置和清除操作分为两个不同的地址具有诸多优势。
首先,它减少了使能中断所需要的步骤,因此也就减少了程序代码并且降低了执行时间。
多个应用程序进程同时访问寄存器时,可能会导致已编程的控制信息丢失,而设置和清除的分离则能防止这种情况的发生,这也是这种安排的第二个优势。

3.中断挂起和清除挂起

如果一个中断发生了,却无法立即处理(比如处理器正在处理更高优先级的中断),这个中断请求将会被挂起。挂起状态保存在一个寄存器中,如果处理器的当前优先级还没有降低到可以处理挂起的请求,并且没有手动清除挂起状态,该状态将会一直保持合法。

可以通过操作中断设置挂起(SETPEND)和中断清除挂起(CLRPEND)这两个寄存器来访问或修改中断挂起状态。

同中断使能控制寄存器类似,中断挂起状态寄存器也是在物理上为一个寄存器,而通过两个地址来实现设置和清除相关位。这就使得每一位都可以独立修改,而无须担心在两个应用程序进程竞争访问时出现的数据丢失。
在这里插入图片描述

4.中断优先级

每一个外部中断都有一个对应的优先级寄存器,每个优先级都是2位宽,并且使用中断优先级寄存器的最高两位,每个寄存器占1个字节(8位)。

Cortex-M0中的NVIC寄存器只支持字传输,这样每次访问都会同时涉及4个中断优先级寄存器。
在这里插入图片描述
未使用的位读出为0,写入这些位的操作会被忽略,而读出时则为0。
在这里插入图片描述
由于每次访问优先级寄存器就相当于访问4个中断的优先级,如果只想改变其中的1个,需要将整个字读出,修改1个字节,然后写回整个字。

中断优先级寄存器的编程应该在中断使能之前,其通常是在程序开始时完成的。应该避免在中断使能之后改变中断优先级,因为这种情况的结果在ARMv6-M体系结构上是不可预知的,并且不被Cortex-M0处理器支持。

5.中断控制的通用汇编代码

使能和禁止中断

中断的禁止和使能非常简单,下面的函数“nvic_set_enable”和“nvic_clr_enable”以中断编号作为输入,中断编号在函数调用前保存在R0中:
在这里插入图片描述
要使用这些函数,只需要将中断编号放在R0中,然后调用函数即可,例如:
在这里插入图片描述
在ARM汇编器中(包括 Keil MDK),FUNCTION和ENDFUNC这两个关键字分别用于指示函数的开始和结束,它们的使用是可选的,ALIGN关键字则保证了函数的开始处于正确的对齐地址上。

设置和清除中断挂起状态

  • 设置和清除中断挂起状态的汇编函数同使能和禁止中断的类似,唯一的区别在于标号和NVIC寄存器的地址不同。
    在这里插入图片描述在这里插入图片描述

  • 应该注意的是,清除某中断的挂起状态未必能够完全阻止中断的产生。如果中断源持续产生中断请求(电平输出),即便你试图清除NVIC的寄存器,中断挂起状态仍可能保持为高。

设置中断优先级

  • 设置中断优先级的汇编函数稍微复杂一些。首先,它需要两个输入参数:中断编号和新的优先级;其次,由于总共有多达8个的优先级寄存器,还需要计算要修改的中断所在的位置;最后,由于优先级寄存器是按照字来访问的,还需要执行读-修改-写的过程,才能把正确的字节数据写到32位优先级寄存器中。
    在这里插入图片描述
    在这里插入图片描述

  • 不过,在大多数应用程序中,可以在程序的开始部分,使用更加简单的代码一次设置多个中断的优先级。例如,可以将优先级预定义在一个常数表中,然后使用一个很短的指令序列将这个表复制到NVIC优先级寄存器中。
    在这里插入图片描述

6.异常屏蔽寄存器(PRIMASK)

  • 异常屏蔽寄存器(PRIMASK)可以屏蔽掉除了NMI和硬件错误异常的其他所有的中断和系统异常。
  • PRIMASK寄存器只有1位有效,并且在复位后默认为0。该寄存器为0时,所有的中断和异常都处于允许状态;而设为1后,只有NMI和硬件错误异常处于使能。实际上,当PRIMASK 设置为1后,处理器的当前优先级就降到了0(可设置的最高优先级)。
  • 对时间敏感的程序完成后,应该清除PRIMASK。要不然即使在中断处理中使用了_disable_irq()函数(或者设置PRIMASK),处理器将停止接受新的中断请求。这点与ARM7TDMI有所不同,ARM7TDMI处理器在中断返回时,由于CPSR的恢复,其I位会被重设(使能中断)。而Cortex-MO处理器的PRIMASK和xPSR是相互独立的,因此异常返回不会影响中断屏蔽状态。

7.中断输入和挂起行为

Cortex-M0处理器允许两种形式的中断请求:电平触发以及脉冲输入,这一特性涉及包括NMI在内的中断输入对应的多个寄存器。每一个中断输入都对应着一个挂起状态寄存器,且每个寄存器只有1位,用于保存中断请求,而不管这个请求有没有得到确认(例如,通过I/O引脚相连的外部硬件产生一个中断脉冲)。当处理器开始处理这个异常时,硬件将会自动清除挂起状态。

NMI的情况也基本上是一样的,只是由于NMI的优先级最高,当它产生后几乎能立即得到响应。除此之外,NMI与IRQ相当类似:NMI的挂起状态也可以由软件产生,如果处理器仍然在处理之前的NMI请求,新的NMI则会保持挂起状态。

一些简单的中断处理如下:

  • 大多数ARM处理器的外设都使用电平触发中断输出,当中断事件发生时,由于外设连接到了NVIC上,中断信号会得到确认。在处理器执行中断服务并且清除外设的中断信号以前,该信号会保持高电平。在NVIC内部,当检测到有中断发生时,该中断的挂起状态会被置位,当处理器接受该中断并且开始执行中断服务程序后,挂起状态就会被清除。
    在这里插入图片描述

  • 有些中断源可能会产生脉冲形式的中断请求(至少持续1个时钟周期)。在这种情况下,在中断得到服务之前,挂起状态寄存器将会一直保持该请求。
    在这里插入图片描述

  • 如果中断请求没有立即执行,并且在确认之前被软件清除了,这样处理器会忽略掉本次请求,并且不会执行中断处理。可以通过写NVIC_CLRPEND寄存器来清除中断挂起状态,这种处理在设置外设时非常有用,因为在设置以前,该外设可能已经产生了一个中断请求。
    在这里插入图片描述

  • 如果在软件清除挂起状态时,外设仍然保持着中断请求,挂起状态还会立即生成。
    在这里插入图片描述

  • 如果外设产生的中断请求在异常处理时没有被清除,异常返回后挂起状态就会被又一次激活,这样中断服务程序会再次执行,若外设中还有待处理的数据这种情况就会发生(例如,只要接收FIFO中还有数据,数据接收机就要将中断请求保持高电平)。
    在这里插入图片描述

  • 对于脉冲中断,如果在中断服务开始执行以前,中断请求脉冲产生了多次(例如,处理器可能在处理另外一个中断请求),这种多个中断脉冲会被当做一次中断请求。
    在这里插入图片描述

  • 在中断服务程序执行过程中产生的脉冲中断请求,会被当做新的中断请求,并且在本次中断退出后,还会引起中断服务程序再次执行。
    在这里插入图片描述
    由于和当前执行中断的优先级相同,故第二个中断请求不会立即引发中断。一旦处理器退出了中断处理,当前的优先级就会降低,这样挂起的中断就会得到获取服务的机会。
    即使某中断已经被禁止,该中断的挂起状态仍然可以被激活。因此,当外设需要重新编程以及更改中断设置时,在重新使能中断前,你可能需要清除NVIC里的中断挂起状态,这个操作可以通过写入地址为0xE000E280的中断清除寄存器来实现。

8.中断等待

通常情况下,Cortex-M0的中断等待时间为16个周期。这个等待时间从中断确认的处理器时钟周期开始,一直到中断处理开始执行结束。计算中断等待需要具备以下前提:

  • 该中断使能并且没有被PRIMASK或是其他正在执行的异常处理所屏蔽。
  • 存储器系统没有任何等待状态。

下面几种情况可能会导致不同的中断等待:

  • 中断的末尾连锁,如果中断返回时产生了另外一个中断请求,处理器就会跳过出栈和压栈过程,这样就减少了中断等待时间。
  • 延迟到达,如果中断发生时,另外一个低优先级的中断正在进行压栈处理,由于延迟到达机制的存在,高优先级的中断会首先执行,这样也会导致高优先级的中断的等待时间减小。

上面这两种情况会使得中断等待减至最小,不过有些嵌入式应用需要零误差的中断响应。Cortex-M0处理器的接口上有一个叫做IRQLATENCY的8位信号,并且它与NVIC相连,可以用作中断等待控制。如果将这个信号连接到0,Cortex-M0处理器就会以最快的速度处理中断请求。

9.系统异常的控制寄存器

对于Cortex-M0处理器,只有3个与OS相关的系统异常才具有可编程的优先级,它们包括SVC、PendSV和SysTick,其他像NMI和硬件错误等系统异常的优先级则是固定的。

在这里插入图片描述
未使用的位读出为0,对这些未使用的位的写操作将会被忽略。Cortex-M0处理器只使用系统处理优先级寄存器SHPR2和SHPR3。
在这里插入图片描述
如果使用符合CMSIS的设备驱动,可以使用如下图所示的寄存器名来访问SHPR2和SHPR3。
在这里插入图片描述
另一个对系统异常处理有用的寄存器为中断控制状态寄存器(ICSR),这个寄存器允许软件挂起NMI异常,并且可以访问PendSV和SysTick的挂起状态。它还提供了对调试器有用的信息,例如当前活跃的异常编号以及当前是否有挂起异常。
在这里插入图片描述
如果使用符合CMSIS的设备驱动库,可以使用寄存器名“SCB->ICSR”访问ICSR。

10.系统控制寄存器

NVIC地址区域(从0xE000E000到0xE000EFFF)中也包含了多个系统控制寄存器,因此NVIC的整个存储器区域又被称作系统控制空间(SCS)。

  • CPU ID基址寄存器

CPU ID基址寄存器中包含了处理器的ID,并且是只读的,它为应用软件以及调试器提供了处理器内核类型和版本信息。
在这里插入图片描述

  • 应用中断和复位控制寄存器
    应用中断和复位控制寄存器(AIRCR)具有多个功能,它可以用于应用程序请求系统复位、识别系统的大小端以及清除所有的异常活动状态(只能由调试器完成)。如果使用符合CMSIS的设备驱动,可以使用“SCB->AIRCR”访问该寄存器。
    在这里插入图片描述

VECTKEY域用于防护对该寄存器的意外写操作引起的系统复位或清除异常状态。

SYSRESETREQ位用于请求系统复位,当写入1并且键值合法时,它就会触发处理器上的SYSRESETREQ信号,系统的实际复位时间与这个信号的连接方式有关。根据系统复位设计的不同,从该位写入1到实际复位可能只需要很小的一段延时。在典型的微控制器设计中,SYSRESETREQ产生的系统复位可以对处理器和系统的大部分都有效,而不应影响微控制器的调试系统。这样即使软件触发了一次复位,调试操作也可以正常工作。

VECTCLRACTIVE位被调试器用来清除异常状态,比如当调试要执行程序返回而不想复位处理器时,就可以使用该位,处理器上运行的应用程序代码不应使用这一特性。

  • 配置和控制寄存器

Cortex-M0处理器上的配置和控制寄存器(CCR)为只读的,它决定了栈的双字对齐设置和非对齐访问的处理。

在这里插入图片描述
STACKALIGN为1,表示当产生异常压栈时,栈帧总是自动对齐到双字对齐的存储器位置上。UNALIGN_TRP位为1,表示试图执行非对齐访问的操作会导致错误异常发生。如果使用符合CMSIS的设备驱动,可以通过寄存器名“SCB->CCR”来访问配置和控制寄存器。

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

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

相关文章

JuiceFS 在火山引擎边缘计算的应用实践

火山引擎边缘云是以云计算基础技术和边缘异构算力结合网络为基础,构建在边缘大规模基础设施之上的云计算服务,形成以边缘位置的计算、网络、存储、安全、智能为核心能力的新一代分布式云计算解决方案。边缘存储主要面向适配边缘计算的典型业务场景&#…

Python seek()和tell()函数详解

在讲解 seek() 函数和 tell() 函数之前,首先来了解一下什么是文件指针。我们知道,使用 open() 函数打开文件并读取文件中的内容时,总是会从文件的第一个字符(字节)开始读起。那么,有没有办法可以自定指定读…

分布式事务实现机制及二阶段提交

注:本文章引自终于把分布式事务讲明白了! 分布式事务 分布式事务是指在分布式环境下事务,一个事务由多个数据库节点共同完成。分布式事务也必须要保证事务的ACID的特性。 实现分布式事务原子性的通常做法就是采用两阶段提交协议&#xff0c…

07- Rossmann商店销售预测 (Xgboost集成算法) (项目七)

查看数据是否为空: train.isnull().sum()查看特征元素: train[StateHoliday].unique() # array([0, a, b, c], dtypeobject)绘制热力图: sns.heatmap(df_train.corr(),cmap RdYlGn_r,annotTrue,vmin -1,vmax1)合并商店信息和销售数据: train pd.merge(train, store, on …

高校房产管理系统有哪些管理功能范围?

数图互通高校房产管理系统是基于公司自主研发的FMCenterV5.0平台,是针对中国高校房产的管理特点和管理要求,研发的一套标准产品;通过在中国100多所高校的成功实施和迭代,形成了一套成熟、完善、全生命周期的房屋资源管理解决方案。…

世界上最健康的程序员作息表!「值得一看」

昨晚看了一篇“传说中”的“世界上最健康的作息时间表”,开始纠结自己还要不要5点半起床。 都说程序员这一行,猝死概率极高,究其原因还是加班太狠、作息不规律、缺乏运动… 今天和大家分享一下这篇文章,还是非常值得参考的&#…

基于Java+SpringBoot+Vue+Uniapp前后端分离商城系统设计与实现

博主介绍:✌全网粉丝3W,全栈开发工程师,从事多年软件开发,在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战✌ 博主作品:《微服务实战》专栏是本人的实战经验总结,《Spring家族及…

PyQt5 界面预览工具

简介 一款为了预览PyQt5设计的UI界面而开发的工具,使用时需要结合PyCharm同时使用。 下载 PyQt5界面预览工具 参数说明 使用配置 启动PyCharm,找到File -> Settings,打开 找到Tools -> External Tools点击打开,在新界面…

GuLi商城-SpringCloud Alibaba-Nacos注册中心

简介: Nacos(Dynamic Naming and Configuration Service)是构建以 “服务” 为中心的现代应用架构 (例 如微服务范式、云原生范式) 的服务基础设施。致力于服务发现、配置和管理,且提供了一组简单 易用的特性集。让微服务的发现…

GEE学习笔记 八十一:【GEE之Python版教程十二】

这一节介绍一下日期类,那么GEE基础的类型基本上介绍完成。后续开始介绍GEE在遥感GIS处理上的一些API内容,比如矢量数据、栅格数据处理等。 这段代码是在程序之前必须执行的,用来注册GEE。 import ee ee.Initialize() 1、日期类API 首先看一…

C语言-文件操作-10

题目&#xff1a; 修改下列程序&#xff0c;用命令行界面代替交互式界面 #include <stdio.h> #include <stdlib.h> #include <string.h> #define BUFSIZE 4096 #define SLEN 81 void append(FILE * source,FILE * dest); char * s_gets(char * st,int n); i…

Spring3定时任务

简介 Spring 内部有一个 task 是 Spring 自带的一个设定时间自动任务调度&#xff0c;提供了两种方式进行配置&#xff0c;一种是注解的方式&#xff0c;而另外一种就是 XML 配置方式了;注解方式比较简洁&#xff0c;XML 配置方式相对而言有些繁琐&#xff0c;但是应用场景的不…

借助 APISIX Ingress,实现与注册中心的无缝集成

作者张晋涛&#xff0c;API7.ai 云原生技术专家&#xff0c;Apache APISIX PMC 成员&#xff0c;Apache APISIX Ingress Controller 项目维护者。 原文链接 云原生场景下是否需要服务发现 背景 微服务架构是当前最为流行的应用架构之一。 应用被拆分为多个服务组件&#xff…

流批一体架构在快手的实践和思考

摘要&#xff1a;本文整理自快手技术专家、Apache Flink & Apache Calcite Committer 张静&#xff0c;在 FFA 流批一体专场的分享。本篇内容主要分为四个部分&#xff1a;Flink 在快手的发展流批一体在快手的规划第一阶段&#xff08;加强批能力&#xff09;的进展第二阶段…

什么是refresh?Spring refresh 流程

refresh 是 AbstractApplicationContext 中的一个方法&#xff0c;负责初始化 ApplicationContext 容器&#xff0c;容器必须调用 refresh 才能正常工作。它的内部主要会调用 12 个方法&#xff0c;我们把它们称为 refresh 的 12 个步骤&#xff1a;1. prepareRefresh2. obtain…

js将数字转十进制+十六进制(联动el-ui下拉选择框)

十进制与十六进制的整数转化一、十进制转十六进制二、十六进制转十进制三、联动demo一、十进制转十六进制 正则表达式&#xff1a; /^([0-9]||([1-9][0-9]{0,}))$/解析&#xff1a;[0-9]代表个位数&#xff0c;([1-9][0-9]{0,})代表十位及以上 二、十六进制转十进制 正则表达…

问卷数据分析流程

文章目录一、数据合并1. 读取数据2. 数据预览二、数据清洗1. 检验ID是否重复&#xff0c;剔除ID重复项2. 剔除填写时间小于xx分钟的值3.处理 量表题 一直选一个选项的问题三、数据清洗1.1 将问卷单选题的选项code解码&#xff0c;还原成原来的选项1.2 自动获取单选题旧的选项列…

object类的equals和hashCode

Object类–基类 equals方法 Object类中的equals方法,底层是用的是""来实现的, 如果比较的两个数是基本类型,就是在比较其值是否相等; 如果比较的两个数是引用数据类型,那么就是比较其地址是否相等 如果输出语句是System.out.println(ab) 输出的是false ,因为a和b …

AcWing 841. 字符串哈希

题目描述 分析&#xff1a; 字符串 hash 小试牛刀 我们在之前模拟散列时&#xff0c;设置的哈希函数为将一个元素(element, e)输入哈希函数中&#xff0c;输出是一个整数&#xff0c;而那时的 eee 为一个有范围的整数。现在我们考虑更复杂的情形&#xff0c;eee 为一个字符串…

论文笔记NeRF: Representing Scenes as Neural Radiance Fields for View Synthesis

NeRF使用神经网络来表示场景。给定一个场景&#xff0c;输入该场景稀疏的视角图片&#xff0c;NeRF可以合成该场景新的视角的图片。 神经辐射场 神经辐射场&#xff08;neural radiance field&#xff0c;NeRF&#xff09;使用5D的向量值函数表示一个场景。 输入是连续的5D坐…