转自:http://www.21ic.com/embed/jiaocheng/sheji/201209/5634.html

一、STM32 (Cortex-M3) 中的优先级概念

STM32(Cortex-M3)中有两个优先级的概念:抢占式优先级和响应优先级,也把响应优先级称作“亚优先级”或“副优先级”,每个中断源都需要被指定这两种优先级。

1. 何为占先式优先级(pre-emption priority)

高占先式优先级的中断事件会打断当前的主程序/中断程序运行—抢断式优先响应,俗称中断嵌套。

2. 何为副优先级(subpriority)

  • 在占先式优先级相同的情况下,高副优先级的中断优先被响应;
  • 在占先式优先级相同的情况下,如果有低副优先级中断正在执行, 高副优先级的中断要等待已被响应的低副优先级中断执行结束后才能得到响应—非抢断式响应(不能嵌套)

3. 判断中断是否会被响应的依据

首先是占先式优先级,其次是副优先级;

占先式优先级决定是否会有中断嵌套;

Reset、NMI、Hard Fault 优先级为负(高于普通中断优先级)且不可调整。

4. 优先级冲突的处理

具有高抢占式优先级的中断可以在具有低抢占式优先级的中断处理过程中被响应,即中断的嵌套,或者说高抢占式优先级的中断可以嵌套低抢占式优先级的中断。

当两个中断源的抢占式优先级相同时,这两个中断将没有嵌套关系,当一个中断到来后,如果正在处理另一个中断,这个后到来的中断就要等到前一个中断处理完之后才能被处理。如果这两个中断同时到达,则中断控制器根据他们的响应优先级高低来决定先处理哪一个;如果他们的抢占式优先级和响应优先级都相等,则根据他们在中断表中的排位顺序决定先处理哪一个。

5. Cortex-M3中对中断优先级的定义

既然每个中断源都需要被指定这两种优先级,就需要有相应的寄存器位记录每个中断的优先级;在Cortex-M3中定义了8个比特位用于设置中断源的优先级,这8个比特位可以有8种分配方式,如下:

所有8位用于指定响应优先级

  • 最高1位用于指定抢占式优先级,最低7位用于指定响应优先级
  • 最高2位用于指定抢占式优先级,最低6位用于指定响应优先级
  • 最高3位用于指定抢占式优先级,最低5位用于指定响应优先级
  • 最高4位用于指定抢占式优先级,最低4位用于指定响应优先级
  • 最高5位用于指定抢占式优先级,最低3位用于指定响应优先级
  • 最高6位用于指定抢占式优先级,最低2位用于指定响应优先级
  • 最高7位用于指定抢占式优先级,最低1位用于指定响应优先级

这就是优先级分组的概念。

6. stm32中对中断优先级的定义

Cortex-M3允许具有较少中断源时使用较少的寄存器位指定中断源的优先级,因此STM32把指定中断优先级的寄存器位减少到4位,这4个寄存器位的分组方式如下:

  • 第0组:所有4位用于指定响应优先级
  • 第1组:最高1位用于指定抢占式优先级,最低3位用于指定响应优先级
  • 第2组:最高2位用于指定抢占式优先级,最低2位用于指定响应优先级
  • 第3组:最高3位用于指定抢占式优先级,最低1位用于指定响应优先级
  • 第4组:所有4位用于指定抢占式优先级

AIRC(Application Interrupt and Reset Register)寄存器中有用于指定优先级的 4 bits。这4个bits用于分配preemption优先级和sub优先级,在STM32的固件库中定义如下:

/* Preemption Priority Group */
#define NVIC_PriorityGroup_0 ((u32)0x700) /* 0 bits for pre-emption priority
bits for subpriority */
#define NVIC_PriorityGroup_1 ((u32)0x600) /* 1 bits for pre-emption priority
bits for subpriority */
#define NVIC_PriorityGroup_2 ((u32)0x500) /* 2 bits for pre-emption priority
bits for subpriority */
#define NVIC_PriorityGroup_3 ((u32)0x400) /* 3 bits for pre-emption priority
bits for subpriority */
#define NVIC_PriorityGroup_4 ((u32)0x300) /* 4 bits for pre-emption priority
bits for subpriority */

可以通过调用STM32的固件库中的函数NVIC_PriorityGroupConfig()选择使用哪种优先级分组方式,这个函数的参数有下列5种:

  • NVIC_PriorityGroup_0 => 选择第0组
  • NVIC_PriorityGroup_1 => 选择第1组
  • NVIC_PriorityGroup_2 => 选择第2组
  • NVIC_PriorityGroup_3 => 选择第3组
  • NVIC_PriorityGroup_4 => 选择第4组

接下来就是指定中断源的优先级,下面以一个简单的例子说明如何指定中断源的抢占式优先级和响应优先级

// 选择使用优先级分组第1组
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
// 使能EXTI0中断
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = ; // 指定抢占式优先级别1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = ; // 指定响应优先级别0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
// 使能EXTI9_5中断
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = ; // 指定抢占式优先级别0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = ; // 指定响应优先级别1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

--------------------------------------------------------------------------------

要注意的几点是:

1. 如果指定的抢占式优先级别或响应优先级别超出了选定的优先级分组所限定的范围,将可能得到意想不到的结果;

2. 抢占式优先级别相同的中断源之间没有嵌套关系;

3. 如果某个中断源被指定为某个抢占式优先级别,又没有其它中断源处于同一个抢占式优先级别,则可以为这个中断源指定任意有效的响应优先级别。

二、开关总中断

在STM32/Cortex-M3中是通过改变CPU的当前优先级来允许或禁止中断。

PRIMASK位:只允许NMI和hard fault异常,其他中断/异常都被屏蔽(当前CPU优先级=0)。

FAULTMASK位:只允许NMI,其他所有中断/异常都被屏蔽(当前CPU优先级=-1)。

在STM32固件库中(stm32f10x_nvic.c和stm32f10x_nvic.h) 定义了四个函数操作PRIMASK位和FAULTMASK位,改变CPU的当前优先级,从而达到控制所有中断的目的。

  • 下面两个函数等效于关闭总中断
void NVIC_SETPRIMASK(void);
void NVIC_SETFAULTMASK(void);
  • 下面两个函数等效于开放总中断
void NVIC_SETPRIMASK(void);
void NVIC_SETFAULTMASK(void);

上面两组函数要成对使用,但不能交叉使用。

例如:

  • 第一种方法:
NVIC_SETPRIMASK(); //关闭总中断
NVIC_RESETPRIMASK();//开放总中断
  • 第二种方法:
NVIC_SETFAULTMASK(); //关闭总中断
NVIC_RESETFAULTMASK();//开放总中断
  • 常常使用:
NVIC_SETPRIMASK(); // Disable Interrupts
NVIC_RESETPRIMASK(); // Enable Interrupts

-------------------------------------------------------------------------------------------------

补充:

  • 可以用:
#define CLI() __set_PRIMASK(1)
#define SEI() __set_PRIMASK(0)

来实现开关总中断的功能

[STM32].NVIC嵌套中断向量的理解的更多相关文章

  1. STM32——NVIV:嵌套中断向量控制器

    STM32有43个channel的settable的中断源:AIRC(Application Interrupt and Reset Register)寄存器中有用于指定优先级的4 bits.这4个b ...

  2. STM32 NVIC配置详解

    例程:  /* Configure one bit for preemption priority */  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1) ...

  3. STM32的优先级NVIC_PriorityGroupConfig的理解及其使用

    写作原由:因为之前有对stm32 优先级做过研究,但是没时间把整理的东西发表,最近项目需要2个串口,但是不是两个串口同时使用,只是随机使用其中一个,程序对2个串口的优先级需要配置: 此文思路:“中断优 ...

  4. STM32的优先级NVIC_PriorityGroupConfig的理解及其使用(转)

    源:http://blog.csdn.net/yx_l128125/article/details/9703843 写作原由:因为之前有对stm32 优先级做过研究,但是没时间把整理的东西发表,最近项 ...

  5. 10.1 Nested vectored interrupt controller (NVIC) 嵌套矢量中断控制器

    特点 60个可屏蔽中断通道(不包含16个Cortex™-M3的中断线): 16个可编程的优先等级(使用了4位中断优先级): 低延迟的异常和中断处理: 电源管理控制: 系统控制寄存器的实现: 1. 中断 ...

  6. STM32 NVIC

    在stm32中是要配置nvic的.何为nvic,对于我这样的初学者来说,直观感受就是在设置为中断后 还需要配置 中断的优先级nvic就是搞这个的. 那么具体的需要配置些什么那? void NVIC_C ...

  7. 【转】stm32中断嵌套全攻略

    断断续续学习STM32一学期了,时间过的好快,现在对STM32F103系列单片机的中断嵌套及外部中断做一个总结,全当学习笔记.废话不多说,ARM公司的Cortex-m3 内核,支持256个中断,其中包 ...

  8. 【转-Andrew_qian】stm32中断嵌套全攻略

    断断续续学习STM32一学期了,时间过的好快,现在对STM32F103系列单片机的中断嵌套及外部中断做一个总结,全当学习笔记.废话不多说,ARM公司的Cortex-m3 内核,支持256个中断,其中包 ...

  9. 关于STM32下载问题的简单理解

    首先STM32分为两种下载方式1.ISP(IN-SYSTEM-PROGRAMMING在线编程)  2.JTAG 这里简单谈谈对ISP下载的理解: ISP下载是51单片机,STM等单片机比较常见的一种下 ...

随机推荐

  1. OpenStack总体架构概览&OpenStack核心组件介绍

    下面个是51CTO上一位朋友发布的O版OpenStack核心组件说明,总结的非常到位,所以我就不再造轮子了.~,~ https://down.51cto.com/data/2448945 私有云 公有 ...

  2. Computer-Hunters——团队展示

    Computer-Hunters--团队展示 这个作业属于哪个课程 https://edu.cnblogs.com/campus/fzu/2019FZUSEZ 这个作业要求在哪里 https://ed ...

  3. Java 并发系列之二:java 并发机制的底层实现原理

    1. 处理器实现原子操作 2. volatile /** 补充: 主要作用:内存可见性,是变量在多个线程中可见,修饰变量,解决一写多读的问题. 轻量级的synchronized,不会造成阻塞.性能比s ...

  4. git使用问题与技巧

    1.修改gitolite管理员 如果gitolite原来的管理员已经没了,那么需要把当前的公钥放到服务器覆盖,然后替换目录下.ssh/authorized_keys内容 2.clone报告超过限制 w ...

  5. 疯了!同事又问我为什么不能用 isXXX

    最近在做Code Review,写下了这篇文章:代码写成这样,老夫无可奈何!,说多了都是泪啊.. 最近又有人同事跑过来质疑我: 为什么变量名取名不能用 isXXX 这种方式,这样有什么问题?! 醉了, ...

  6. 每月IT摘录201911

    技术 1.以 MySQL 的 InnoDB 引擎为例,由于 MySQL 中有两套日志机制,一套是存储层的 redo log,另一套是 server 层的 binlog,每次更新数据都要对两个日志进行更 ...

  7. 【技术博客】Postman接口测试教程 - 环境、附加验证、文件上传测试

    Postman接口测试教程 - 环境.附加验证.文件上传测试 v1.0 作者:ZBW 前言 继利用Postman和Jmeter进行接口性能测试之后,我们发现Postman作为一款入门容易的工具,其内置 ...

  8. 【操作系统之十】内存分页管理与swap

    一.虚拟内存电脑里内存分内存条(这里我们叫物理内存)和硬盘,内存条保存程序运行时数据,硬盘持久保存数据.那么虚拟内存是什么? 程序运行会启动一个进程,进程里有程序段.全局数据.栈和堆,这些都会加载到内 ...

  9. Docker方式安装SonarQube

    获取镜像 docker pull postgres: docker pull sonarqube:-community 启动镜像 docker run -d -p : -e POSTGRES_PASS ...

  10. c# 数据请求方式提供

    营销平台数据请求介绍 项目介绍: 前端使用 WPF,采用MVVM模式  后端数据库采用的sqlite 依靠本地化运行   后期可能会采用WebApi   因为WPF都是自学的 所以 代码方面写的可能不 ...