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

中断优先级分组
STM32(Cortex-M3)中有两个优先级的概念--抢占式优先级和响应优先级,有人把响应优先级称作'亚优先级'或'副优先级',每个中断源都需要被指定这两种优先级。
具有高抢占式优先级的中断可以在具有低抢占式优先级的中断处理过程中被响应,即中断嵌套,或者说高抢占式优先级的中断可以嵌套在低抢占式优先级的中断中。
当两个中断源的抢占式优先级相同时,这两个中断将没有嵌套关系,当一个中断到来后,如果正在处理另一个中断,这个后到来的中断就要等到前一个中断处理完之后才能被处理。如果这两个中断同时到达,则中断控制器根据他们的响应优先级高低来决定先处理哪一个;如果他们的抢占式优先级和响应优先级都相等,则根据他们在中断表中的排位顺序决定先处理哪一个。
Cortex内核具有强大的异常响应系统,它把能够打断当前代码执行流程的事件分为异常(exception)和中断(interrupt),并把它们用一个表管理起来,编号为0~15的称为内核异常,而16以上的则称为外部中断,这个表就称为中断向量表。
正是因为每个中断源都需要被指定这两种优先级,就需要有相应的寄存器位记录每个中断的优先级;在Cortex-M3中定义了8个比特位用于设置中断源的优先级,这8个比特位可以有8种分配方式,如下:
- 所有8位用于指定响应优先级
- 最高1位用于指定抢占式优先级,最低7位用于指定响应优先级
- 最高2位用于指定抢占式优先级,最低6位用于指定响应优先级
- 最高3位用于指定抢占式优先级,最低5位用于指定响应优先级
- 最高4位用于指定抢占式优先级,最低4位用于指定响应优先级
- 最高5位用于指定抢占式优先级,最低3位用于指定响应优先级
- 最高6位用于指定抢占式优先级,最低2位用于指定响应优先级
- 最高7位用于指定抢占式优先级,最低1位用于指定响应优先级
以上便是优先级分组的概念,但是Cortex-M3允许具有较少中断源时使用较少的寄存器位指定中断源的优先级。
而STM32对这个表重新进行了编排,把编号从-3至6的中断向量定义为系统异常,编号为负的内核异常不能被设置优先级,如复位(Reset)、不可屏蔽中断 (NMI)、硬错误(Hardfault)。从编号 7开始的为外部中断,这些中断的优先级都是可以用户更改的。详细的 STM32中断向量号可以在startup_stm32f10x_XX.s中查找。
因此STM32把指定中断优先级的寄存器位减少到4位,这4个寄存器位的分组方式如下:
第0组:所有4位用于指定响应优先级(16种)
第1组:最高1位用于指定抢占式优先级,最低3位用于指定响应优先级(8种)
第2组:最高2位用于指定抢占式优先级,最低2位用于指定响应优先级(4种)
第3组:最高3位用于指定抢占式优先级,最低1位用于指定响应优先级(2种)
第4组:所有4位用于指定抢占式优先级
这里便对于于文章最前提到的固件库里相关的函数了——NVIC_PriorityGroupConfig(u32 NVIC_PriorityGroup),函数的参数共有5种:
这个函数的参数(NVIC_PriorityGroup值)有下列5种:
NVIC_PriorityGroup_0 => 选择第0组 NVIC_PriorityGroup_1 => 选择第1组 NVIC_PriorityGroup_2 => 选择第2组 NVIC_PriorityGroup_3 => 选择第3组 NVIC_PriorityGroup_4 => 选择第4组 //NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
这其实也很好理解,比如选择NVIC_PriorityGroup_1,那么抢占式优先级便占一位,也就是说可以有2^1个级别,可以设置为0和1,而响应优先级则占3位,也就是说可以有2^3个选择,可以设置为0~7;总共来说就可以区别>16种优先级了。
举个例子
void NVIC_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
#ifdef VECT_TAB_RAM
//Set the Vector Table base location at 0x20000000
NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
#else
//Set the Vector Table base location at 0x08000000
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
#endif
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); //中断优先级组 :1组(整个系统为同一组)
// 设置抢占优先级0~1,响应优先级0~7
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; // TIM2 全局中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = ; // 抢占优先级 1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = ; // 响应优先级 0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // IRQ通道被使能
NVIC_Init(&NVIC_InitStructure);
//* Enable the TIM3 Interrupt
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; // TIM3 全局中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = ; // 抢占优先级 1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = ; // 响应优先级 1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // IRQ通道被使能
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; // USART1 全局中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = ; // 抢占优先级 0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = ; // 响应优先级 0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // IRQ通道被使能
NVIC_Init(&NVIC_InitStructure);
}
说明:假如TIM3是正在运行的中断,如果USART1中断也发生了,则优先处理,TIM3被嵌套并挂起;如果TIM2中断发生了,则需要等到TIM3处理完之后再处理TIM2。这就是抢占优先级和响应优先级的区别。
10.1 Nested vectored interrupt controller (NVIC) 嵌套矢量中断控制器的更多相关文章
- Input/output subsystem having an integrated advanced programmable interrupt controller for use in a personal computer
A computer system is described having one or more host processors, a host chipset and an input/outpu ...
- [STM32].NVIC嵌套中断向量的理解
转自:http://www.21ic.com/embed/jiaocheng/sheji/201209/5634.html 一.STM32 (Cortex-M3) 中的优先级概念 STM32(Cort ...
- Linux中断(interrupt)子系统之一:中断系统基本原理【转】
转自:http://blog.csdn.net/droidphone/article/details/7445825 这个中断系列文章主要针对移动设备中的Linux进行讨论,文中的例子基本都是基于AR ...
- Linux中断(interrupt)子系统之一:中断系统基本原理
这个中断系列文章主要针对移动设备中的Linux进行讨论,文中的例子基本都是基于ARM这一体系架构,其他架构的原理其实也差不多,区别只是其中的硬件抽象层.内核版本基于3.3.虽然内核的版本不断地提升,不 ...
- 中断服务程序不用interrupt关键字也可实现中断,该关键字是否必须?
2013-06-20 11:13:35 中断服务程序不用interrupt关键字也可实现中断,该关键字是否必须? 使用tools->pin connect,将INT5与pin.txt关联,模拟外 ...
- LeetCode 339. Nested List Weight Sum (嵌套列表重和)$
Given a nested list of integers, return the sum of all integers in the list weighted by their depth. ...
- hdu 1677 Nested Dolls【贪心解嵌套娃娃问题】
链接: http://acm.hdu.edu.cn/showproblem.php?pid=1677 http://acm.hust.edu.cn/vjudge/contest/view.action ...
- INTERRUPT CONTROLLER
1,中断的基本概念 CPU与外设之间传输数据的控制方式通常有3种:查询方式,中断方式和DMA方式.查询方式的优点是硬件开销小不需要额外的硬件支持只是通过软件不断的轮询,使用起来也就比较简单,但在此方式 ...
- [leetcode]364. Nested List Weight Sum II嵌套列表加权和II
Given a nested list of integers, return the sum of all integers in the list weighted by their depth. ...
随机推荐
- Shiro学习(11)缓存机制
Shiro提供了类似于spring的Cache抽象,即Shiro本身不实现Cache,但是对Cache进行了又抽象,方便更换不同的底层Cache实现.对于Cache的一些概念可以参考我的<Spr ...
- Vuex 常规用法
背景 很多时候我们已经熟悉了框架的运用,但是有时候就是忘了怎么用 所以这里想记下大部分的框架使用方法,方便使用的时候拷贝 一.安装 npm 方式 npm install vuex --save yar ...
- 状态压缩dp增量统计贡献——cf1238E(好题)
这题的状态设计非常巧妙,因为dp[S]表示的并非当前正确的值,而是维护一个中间量,这个中间量在到达末状态时才正确 当然官方的题解其实更加直观,只不过理解起来其实有点困难 /* 给定一个串s,字符集为2 ...
- list 链表
#include <list> #include <iostream> using std::list; /* 双向环状链表 //每一个结点 一个数据域 一个前驱指针 一个后驱 ...
- docker核心组件(6)
Docker 的核心组件包括: Docker 客户端 - Client Docker 服务器 - Docker daemon Docker 镜像 - Image Registry Docker 容器 ...
- docker镜像下载加速(5)
镜像下载加速 由于 Docker Hub 的服务器在国外,下载镜像会比较慢.幸好 DaoCloud 为我们提供了免费的国内镜像服务. 下面介绍如果使用镜像. 在 daocloud.io 免费注册一个用 ...
- tp5使用jwt生成token,做api的用户认证
首先 composer 安装 firebase/php-jwt github:https://github.com/firebase/php-jwt composer require firebas ...
- Apache Flink 整体介绍
前言 Flink 是一种流式计算框架,为什么我会接触到 Flink 呢?因为我目前在负责的是监控平台的告警部分,负责采集到的监控数据会直接往 kafka 里塞,然后告警这边需要从 kafka topi ...
- 【Java多线程系列二】Thread类的方法
Thread实现Runnable接口并实现了大量实用的方法. /* * 此方法释放CPU,但并不释放已获得的锁,其它就绪的线程将可能得到执行机会,它自己也有可能再次得到执行机会 */ public s ...
- node.js 中的 fs (文件)模块
记录 fs 模块的方法及使用 1. fs.stat 获取文件大小,创建时间等信息 // 引入 fs 模块 const fs = require('fs'); fs.stat('01.fs.js', ( ...