Cortex-M3和Cortex-M4 Fault异常应用之一 ----- 基础知识(3)
- UID
- 1029342
- 性别
- 男
|
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的位置的地址
|
|
|
|
|
|
|