请阅读【嵌入式开发学习必备专栏 之 ARM Cortex-Mx专栏】
由于文章【ARMv8M Cortex-M33 系列 7.2 – HardFault 问题定位 1】 中提到了HardFault 的发生是由于其它异常所升级导致的,所以就需要调查下如何是能其它异常中断。
在 ARM Cortex-M33 核心上启用 UsageFault
、MemManageFault
和 BusFault
异常的方法是通过设置系统控制块 (System Control Block, SCB) 中的配置寄存器。以下是如何启用这些异常中断的步骤:
SCB->SHCSR
寄存器包含控制系统处理程序(如 UsageFault
、MemManage
和 BusFault
)的使能位。SCB->SHCSR
中的以下位来使能对应的异常:SCB_SHCSR_MEMFAULTENA_Msk
:使能 MemManage
异常。SCB_SHCSR_BUSFAULTENA_Msk
:使能 BusFault
异常。SCB_SHCSR_USGFAULTENA_Msk
:使能 UsageFault
异常。以下是相应的代码示例:
#include "core_cm33.h" // 包含 CMSIS 核心寄存器定义和功能
void EnableFaults(void)
{
// 使能 MemManage 异常
SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
// 使能 BusFault 异常
SCB->SHCSR |= SCB_SHCSR_BUSFAULTENA_Msk;
// 使能 UsageFault 异常
SCB->SHCSR |= SCB_SHCSR_USGFAULTENA_Msk;
}
当你运行上面的代码后,MemManageFault
、BusFault
和 UsageFault
异常将被使能,并且在相应的故障条件发生时,处理器将进入对应的异常处理程序。
还有一点需注意的是,在默认情况下,Cortex-M 处理器的 MemManage
和 BusFault
异常是使能的,但 UsageFault
异常可能默认是禁用的。因此,如果你希望捕获所有可能的异常状况,不要忘记使能 UsageFault
异常。
启用这些异常后,你还需要实现相应的异常处理函数(例如 MemManage_Handler
、BusFault_Handler
和 UsageFault_Handler
),以便在异常发生时执行适当的错误处理或恢复操作。
如果使用的是 RT-Thread 或其他类似的实时操作系统,通常这些异常处理函数已经由操作系统提供,或者你可以在操作系统框架内自定义它们。
【ARMv8M Cortex-M33 系列 7.2 – HardFault 问题定位 1】 中提到了提到了通过 CFSR 寄存器可以看到UFSR 位域 INVPC 置位了,所以接下来又需要调查下,这个是个什么东东?
UFSR 位域 INVPC 中的 “Invalid PC flag. Sticky flag indicating whether an integrity check error has occurred.
在 ARM Cortex-M33 微控制器系列中,UFSR
(UsageFault Status Register)是一个寄存器,其中包含了使用错误(UsageFault)的状态信息。UFSR
的位域 INVPC
(Invalid PC Load UsageFault)是 UFSR
寄存器的一个特定标志位,用于捕获程序计数器 (PC) 载入时的完整性检查错误。
当 INVPC
标志被设置时,它表示处理器试图执行一个无效或损坏的指令。这通常是因为 PC 包含了一个非法的地址,这可能发生在以下情况:
PC 被加载了一个未能正确对齐的地址。在 Cortex-M33 架构中,所有指令必须是 2 字节或 4 字节对齐的。如果 PC 的值不是 2 字节或 4 字节对齐的,会触发 INVPC
错误。
PC 被加载了一个不能作为指令执行的地址。例如,如果 PC 被设置为指向一个数据区域或者一个禁止执行的内存区域,将无法执行有效指令,从而导致完整性错误。
INVPC
是一个粘滞(sticky)标志,这意味着一旦设置,它将保持被设置的状态,直到软件明确清除它。这允许在调试期间或通过故障处理例程来检测到这类问题的发生。
如果在 Cortex-M33 微控制器上触发了一个 UsageFault
,并且 INVPC
标志被设置,需要检查以下几点来确定问题的原因,并采取相应的解决措施:
由于 INVPC
错误通常是严重的程序错误,可能需要对系统进行全面的审查和测试,以确保代码的健壮性和稳定性。