打印

(转)GD32F130FXP6学习笔记十:Cortex-M3中断学习

[复制链接]
991|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
renzheshengui|  楼主 | 2018-8-4 10:37 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

出处:http://blog.csdn.net/sunheshan/article/details/48553467



1 异常M3支持15个系统异常,240个外部异常IRQ,其中NMI,复位,hardfault三个异常的优先级固定不可更改且是负数,其余的都可编程。M3的异常分为抢占优先级和子优先级。2 关于中断优先级M3中,除了复位,NMI以及硬fault有固定的优先级,其他优先级都是可编程的。原则上,CM3支持3个固定的高优先级和多达256级的可编程优先级,并且支持128级抢占。但是,绝大多数CM3芯片都会精简设计,以致实际上支持的优先级数会更少,如8级,16级,


  • 32级等。它们在设计时会裁掉表达优先级的几个低端有效位。



  • 如使用3个位表示优先级则配置寄存器的结构如图所示:







  • 在M3中,优先级分为两个部分,一个是抢占优先级优先级,一个是子优先级。在计算抢




  • 占优先级和子优先级的有效位数时,必须要知道



  •     1、芯片实际使用了多少位来表达优先级



  •     2、优先级组是如何划分的。



  •     举个例子,如果只使用3个位来表达优先级([7:5]),并且优先级组的值是5(从比特5处分组),




  • 则得到4级抢占优先级,且在每个抢占优先级的内部有2个子优先级,







  •     当然也可设置全部是抢占优先级没有子优先级







  •     在编写应用程序的时候,只需要系统所需要的中断分组和组内优先级即可,直接调用m3




  • 提供的API函数即可。



  •     在CM3中,允许使用3个位到8个位来表达优先级。为了确定具体的位数,可以先往一个优


先级寄存器中写0xFF,再读回来,读出多少个1,就表示使用多少个位来表达优先级。

关于中断配置基础
每个外部中断都在NVIC的下列寄存器中“挂号”:



  • 1. 使能与除能寄存器



  • 2. 悬起与“解悬”寄存器



  • 3. 优先级寄存器



  • 4. 活动状态寄存器



  • 5. 异常掩蔽寄存器(PRIMASK, FAULTMASK以及BASEPRI)



  • 另外,下列寄存器也对中断处理有重大影响



  • 1. 向量表偏移量寄存器



  • 2. 软件触发中断寄存器



  • 3. 优先级分组位段



  • 其他异常配置寄存器



  •     系统Handler控制及状态寄存器SHCSR用法fault,总线fault以及存储器管理fault都是特殊


的异常,因此给它们开了小灶。它们的使能控制都是通过SHCSR来实现,各种faults的悬起状态


  • 和大多数系统异常的活动状态也都在该寄存器中。



  • 中断控制及状态寄存器ICSR



  •     在大多数情况下,它们对于应用软件都没有什么用处,只有悬起位对应用程序常常比较有参考价值。


异常屏蔽寄存器
PRIMASK用于除能在NMI和硬fault之外的所有异常,它有效地把当前优先级改为0(可编程
优先级中的最高优先级)。该寄存器可以通过MRS和MSR以下例方式访问:
1. 关中断



  • MOV   R0,     #1



  • MSR   PRIMASK, R0


  • 1
  • 2
  • 1
  • 2
  • 开中断


  • MOV   R0,     #0



  • MSR   PRIMASK,  R0


  • 1
  • 2
  • 1
  • 2

此外,还可以通过CPS指令快速完成上述功能:



  • CPSID i    ;关中断



  • CPSIE i    ;开中断


  • 1
  • 2
  • 1
  • 2
FAULTMASK更绝,它把当前优先级改为-1。这么一来,连硬fault都被掩蔽了。使用方案与PRIMASK的相似。但要注意的是,FAULTMASK会在异常退出时自动清零。掩蔽寄存器虽然能一手遮天,却都动不了NMI,因为NMI是用在最危急的情况下的。因此系统为它开出单行道,无需挂号只是不要迟到。当NMI激活时,“谁都是省略号,唯独是你不得了,第一优先谁比你重要”!试想,如果NMI被连接到系统的掉电报警线上,且系统是体外循环机的电源管理器……如果因为中断被除能就视而不见,则会使体外循环机因断电而失能,体外循环序列可以被意外终止,病人的生命也将丢失。

Active状态寄存器
每个外部中断都有一个活动状态位。在处理器执行了其ISR的第一条指令后,它的活动位就被置1,

并且直到ISR返回时才硬件清零。由于支持嵌套,允许高优先级异常抢占某个ISR。然而,哪怕中

断被抢占,其活动状态也依然为1。

3 使用中断

对于应用程序存储在ROM中,不需要更改异常服务程序。

  • 建立优先级组
  • 为该中断指定优先级
  • 使能该中断
4 cm3.h中操作中断相关函数


  • __STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup)       //---设置组优先级



  • __STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void)                  //---获得组优先级



  • __STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)                 //---使能中断



  • __STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)                    //---除能中断



  • __STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)          //---获得被挂起的中断



  • __STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)             //---挂起中断



  • __STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)           //---清除挂起中断



  • __STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn)              //---中断是否活动



  • __STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)  //---设置中断优先级



  • __STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)             //---获取中断优先级



  • __STATIC_INLINE void NVIC_SystemReset(void)                          //---NVIC  复位






  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
5 用户EFM32中断

1)优先级数目
首先对于特定处理器,支持的外部中断数不一样,故在设置中断优先级时需要知道芯片实际

使用了多少位来表达优先级。在EFM32中:__NVIC_PRIO_BITS定义efm32g280f128.h当中。

#define  __NVIC_PRIO_BITS       3 /**< NVIC interrupt priority bits */
  • 1
  • 1
cm3.h的优先级设置函数设置优先级语句为:NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff);  
  • 1
  • 1
    从cm3.h设置优先级函数可知芯片实际用了(8-__NVIC_PRIO_BITS)表达优先级。这个


  • EFM32startup.s提供的30中断向量数目符合。



  • 2)优先级组



  •     优先级数目是定死了的,对于优先级组AIPCR[8:10]复位值为0,对于(8-__NVIC_PRIO_BITS)


优先级数目来说就全部是抢占优先级而没有子优先级。对于应用程序,可以根据工程需要对优先级组进行设定。


  • void  NVIC_SetPriorityGrouping (uint32_t PriorityGroup)



  • PriorityGroup


  • 1
  • 2
  • 1
  • 2


  •     有7-PriorityGroup位表示优先级组。如PriorityGroup为5,则[7:6]表示优先级抢占位段。



  • 3)开关可屏蔽中断



  •     在core_cmFunc.h中定义了与PRIMASK中断操作相关的函数




  •     __disable_irq(void);



  •     __enable_irq(void);



  •     __get_PRIMASK(void);



  •     __set_PRIMASK(uint32_t priMask);


  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4
6 使用SVC


  •     SVC指令带一个8位的立即数,可以视为是它的参数,被封装在指令本身中,如:



  •     SVC   3    ;呼叫3号系统服务



  •     SVC是用于呼叫OS所提供API的正道。用户程序只需知道传递给OS的参数,而不必知道各API函数的地址。



沙发
heimaojingzhang| | 2018-8-4 11:07 | 只看该作者
这样看来 基本上所有的中断都是差不多的

使用特权

评论回复
板凳
guanjiaer| | 2018-8-8 09:43 | 只看该作者
写的很扎实

使用特权

评论回复
地板
renzheshengui|  楼主 | 2018-8-8 12:56 | 只看该作者

客气了 感觉排版没弄好

使用特权

评论回复
5
vivilzb1985| | 2018-8-18 20:20 | 只看该作者
异常M3支持15个系统异常,240个外部异常IRQ,其中NMI,复位,hardfault三个异常的优先级固定不可更改且是负数,其余的都可编程。

使用特权

评论回复
6
renzheshengui|  楼主 | 2018-8-20 12:45 | 只看该作者
vivilzb1985 发表于 2018-8-18 20:20
异常M3支持15个系统异常,240个外部异常IRQ,其中NMI,复位,hardfault三个异常的优先级固定不可更改且是负 ...

您是明白人啊

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

78

主题

3858

帖子

2

粉丝