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

stm32学习笔记-启动文件 1、配置栈 Stack_Size EQU 0x00000400 AREA STACK, NOINIT, READWRITE, ALIGN=3 Stack_Mem SPACE Stack_Size __initial_sp EQU:相当于C中的define,定义Stack_Size = 0x00000400。 AREA: 指... 阅读详情

1. 摘要  

      Cortex-M内核实现了一个高效异常处理模块,可以捕获非法内存访问和数个程序错误条件。本应用笔记从程序员角度描述Cortex-M Fault异常,并且讲述在软件开发周期中的Fault用法。  

2. 简介  

      Cortex-M3(以下简称CM3)和Cortex-M4(以下简称CM4)内核的Fault异常可以捕获非法内存方法和非法编程行为。Fault异常能够检测到以下情况:

总线Fault:在取址、数据读/写、取中断向量、进入/退出中断时寄存器堆栈操作(入栈/出栈)时检测到内存访问错误。

存储器管理Fault:检测到内存访问违反了MPU定义的区域。

用法Fault:检测到未定义的指令异常,未对齐的多重加载/存储内存访问。如果使能相应控制位,还可以检测出除数为零以及其他未对齐的内存访问。

硬Fault:如果上面的总线Fault、存储器管理Fault、用法Fault的处理程序不能被执行(例如禁能了总线Fault、存储器管理Fault、用法Fault异常或者在这些异常处理程序执行过程中又出现了Fault)则触发硬Fault。

      本应用笔记描述CM3和CM4的Fault异常用法。系统控制寄存器组中的寄存器可以控制Fault异常或者提供引发异常的原因信息。  

更深入的文档  

       完整的异常描述见《Cortex - M3 Technical Reference Manual》或者《Cortex -M4 Technical Reference Manual》,这两本参考手册都可以在www.arm.com中找到。  

      另一个很好的参考书是由Joseph Yiu编写的《The Definitive Guide to the ARM Cortex-M3》 (这本书有中文版:宋岩译的《ARM Cortex-M3权威指南》)。  

3. Cortex-M Fault异常和寄存器  

      每个符合CMSIS规范的编译器所提供的启动文件(Startup_device)都会定义好设备所有的异常和中断向量。这些向量表定义了异常或中断处理程序的入口地址。下表给出了一个典型的向量表,Fault异常向量用蓝色标注。  

   1:      : 
   3:      : 
   5:  __Vectors DCD __initial_sp ; 栈顶
   7:  DCD Reset_Handler          ; 复位处理程序入口
   9:  DCD NMI_Handler            ; NMI 处理程序入口
  11:  DCD HardFaul t_Handler     ; 硬Fault处理程序入口 
  13:  DCD MemManage_Handler      ; 存储器管理处理程序入口 
  15:  DCD BusFault_Handler       ; 总线Fault 处理程序入口 
  17:  DCD UsageFault_Handler     ; 用法 Fault 处理程序入口 
  19:  DCD 0                      ; 保留 
  21:      : 
  23:      : 
        通常总是使能硬Fault异常的,硬Fault异常具有固定的优先级,并且优先级高于其它Fault异常以及中断,但低于NMI。硬Fault异常处理程序在以下情况下会被执行:其它非硬Fault异常(非硬Fault异常是指总线、存储器管理和用法Fault 异常,下同。)被禁能,并且这些Fault异常被触发;在执行一个非硬Fault异常处理程序中又产生非硬Fault异常。

      所有非硬Fault具有可编程的优先级。当Cortex-M内核复位后,这些非硬Fault被禁能,你可以在应用软件中通过设置“系统Handler控制及状态寄存器(SHCSR)”来使能非硬Fault异常。这个寄存器属于系统控制模寄存器组(SCB)

3.1 Fault异常的控制寄存器

      在这里有必要介绍一下系统控制模块寄存器组(SCB)的成员,这个寄存器组的定义可以在core_cm3.h文件中,该文件属于CMSIS Cortex-M3 内核外设接口抽象层的一部分(关于不清楚CMSIS的,可以自行查找资料)。定义如下:

1.定义系统控制寄存器组结构体

     /** @brief System Control Block (SCB) register structure definition */
     typedef struct
     { 
         __I uint32_t CPUID;   /*!< Offset: 0x00 CPU ID Base Register*/ 
         __IO uint32_t ICSR;   /*!< Offset: 0x04 Interrupt Control State Register*/ 
        __IO uint32_t VTOR;   /*!< Offset: 0x08 Vector Table Offset Register*/  
        __IO uint32_t AIRCR;  /*!< Offset: 0x0C Application Interrupt / Reset Control Register*/ 
        __IO uint32_t SCR;    /*!< Offset: 0x10 System Control Register*/  
        __IO uint32_t CCR;    /*!< Offset: 0x14 Configuration Control Register*/   
        __IO uint8_t SHP[12]; /*!< Offset: 0x18 System Handlers Priority Registers (4-7, 8-11, 12-15) */  
        __IO uint32_t SHCSR;  /*!< Offset: 0x24 System Handler Control and State Register */  
        __IO uint32_t CFSR;   /*!< Offset: 0x28 Configurable Fault Status Register*/  
        __IO uint32_t HFSR;   /*!< Offset: 0x2C Hard Fault Status Register*/  
        __IO uint32_t DFSR;   /*!< Offset: 0x30 Debug Fault Status Register */ 
        __IO uint32_t MMFAR;  /*!< Offset: 0x34 Mem Manage Address Register*/  
        __IO uint32_t BFAR;   /*!< Offset: 0x38 Bus Fault Address Register*/ 
        __IO uint32_t AFSR;   /*!< Offset: 0x3C Auxiliary Fault Status Register*/  
        __I uint32_t PFR[2];  /*!< Offset: 0x40 Processor Feature Register*/  
        __I uint32_t DFR;     /*!< Offset: 0x48 Debug Feature Register*/ 
        __I uint32_t ADR;     /*!< Offset: 0x4C Auxiliary Feature Register*/  
        __I uint32_t MMFR[4]; /*!< Offset: 0x50 Memory Model Feature Register*/   
        __I uint32_t ISAR[5]; /*!< Offset: 0x60 ISA Feature Register*/  
    } SCB_Type; 


2. 定义系统控制寄存器组物理空间基地址

         #define SCS_BASE (0xE000E000) /*!< System Control Space Base Address */
3. 定义指向系统控制寄存器组的指针

         #define SCB ((SCB_Type *)SCB_BASE) /*!< SCB configuration struct * / 
      通过以上三步,我们就可以使用结构体指针SCB来访问系统控制寄存器组的寄存器了,比如给系统控制寄存器SCR赋值:SCB->SCR=0xFF;

      SCB->CCR寄存器控制除数为零和未对齐内存访问是否触发用法Fault。

      SCB->SHCSR寄存器可用来使能非硬Fault异常。如果一个非硬Fault异常被禁能并且相关Fault发生,这时异常会升级为硬Fault。SCB->SHP寄存器组控制异常的优先级。

Fault异常控制寄存器列表:

地址/访问

寄存器

复位值

描述

0xE000ED14

RW 特权级

SCB->CCR

0x00000000

配置和控制寄存器:包含控制除数为零和未对齐内存访问是否触发用法Fault的使能位。

0xE000ED18

RW 特权级

SCB->SHP[12]

0x00

系统处理程序优先级寄存器:控制异常处理程序的优先级

0xE000ED24

RW特权级

SCB->SHCSR

0x00000000

系统处理程序控制和状态寄存器

3.1.1 SCB->CCR 寄存器

蓝色部分控制是否使能相应的用法Fault

位

名称

描述

[31:10]

-

保留

[9]

STKALIGN

表示进入异常时的堆栈对齐。

0:4字节对齐

1:8字节对齐

进入异常时,处理器使用压入堆栈的PSR位[9]来指示堆栈对齐。从异常返回时,这个堆栈位被用来恢复正确的堆栈对齐。

[8]

BFHFNMIGN

使能时,使得以优先级位-1或-2运行的处理程序忽略加载和存储指令引起的数据总线故障。它用于硬故障、NMI和FAULTMASK升级处理程序中:

0:加载和存储指令引起的数据总线故障会引起锁定。

1:以优先级-1或-2运行的处理程序忽略加载和存储指令引起的数据总线故障。

仅在处理程序和其数据处于绝对安全的存储器时将该位设为1。一般将该位用于探测系统设备和桥接器以检测并纠正控制路径问题。

[7:5]

-

保留

[4]

DIV_0_TRP

当处理器进行除0操作(SDIV或UDIV指令)时,会导致故障或停止。

0:不捕获除以零故障

1:捕获除以零故障。

当该位设为0时,除以零返回的商数为0。

[3]

UNALIGN_TRP

使能非对齐访问捕获:

0:不捕获非对齐半字和字访问

1:捕获非对齐半字和字访问。

如果该位设为1,非对齐访问产生一个使用故障。无论UNALIGN_TRP是否设为1,非对齐的LDM、STM、LDRD和STRD指令总是出错。

[2]

-

保留

[1]

USERSETM

PEND

 

使能对STIR的无特权软件访问。

0:禁能

1:使能

[0]

NONEBASE

THRDENA

 

指示处理器如何进入线程模式:

0:处理器仅在没有有效异常时才能够进入线程模式。

1:处理器可以从EXC_RETURN值控制下的任何级别进入线程模式

3.1.2 SCB->SHP 寄存器组

      以下SCB->SHP 寄存器组的寄存器用来设置异常处理程序的优先级:

             SCB->SHP[0]:存储器管理Fault的优先级

             SCB->SHP[1]:总线Fault的优先级

             SCB->SHP[2]:用法Fault的优先级

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

     /** \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))); }
    } 

 
可以通过下面的示例代码更改异常优先级:

             : 
             : 
         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异常):

         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的位置的地址

3.2.1 SCB->CFSR寄存器

SCB->CFSR寄存器的位分配表:

bit31                                                                           bit16

bit15                   bit8

bit7                    bit0

用法Fault状态寄存器(UFSR)

总线Fault状态寄存器(BFSR)

存储器管理Fault状态寄存器(MMFSR)

SCB->CFSR寄存器可以被分成三个组:

      存储器管理Fault 状态寄存器:地址0x0xE000ED28,可以按字节访问

      总线Fault状态寄存器:地址0xE000ED29,可以按字节访问

      用法Fault状态寄存器:地址0xE000ED2A,可以按半字访问

3.2.1.1 存储器管理Fault状态寄存器MMFSR:指示存储器访问Fault的原因

位

名称

描述

[7]

MMARVALID

存储器管理Fault地址寄存器(MMAR)有效标志:

0:MMAR中的值不是一个有效Fault地址

1:MMAR中保留一个有效Fault地址。

如果发生了一个存储器管理Fault,并由于优先级的原因升级成一个硬Fault,那么硬Fault处理程序必须将该位设为0。

[6:5]

-

保留

[4]

MSTKERR

进入异常时的入栈操作引起的存储器管理Fault:

0:无入栈Fault

1:进入异常时的入栈操作引起了一个或一个以上的访问违犯。

当该位设为1时,依然要对SP进行调节,并且堆栈的上下文区域的值可能不正确。处理器没有向MMAR中写入Fault地址。

[3]

MUNSTKERR

异常返回时的出栈操作引起的存储器管理Fault:

0:无出栈Fault

1:异常返回时的出栈操作已引起一个或一个以上的访问违犯.

该Fault与处理程序相连,这意味着当该位为1时,原始的返回堆栈仍然存在。

处理器不能对返回失败的SP进行调节,并且不会执行新的存储操作。处理器没有向MMAR中写入Fault地址。

[2]

-

保留

[1]

DACCVIOL

数据访问违犯标志:

0:无数据访问违犯Fault

1:处理器试图在不允许执行操作的位置上进行加载和存储。

当该位为1时,异常返回的压入堆栈的PC值指向出错指令。处理器已在MMAR中加载了目标访问的地址。

[0]

IACCVIOL

指令访问违犯标志:

0:无指令访问违犯错误

1:处理器试图从不允许执行操作的位置上进行指令获取。

即使MPU被禁能,这一故障也会在XN(CM3内核的0xE0000000~0xFFFFFFFF区域)区寻址时发生。

当该位为1时,异常返回的压入堆栈的PC值指向出错指令。处理器没有向MMAR中写入故障地址。

3.2.1.2 总线Fault状态寄存器BFSR:指示总线访问Fault原因

位

名称

描述

[7]

BFARVALID

总线Fault地址寄存器(BFAR)有效标志:

0:BFAR中的值不是有效故障地址

1:BFAR中保留一个有效故障地址。

在地址已知的总线故障发生后处理器将该位设为1。该位可以被其他Fault清零,例如之后发生的存储器管理Fault。

如果发生总线Fault,并由于优先级原因升级为一个硬Fault,那么硬Fault处理程序必须将该位设为0。

[6:5]

-

保留

[4]

STKERR

进入异常时的入栈操作引起的总线Fault:

0:无入栈故障

1:进入异常时的入栈操作已引起一个或一个以上的总线故障。

当处理器将该位设为1时,依然要对SP进行调节,并且堆栈的上下文区域的值可能不正确。处理器没有向BFAR中写入Fault地址。

[3]

UNSTKERR

异常返回时的出栈操作引起的总线Fault:

0:无出栈Fault

1:异常返回时的出栈操作已引起一个或一个以上的总线Fault。

该Fault与处理程序相连, 这意味着当处理器将该位设为1时,原始的返回堆栈仍然存在。处理器不能对返回失败的SP进行调节,并且不会执行新的存储操作,也未向BFAR中写入Fault地址。

[2]

IMPRECISERR

非精确数据总线错误:

0:无非精确数据总线错误

1:已发生一个数据总线错误,但是堆栈帧中的返回地址与引起错误的指令无关。

当处理器将该位设为1时,不向BFAR中写入Fault地址。

这是一个异步Fault。因此,如果在当前进程的优先级高于总线Fault优先级时检测到该Fault,总线Fault被挂起并仅在处理器从所有更高优先级进程中返回时开始变为有效。如果在处理器进入非精确总线Fault的处理程序前发生一个精确Fault,那么处理程序同时对IMPRECISERR 和其中一个精确Fault状态位进行检测,判断它们是否置位为1。

[1]

PRECISERR

精确数据总线错误:

0:非精确数据总线错误

1:已发生一个数据总线错误,且异常返回的压入堆栈的PC值指向引起Fault的指令。

当处理器将该位设为1时,向BFAR中写入Fault地址。

[0]

IBUSERR

指令总线错误:

0:无指令总线错误

1:指令总线错误。

处理器检测到预取指令时的指令总线错误,但仅在其试图签发Fault指令时才将IBUSERR 标志设为1。

当处理器将该位设为1时,不向BFAR中写入Fault地址。

3.2.1.3 用法Fault状态寄存器UFSR:指示产生用法Fault的原因

位

名称

描述

[15:10]

-

保留

[9]

DIVBYZERO

0:无除以零Fault或除以零捕获未使能

1:处理器已执行SDIV或UDIV指令(除以零)。

当处理器将该位设为1时,异常返回的压入堆栈的PC值指向执行除以零的指令。

注:通过将CCR中的DIV_0_TRP位设为1使能除以零捕获,默认是不使能的。

[8]

UNALIGNED

0:无非对齐访问Fault,或非对齐访问捕获未使能

1:处理器已进行了一次非对齐的存储器访问。

注:通过将CCR中的UNALIGN_TRP位设为1来使能非对齐访问捕获,默认是不使能的。非对齐的LDM、STM、LDRD和STRD指令总是出错,与UNALIGN_TRP的设置无关。

[7:4]

-

保留

[3]

NOCP

无协处理器用法Fault。处理器不支持协处理器指令:

0:试图访问一个协处理器未引起用法Fault

1:处理器已试图访问一个协处理器。

[2]

INVPC

EXC_RETURN的无效PC加载引起的无效PC加载用法Fault:

0:没有发生无效PC加载用法Fault

1:处理器已试图将EXC_RETURN非法载入PC,作为一个无效的上下文或一个无效的EXC_RETURN值。

当该位被设为1时,异常返回的压入堆栈的PC值指向尝试执行非法PC加载的指令。

[1]

INVSTATE

无效状态用法Fault:

0:未发生无效状态用法Fault

1:处理器已试图执行一个非法使用EPSR的指令。

当该位设为1时,异常返回的压入堆栈的PC值指向一个尝试非法使用EPSR的指令。

如果一个未定义的指令使用了EPSR,则该位不被置位为1。

[0]

UNDEFINSTR

未定义的指令用法Fault:

0:无未定义的指令用法Fault

1:处理器已试图执行一个未定义的指令。当该位设为1时,异常返回的压入堆栈的PC值指向未定义的指令。

未定义的指令是一条不能被处理器译码的指令。

3.2.2 SCB->HSFR寄存器

SCB->HSFR寄存器提供关于激活硬Fault处理程序的事件的信息,写入1清零相应位。

位

名称

描述

[31]

DEBUGEVT

硬Fault因调试事件产生,保留供调试使用。对寄存器执行写操作时,必须向该位写入0;否则,该行为不可预知。

[30]

FORCED

指示硬Fault是否由上访产生,非硬Fault的处理程序无法执行时,会上访成硬Fault。

0:硬Fault不是因为非硬Fault上访产生的

1:硬Fault是通过非硬Fault上访产生的。

当该位设为1时,硬Fault处理程序必须读其他Fault状态寄存器以找出Fault原因。

[29:2]

-

保留

[1]

VECTTBL

指示一个在异常处理过程中读向量表而引起的总线Fault:

0:读向量表未引起总线Fault

1:读向量表引起了总线Fault。

这一错误通常情况下都由硬Fault处理程序来处理。

[0]

-

保留

3.2.3 SCB->MMFAR和SCB->BFAR寄存器

      为了确定产生了哪个Fault异常以及什么原因引起的Fault异常,你需要检测Fault状态寄存器。

      如果SCB->CFSR寄存器的BFARVALID位有效(为1),则SCB->BFAR寄存器的值表示引起总线Fault的内存地址。

      如果SCB->CFSR寄存器的MMFARVALID位有效(为1),则SCB->MMFAR寄存器的值表示引起存储器管理Fault的内存地址。

 

参考资料:

1. ARM Cortex-M3权威指南                Joseph Yiu著   宋岩译

2. Application Note 209   Using Cortex-M3 and Cortex -M4 Fault exceptions         Copyright 2010 ARM

3. LPC178x/7x用户手册                       NXP
————————————————
版权声明:本文为优快云博主「zhzht19861011」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.youkuaiyun.com/zhzht19861011/article/details/8645661

新手必学!通过SCB寄存器快速定位STM32 HardFault根源 本文详细介绍了如何通过SCB寄存器快速诊断STM32 HardFault故障。深入解析CFSR、HFSR、MMFAR和BFAR等关键寄存器的作用,提供Keil环境下的实战调试技巧和自定义处理函数编写方法,帮助开发者精准定位内存访问错误、堆栈溢出等常见问题根源。 阅读详情

相关推荐

Cortex-M3/M4/M7 芯片 Fault 分析原理与实战

HardFault(硬件错误)是一类在嵌入式系统开发中较为常见的系统异常,优先级仅低于复位和 NMI(不可屏蔽中断)。当系统运行过程中遇到了某些错误时程序就会跳转至函数中,引发程序故障进而影响程序的正常运行。HardFault(硬件故障):默认异常,由于异常处理过程中的错误或由于任何其他异常机制无法管理异常而触发。MemManage(内存管理故障):检测内存管理单元(MPU)中定义的区域的内存访问违规;例如,在一个只有读/写访问权限的内存区域中执行代码。BusFault。

Projectsauron 的博客 1万+

stm32 各种类型错误:HardFault_Handler、MemManage_Handler、BusFault_Handler、UsageFault_Handler

STM32出现HardFault_Handler故障的原因主要有两个方面: 1、内存溢出或者访问越界。这个需要自己写程序的时候规范代码,遇到了需要慢慢排查。 2、堆栈溢出。增加堆栈的大小。 MemManage_Handler:访问了内存管理单元(MPU)定义的不合法的内存区域,比如向只读区域写入数据。 BusFault_Handler:在fetch指令、数据读写、fetch中断向量或中断时存储恢复寄存器栈情况下,检测到内存访问错误则产生 BusFault。 UsageFault...

灵哎惹,凌沃敏的博客 1万+

STM32 Cortex-M3 HardFault异常定位

STM32 HardFault定位

binhao002的博客 3007

STM32使能中断时进入Hardfault问题

最近在做项目时,遇到的问题,刚开始只是用USART1+ADC+RTC_Wakeup,程序没有问题,但是后来加入USART2,遇到了在ADC_Enable(hadc)时候进入hardfault,由于ADC不是时刻需要,然后就把main函数中ADC_Init();放到了开启ADC前面,没有再进入hardfault。 但是新的问题又出现了,在使能串口2中断后,串口中断在执行过程中,跳到HAL_RTCEx_WakeUpTimerIRQHandler(RTC_HandleTypeDef *hrtc)函数会进入h..

qq_43186111的博客 2706

Cortex-M3架构学习:异常

Cortex-M3架构学习-异常(中断)

kkbbaaii的博客 1690

代码调试跟踪与优化(三)--- 如何调试Fault 异常?

我们在开发嵌入式代码时,经常会遇到处理器无法启动或系统停止响应的情况,比较常见的是处理器触发了Fault 异常,并停留在Fault 异常处理程序内循环,我们如何分析产生Fault 异常的原因呢?如何借助fault status / address registers 获知产生fault 的原因呢?如何跟踪定位产生fault 的具体代码行呢?有哪些调试工具可以帮我们快速分析定位解决fault 呢?如何设计fault handlers 以输出fault log 帮我们快速定位分析解决系统bug?

流云 8760

Cortex-M3和Cortex-M4 Fault异常基础知识

硬Fault:如果上面的总线Fault、存储器管理Fault、用法Fault的处理程序不能被执行(例如禁能了总线Fault、存储器管理Fault、用法Fault异常或者在这些异常处理程序执行过程中又出现了Fault)则触发硬Fault。如果一个非硬Fault异常被禁能并且相关Fault发生,这时异常会升级为硬Fault。Fault状态寄存器组(SCB->CFSR和SCB->HFSR)和Fault地址寄存器组(SCB->MMAR和SCB->BFAR)包含Fault的详细信息以及异常发生时访问的内存地址。...

lbaihao的专栏 3085

Cortex-M Fault

函数说明* 执行未定义的指令时触发 UsageFault 或 HardFault。* 附加信息* 在无效地址执行时触发 UsageFault。* 硬故障的相关寄存器:* FORCED = 1 - UsageFault 升级为 HardFault* UNDEFINSTR = 1 - 执行了未定义的指令*/// 0xDEAD: UDF # (永久未定义)int r;

CoolBreeze的博客 1639

Cortex-M3/4的Hard Fault调试方法

1 Cortex-M3/4的Fault简介 Cortex-M3/4的Fault异常是由于非法的存储器访问(比如访问0地址、写只读存储位置等)和非法的程序行为(比如除以0等)等造成的。常见的4种异常及产生异常的情况如下: Bus Fault:在fetch指令、数据读写、fetch中断向量或中断时存储恢复寄存器栈情况下,检测到内存访问错误则产生Bus Fault。 Memory Mana...

系统 运维 1995

鸿蒙轻内核M核源码分析系列十八 Fault异常处理

本文先简单介绍下Fault异常类型,向量表及其代码,异常处理C语言程序,然后详细分析下异常处理汇编函数实现代码。文中所涉及的源码,以内核为例,均可以在开源站点 https://gitee.com/openharmony/kernel_liteos_m 获取。

maniuT的博客 857

Cortex-M3异常处理与调试接口实战:从Hard Fault诊断到ICEPick连接

在嵌入式系统开发中,异常处理和调试是保障系统稳定性的核心技术。异常是处理器响应内部或外部紧急事件的硬件机制,而调试接口则是开发者探查系统内部状态的生命线。理解其原理,需要从处理器自动保存现场的核心机制——异常栈帧入手,它记录了程序状态、返回地址等关键信息,是诊断问题的第一手资料。结合Fault状态寄存器,开发者可以精准定位如内存访问违规、指令错误等根源。在工程实践中,高效的调试离不开对JTAG、cJTAG等调试接口协议的掌握,以及ICEPick模块在安全访问与资源调度中的关键作用。这些技术共同应用于实时性要

weixin_34259232的博客 385

关于Cortex-M3单片机出现Fault故障,应该如何判断和解决

Cortex-M3单片机出现Fault故障可能是由于多种原因引起的,包括软件错误、硬件故障或者外部环境因素等。:Cortex-M3处理器有多种Fault类型,包括Hard Fault、Bus Fault、Memory Management Fault和Usage Fault等。首先,查看发生的具体Fault类型可以帮助定位问题所在。:在出现Fault时,处理器会保存一些状态信息,例如堆栈指针、程序计数器等。通过查看这些状态信息,可以了解出现Fault时处理器的上下文,从而有助于定位问题。

Kyle_Chan_zMH的博客 2429

解决gd32 延时2s 错误FFFFFFFF DCD 0xFFFFFFFF ; ?Undefined和HardFault_Handler BusFault_Handler

延时2s方法: main.c delay_1ms(2000); gd32f10x_it.c void SysTick_Handler(void) { delay_decrement(); } 仿真错误信息: 1.FFFFFFFF DCD 0xFFFFFFFF ; ?Undefined 2.gd32f10x_it.c 停在函数HardFault_Handler()和BusFault_Handler() 错误解决方法: 外部是12Mhz,将系统时钟从1...

qq_20395637的博客 1869

ARM Cortex-M3/M4开发踩坑记:手把手教你调试Usage Fault异常(附完整代码)

本文详细解析了ARM Cortex-M3/M4开发中常见的Usage Fault异常,提供了从环境搭建到实战调试的全流程指南。通过分析异常触发机制、关键寄存器配置及智能恢复策略,帮助开发者快速定位和解决Usage Fault问题,提升嵌入式系统稳定性。

weixin_30905133的博客 571

别再乱装了!Win10下NVIDIA显卡驱动、CUDA 11.0和cuDNN 8.0.5保姆级配置指南(含版本匹配避坑)

本文提供Win10下NVIDIA显卡驱动、CUDA 11.0和cuDNN 8.0.5的保姆级配置指南,详细解析版本匹配逻辑与安装步骤。从驱动选择到环境变量配置,再到框架测试,手把手教你避开常见坑点,确保深度学习环境一次配置成功。特别强调版本匹配的重要性,帮助开发者高效搭建GPU开发环境。

weixin_30600197的博客 307

livox avia平台搭建

livox雷达数据采集平台搭建

Shilong的博客 1307

Cortex-M3异常

Cortex-M3权威指南异常学习

weixin_54930908的博客 1089

基于R语言的PLS算法实现解读

我们使用"pls"包来执行PLS回归,并提供了相应的源代码。在本文中,我们将详细解读基于R语言的PLS算法的实现过程,并提供相应的源代码。PLS算法的实现可以借助R语言中的"pls"包。该包提供了丰富的函数和工具,用于执行PLS回归、PLS-DA(PLS-Discriminant Analysis)和其他相关任务。除了执行PLS回归,"pls"包还提供了其他功能,例如PLS-DA(用于分类问题)和PLS变量选择等。上述代码将基于输入的X值,使用训练好的PLS模型进行预测,并返回预测结果。

TechWhizKid的博客 1043

别再让HardFault背锅了!深入Cortex-M3/M4的Usage Fault机制与精确捕获

本文深入解析ARM Cortex-M3/M4处理器的Usage Fault机制,揭示如何从误诊HardFault到精准捕获Usage Fault。通过详细讲解异常处理层级架构、SCB->SHCSR寄存器配置、异常栈帧保存机制及高效处理函数编写,帮助开发者提升嵌入式系统调试效率。

weixin_30423977的博客 516

基于Simulink进行微电网中DC-DC变换器的仿真建模

微电网:包括可再生能源发电设备、储能系统和负载,可以独立于大电网运行,也可以并网运行。重要性提高能源可靠性:通过本地化供电减少对外部电网的依赖。促进可再生能源利用:支持高效整合多种可再生能源。挑战多源管理:不同类型的能源产生方式各异,需设计灵活的电源管理系统。能量转换效率:需要高效的能量转换装置来确保能源的有效利用。首先明确要模拟的任务内容。设计一个能够在不同输入条件下为微电网提供稳定输出电压的DC-DC变换器。根据微电网的工作状态调整控制策略以维持最佳性能。

amy_mhd的博客 154

【日志】Prometheus/Loki+Alertmanager+Grafana监控告警

参考文章:匹配写法:https://blog.ossq.cn/2674.html。

CN_Eden 1320
上一篇: linux下使用TC模拟弱网络环境(网络延迟和丢包)
下一篇: lcov收集覆盖率
evilcode
博客等级 码龄20年 307粉丝 16原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值