首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

Cortex-M3和Cortex-M4 Fault异常应用之一 ----- 基础知识(3)

Cortex-M3和Cortex-M4 Fault异常应用之一 ----- 基础知识(3)

为了编程中断和异常的优先级,CMSIS提供了函数NVIC_SetPrioriity和NVIC_GetPriority。这两个函数也位于core_cm3.h中,源码为:
[cpp] view plaincopy


  • /** \brief Set Interrupt Priority  

  • This function sets the priority for the specified interrupt. The interrupt number can be positive  
  •    to specify an external (device specific) interrupt, or negative to specify an internal (core)
  •    interrupt.  
  • Note: The priority cannot be set for every core interrupt.  

  • \param [in] IRQn Number of the interrupt for set priority  
  • \param [in] priority Priority to set  
  • */
  • static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)   
  • {   
  •     if(IRQn < 0) {   
  •             /* set Priority for Cortex-M System Interrupts */
  •         SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); }  
  •     else {   
  •               /* set Priority for device specific Interrupts */
  •         NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); }  
  • }   

  • /** \brief Get Interrupt Priority  

  • This function reads the priority for the specified interrupt. The interrupt number can be positive
  •    to specify an external (device specific) interrupt, or negative to specify an internal (core)  
  •    interrupt.  
  • The returned priority value is automatically aligned to the implemented priority bits of the  
  •    microcontroller.  

  • \param [in] IRQn Number of the interrupt for get priority  
  • \return Interrupt Priority  
  • */
  • static __INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)   
  • {   
  •     if(IRQn < 0) {   
  •                /* get priority for Cortex-M system interrupts */
  •         return((uint32_t)(SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] >> (8 - __NVIC_PRIO_BITS))); }  
  •     else {   
  •                /* get priority for device specific interrupts */
  •         return((uint32_t)(NVIC->IP[(uint32_t)(IRQn)] >> (8 - __NVIC_PRIO_BITS))); }  
  • }   


  
可以通过下面的示例代码更改异常优先级:
[cpp] view plaincopy

  •     :   
  •     :   
  • NVIC_SetPriority (MemoryManagement_IRQn, 0xF0);   
  • NVIC_SetPri ority (BusFault_IRQn, 0x80);   
  • NVIC_SetPriority ( UsageFault_IRQn, 0x10);   
  •     :   
  • UsageFault_prio = NVIC_GetPriority ( UsageFault_IRQn);   
  •     :   
  •     :   




3.1.3 SCB->SHCSR寄存器
与Fault异常相关位见下表的蓝色部分


名称
描述
[31:19]
-
保留
[18]
USGFAULTENA
用法Fault使能位,设为1时使能
[17]
BUSFAULTENA
总线Fault使能位,设为1时使能
[16]
MEMFAULTENA
存储器管理Fault使能位,设为1使能
[15]
SVCALLPENDED
SVC调用挂起位,如果异常挂起,该位读为1
[14]
BUSFAULTPENDED
总线Fault异常挂起位,如果异常挂起,该位读为1
[13]
MEMFAULTPENDED
存储器Fault故障异常挂起位,如果异常挂起,该位读为1
[12]
USGFAULTPENDED
用法Fault异常挂起位,如果异常挂起,该位读为1
[11]
SYSTICKACT
SysTick 异常有效位,如果异常有效,该位读为1
[10]
PENDSVACT
PendSV异常有效位,如果异常有效,该位读为1
[9]
-
保留
[8]
MONITORACT
调试监控有效位,如果调试监控有效,该位读为1
[7]
SVCALLACT
SVC调用有效位,如果SVC调用有效,该位读为1
[6:4]
-
保留
[3]
USGFAULTACT
用法Fault异常有效位,如果异常有效,该位读为1
[2]
-
保留
[1]
BUSFAULTACT
总线Fault异常有效位,如果异常有效,该位读为1
[0]
MEMFAULTACT
存储器管理Fault异常有效位,如果异常有效,该位读为1

      尽管可以写SCB->SHCSR寄存器的所有位,但建议软件只写异常使能位。下面的例子用于使能所有非硬Fault(存储器管理Fault、总线Fault、用法Fault异常):
[cpp] view plaincopy

  • SCB - >SHCSR |= 0x00007000; /*enable Usage Fault, Bus Fault, and MMU Fault*/


注:要包含core_cm3.h头文件。
3.2 Fault异常的状态和地址寄存器
      Fault状态寄存器组(SCB->CFSR和SCB->HFSR)和Fault地址寄存器组(SCB->MMAR和SCB->BFAR)包含Fault的详细信息以及异常发生时访问的内存地址。
地址/访问
寄存器
复位值
描述
0xE000ED28
RW 特权级
SCB->CFSR
0x00000000
可配置Fault状态寄存器:包含指示存储器管理Fault、总线Fault或用法Fault的原因位
0xE000ED2C
RW 特权级
SCB->HFSR
0x00000000
硬Fault状态寄存器:包含用于指示硬Fault原因位。
0xE000ED34
RW特权级
SCB->MMFAR
不可知
存储器管理Fault地址寄存器:包括产生存储器管理Fault的位置的地址
0xE000ED38
RW特权级
SCB->BFAR
不可知
总线Fault地址寄存器:包括产生总线Fault的位置的地址
继承事业,薪火相传
返回列表