我要投搞

标签云

收藏小站

爱尚经典语录、名言、句子、散文、日志、唯美图片

当前位置:全民彩票 > 多级中断 >

STM32中断向量嵌套NVIC理解

归档日期:05-10       文本归类:多级中断      文章编辑:爱尚语录

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

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

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

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

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

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

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

  中断设置:时能中断->

  优先级分组方式(对应的每个中断都有)->

  设定抢占式优先级别->

  设定响应优先级别->

  调用NVIC_Init(&xx)

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

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

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

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

  作为我的一个习惯,学习某一个平台的东西,总是先要摸清楚中断的处理流程,当然是从文件代码级的流程分析了。

  下面就说下stm32的中断流程。我们知道,stm32的库中写好了很多的驱动程序,可以说包括了所有的。同时也提供很多数据处理方式,例如串口的读写,用户可以选择轮询、中断、DMA等3中方式来处理。

  关于中断,stm32的库中做好了框架,用户只要填写好几个函数的实现就ok了,就像网上说的,这就是傻瓜式开发。

  了解中断,首先要知道stm32f10x_it.c这个文件,一般情况下是和main文件在同一个目录下的。打开这个文件,我们可以看到xyz_IRQHandler函数的实现,虽然说是实现,但是几乎都是空的。对了,这些函数就是要用户填写的中断处理函数,如果你用到了哪个中断来做相应的处理,你就要填写相应的中断处理函数,需要根据各外设的实际情况来填写,但是一般都会有关闭和开启中断。在这个文件中还有很多系统相关的中断处理函数,例如系统时钟SysTickHandler。具体的实现可以参考stm32fwlibFWLibexamples下的各例子。

  到这里,我们也只不过看了中断的处理函数,而这些处理函数是如何被硬件中断调用的呢?嗯,说到这里就不得不提一下stm32f10x_vector.c这个文件了。内容如下:

  //IAR对所用语言(这里是C)做的一些扩展,也就是说这里可以用扩展的功能

  现在我们清楚了,这儿就是中断向量表,每一个item对应一个中断或异常处理,这里item的填写要和stm32spec中的Interrupt and exception vectors一节中的列表中的顺序一致。

  说道这里,又有一个问题,这个向量表是放在何处的呢?上面对.intvec的解释可以看出是被链接器放到了一个地址上(这里是0x08000000,NVIC_VectTab_FLASH)。但是stm32是怎么知道这个地址的呢,也许有个默认值,或者是就这一个固定值?)。我们在stm32f10x_nvic.c文件中发现下面这样的一个函数

  在这个例子里面就是直接调用了上面的那个函数,似乎意思很明显了。但是SCB->

  ExceptionTableOffset是如何起作用的呢?

  其实这里主要就是要弄清楚这个SCB是什么意思,因为这个结构是映射到一个物理地址上的。像别的控制寄存器都是这么个玩法,莫非这也是个某类控制器。google一下,果然对于系统控制寄存器组【上篇文章有提到】STM32的固件库中有如下定义:

  至此,我们终于清楚了,这个中断向量表的地址,最终是要写到某个控制器中去。那这么说来,上述的0x08000000可以是个别的值了,只要保证这一处的地址不能被别的程序访问就行了。

本文链接:http://jomsell.com/duojizhongduan/152.html