一、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

  4 bits for subpriority */

  #define NVIC_PriorityGroup_1 ((u32)0x600) /* 1 bits for pre-emption priority

  3 bits for subpriority */

  #define NVIC_PriorityGroup_2 ((u32)0x500) /* 2 bits for pre-emption priority

  2 bits for subpriority */

  #define NVIC_PriorityGroup_3 ((u32)0x400) /* 3 bits for pre-emption priority

  1 bits for subpriority */

  #define NVIC_PriorityGroup_4 ((u32)0x300) /* 4 bits for pre-emption priority

  0 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; // 指定抢占式优先级别1

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 指定响应优先级别0

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStructure);

  // 使能EXTI9_5中断

  NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQChannel;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 指定抢占式优先级别0

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // 指定响应优先级别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_RESETPRIMASK(void);

  void NVIC_RESETFAULTMASK(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的资料便于参考学习

(STM32中断系统)
http://www.makeru.com.cn/live/1392_1124.html?s=45051

基于STM32-WiFi智能小车机器人开发实战
http://www.makeru.com.cn/course/details/3008?s=45051

ARM之中断GIC分析
http://www.makeru.com.cn/live/1758_328.html?s=45051

嵌入式操作系统uC/OS
http://www.makeru.com.cn/live/5413_2094.html?s=45051

关于STM32 (Cortex-M3) 中NVIC的分析的更多相关文章

  1. STM32学习之路入门篇之指令集及cortex——m3的存储系统

    STM32学习之路入门篇之指令集及cortex——m3的存储系统 一.汇编语言基础 一).汇编语言:基本语法 1.汇编指令最典型的书写模式: 标号 操作码        操作数1, 操作数2,... ...

  2. ARM 架构、ARM7、ARM9、STM32、Cortex M3 M4 、51、AVR 之间有什么区别和联系?(转载自知乎)

    ARM架构:  由英国ARM公司设计的一系列32位的RISC微处理器架构总称,现有ARMv1~ARMv8种类. ARM7:       一类采用ARMv3或ARMv4架构的,使用冯诺依曼结构的内核. ...

  3. stm32和cortex M3学习内核简单总结

    1.stm32综述 2.寄存器组 3.操作模式和特权级别 4.存储器映射 5.中断和异常 6.其他 Stm32综述 这可以说是我第一款认真学习的单片机了,学完这个就要开启我通往arm9的大门了,接下来 ...

  4. ARM Cortex M3系列GPIO口介绍(工作方式探讨)

    一.Cortex M3的GPIO口特性    在介绍GPIO口功能前,有必要先说明一下M3的结构框图,这样能够更好理解总线结构和GPIO所处的位置. Cortex M3结构框图     从图中可以看出 ...

  5. ARM Cortex M3(V7-M架构)硬件启动程序 一

    Cortex-m3启动代码分析笔记 启动代码文件名是STM32F10X.S,它的作用先总结下,然后再分析. 启动代码作用一般是: 1)堆和栈的初始化: 2)中断向量表定义: 3)地址重映射及中断向量表 ...

  6. 【freertos】002-posix模拟器设计与cortex m3异常处理

    目录 前言 posix 标准接口层设计 模拟器的系统心跳 模拟器的task底层实质 模拟器的任务切换原理 cortex M3/M4异常处理 双堆栈指针 双操作模式 栈帧 EXC_RETURN 前言 如 ...

  7. Android中AppWidget的分析与应用:AppWidgetProvider .

    from: http://blog.csdn.net/thl789/article/details/7887968 本文从开发AppWidgetProvider角度出发,看一个AppWidgetPrv ...

  8. JAVA WEB 中的编码分析

    JAVA WEB 中的编码分析 */--> pre.src {background-color: #292b2e; color: #b2b2b2;} pre.src {background-co ...

  9. Android 中图片压缩分析(上)

    作者: shawnzhao,QQ音乐技术团队一员 一.前言 在 Android 中进行图片压缩是非常常见的开发场景,主要的压缩方法有两种:其一是质量压缩,其二是下采样压缩. 前者是在不改变图片尺寸的情 ...

随机推荐

  1. Tars | 第8篇 TarsJava Subset最终代码的执行流程与原理分析

    目录 前言 1. SubsetConf配置项的结构 1.1 SubsetConf 1.2 RatioConfig 1.3 KeyConfig 1.4 KeyRoute 1.5 SubsetConf的结 ...

  2. vue2.0 前端框架

    在正式开始先复习一下js基础.因为vue最通终也要操作这些元素,vue和以前学的js并不挂勾,他和传统的jquert  设计理念相反 ## js 数据类型 1 基本类型 number  string  ...

  3. CPU到底是什么东西?它为什么能够执行数学运算?

    CPU到底是什么东西?它为什么能够执行数学运算? 本文地址http://yangjianyong.cn/?p=20转载无需经过作者本人授权 简单的物理电路 先来看一张初中学过的物理电路图: 从图中我们 ...

  4. Java基础系列(14)- JavaDoc生成文档

    JavaDoc JavaDoc是一种将注释生成HTML文档的技术,生成的HTML文档类似于Java的API,易读且清晰明了 参数信息 @author 作者名 @version 版本号 @since 指 ...

  5. 手把手教你 Docker搭建nacos单机版

    Docker搭建nacos单机版步骤 一.使用 docker pull nacos/nacos-server 拉取nacos镜像 我这里没有指定版本所以是拉取latest,你也可以使用 docker ...

  6. tomcat URI get 参数中文传到后台 乱码 URIEncoding

    * 修改tomcat server.xml 找到这一行 <Connector connectionTimeout="20000" port="80" pr ...

  7. GUI自动化测试遇到的问题

    学习接口自动化测试框架或工具,UI自动化测试框架或工具,有时会觉得知识似乎比较零散,死记硬背不是一个好方法.一个学习的思路是思考使用这些框架或工具的时候,可能会遇到什么问题,遇到这些问题可以通过什么方 ...

  8. sqlalchemy ————关联表

    1.创建模型的时候做外键关联 class UI_ID(db.Model): __tablename__ = 'ui_id' id = db.Column(INTEGER(11), primary_ke ...

  9. 简单易行的美化方案:Ubuntu 18.04 把启动过程中的紫色美化为黑色

    背景 给笔记本装了一个Ubuntu,嫌弃启动的颜色很丑:因此在网上找到了一些修改方法,集成为一个傻瓜脚本. 参考文档: https://askubuntu.com/questions/5065/how ...

  10. P6628-[省选联考 2020 B 卷] 丁香之路【欧拉回路,最小生成树】

    正题 题目链接:https://www.luogu.com.cn/problem/P6628 题目大意 给出\(n\)个点的一张完全无向图,\(i\sim j\)的边权是\(|i-j|\). 然后给出 ...