STM32开发学习——使用 Cortex-M3M4M7 故障异常原因与定位(二)

STM32开发学习——使用 Cortex-M3M4M7 故障异常原因与定位(二)

文档说明:

分享一下在Stm32学习过程收集到的一些值得记录的好资料,以便自己保留印象和尽可能的应用到工作中,达到事半功倍的效果。

这是一篇关于Cortex-M内核故障异常的举例。

Cortex-M内核故障的基础概念请看STM32开发学习——使用 Cortex-M3M4M7 故障异常原因与定位(一)

官方参考文档线上链接(可在线阅读与下载):

故障分析示例

BusFault总线故障示例

非法内存写入(Illegal Memory Write)
/*********************************************************************
*
*   通过写入保留地址触发BusFault或HardFault。
*
*  Additional Information
*    BusFault是在写入指令之后引发的一些指令。
*    Related registers on fault:
*      HFSR = 0x40000000
*        FORCED = 1           - BusFault escalated to HardFault (when BusFault is not activated)
*      BFSR = 0x00000004
*        IMPRECISERR = 1      - Imprecise data access violation. Return address not related to fault
*        BFARVALID   = 0      - BFAR not valid
*/
static int _IllegalWrite(void) {
    int r;
    volatile unsigned int* p;

    r = 0;
    p = (unsigned int*)0x00100000;       // 0x00100000-0x07FFFFFF is reserved on STM32F4
    //  F44F1380    mov.w r3, #0x00100000
    *p = 0x00BADA55;
    //  4A03        ldr r2, =0x00BADA55
    //  601A        str r2, [r3]         <- Illegal write is done here
    return r;
    //  9B00        ldr r3, [sp]
    //  4618        mov r0, r3
    //  B002        add sp, sp, #8       <- Fault might be raised here 
    //  4770        bx lr
}
非法内存读取(Illegal Memory Read)
/*********************************************************************
*
*       _IllegalRead()
*
*  Function description
*   通过读取保留地址触发BusFault或HardFault。
*
*  Additional Information
*    读取指令会立即触发BusFault。
*    Related registers on fault:
*      HFSR = 0x40000000
*        FORCED = 1           - BusFault escalated to HardFault
*      BFSR = 0x00000082
*        PRECISERR = 1        - Precise data access violation
*        BFARVALID = 1        - BFAR is valid
*      BFAR = 0x00100000      - The address read from
*/
static int _IllegalRead(void) {
  int r;
  volatile unsigned int* p;

  p = (unsigned int*)0x00100000;        // 0x00100000-0x07FFFFFF is reserved on STM32F4
  //  F44F1380    mov.w r3, #0x00100000 <- The read address. Will be found in BFAR
  r = *p;
  //  681B        ldr r3, [r3]          <- Illegal read happens here and raises BusFault
  //  9300        str r3, [sp]

  return r;
}
非法执行功能(Illegal Function Execution)
/*********************************************************************
*
*       _IllegalFunc()
*
*  Function description
*   通过在保留地址执行来触发BusFault或HardFault。
*
*  Additional Information
*    在无效地址执行时触发BusFault。
*    Related registers on fault:
*      HFSR = 0x40000000
*        FORCED = 1           - BusFault escalated to HardFault
*      BFSR = 0x00000001
*        IBUSERR = 1          - BusFault on instruction prefetch
*/
static int _IllegalFunc(void) {
  int r;
  int (*pF)(void);

  pF = (int(*)(void))0x00100001;         // 0x00100000-0x07FFFFFF is reserved on STM32F4
  //  F44F1380    mov.w r3, #0x00100001
  r = pF();
  //  4798        blx r3                 <- Branch to illegal address, causes fetch from 0x00100000 and fault exception
  return r;
}

UsageFault 使用故障示例

未定义的指令执行(Undefined Instruction Execution)
/*********************************************************************
*
*       _UndefInst()
*
*  Function description
*   通过执行未定义的指令触发UsageFault或HardFault。
*
*  Additional Information
*    UsageFault是在无效地址执行时触发的。
*    Related registers on hard fault:
*      HFSR = 0x40000000
*        FORCED = 1           - UsageFault escalated to HardFault
*      UFSR = 0x0001
*        UNDEFINSTR = 1       - Undefined instruction executed
*/
static int _UndefInst(void) {
  static const unsigned short _UDF[4] = {0xDEAD, 0xDEAD, 0xDEAD, 0xDEAD}; // 0xDEAD: UDF #<imm> (permanently undefined)
  int r;
  int (*pF)(void);

  pF = (int(*)(void))(((char*)&_UDF) + 1);
  //  4B05        ldr r3, =0x08001C18 <_UDF> <- Load address of "RAM Code" instructions
  //  3301        adds r3, #1                <- Make sure Thumb bit is set
  r = pF();
  //  4798        blx r3                     <- Call "RAM Code", will execute UDF instruction and raise exception
  //  9000        str r0, [sp]
  return r;
}
非法状态(Illegal State)
/*********************************************************************
*
*       _NoThumbFunc()
*
*  Function description
*   通过执行未设置thumb的地址来触发 UsageFault 或 HardFault。
*
*  Additional Information
*    UsageFault是在无效地址执行时触发的。
*    Related registers on hard fault:
*      HFSR = 0x40000000
*        FORCED = 1           - UsageFault escalated to HardFault
*      UFSR = 0x0002
*        INVSTATE = 1         - Instruction execution with invalid state
*/
static int _NoThumbFunc(void) {
  int r;
  int (*pF)(void);

  pF = (int(*)(void))0x00100000;         // 0x00100000-0x07FFFFFF is reserved on STM32F4
  //  F44F1380    mov.w r3, #0x00100000  <- Note that bit [0] is not set.
  r = pF();
  //  4798        blx r3                 <- Branch exchange with mode change to ARM, but Cortex-M only supports Thumb mode.
  return r;
}
除以零(Division By Zero)
/*********************************************************************
*
*       _DivideByZero()
*
*  Function description
*   通过除以零触发UsageFault或HardFault。
*
*  Additional Information
*    UsageFault在除法指令上立即触发。
*    Related registers on hard fault:
*      HFSR = 0x40000000
*        FORCED = 1           - UsageFault escalated to HardFault
*      UFSR = 0x0200
*        DIVBYZERO = 1        - Divide-by-zero fault
*/
static int _DivideByZero(void) {
  int r;
  volatile unsigned int a;
  volatile unsigned int b;
  a = 1;
  //  2301        movs r3, #1       <- Load dividend
  b = 0;
  //  2300        movs r3, #0       <- Load divisor
  r = a / b;
  //  FBB2F3F3    udiv r3, r2, r3   <- divide by 0 raises fault exception
  return r;
}
未对齐访问
/*********************************************************************
*
*       _UnalignedAccess()
*
*  Function description
*   通过未对齐的字访问触发UsageFault或HardFault。
*
*  Additional Information
*    UsageFault在读取或写入指令时立即触发。
*    Related registers on fault:
*      HFSR = 0x40000000
*        FORCED = 1           - UsageFault escalated to HardFault
*      UFSR = 0x0100
*        UNALIGNED = 1        - Unaligned memory access
*/
static int _UnalignedAccess(void) {
  int r;
  volatile unsigned int* p;

  p = (unsigned int*)0x20000002;
  //  4B04        ldr r3, =0x20000002  <- Not word aligned address
  r = *p;
  //  681B        ldr r3, [r3]         <- Load word from unaligned address raises exception
  //  9300        str r3, [sp]
  return r;
}

HardFault 示例

非法向量表提取
/*********************************************************************
*
*       _IllegalVector()
*
*  Function description
*   通过使用非法矢量表进行中断来触发HardFault。
*
*  Additional Information
*    Related registers on fault:
*      HFSR = 0x00000002
*        VECTTBL = 1           - Vector table read fault
*/
static int _IllegalVector(void) {
  int r;

  SCB->VTOR = 0x001000000;            // Relocate vector table to illegal address  
  //  4B09        ldr r3, =0xE000ED00
  //  F04F7280    mov.w r2, #0x1000000
  //  609A        str r2, [r3, #8]
  SCB->ICSR = SCB_ICSR_PENDSVSET_Msk; // Trigger PendSV exception to read invalid vector
  //  4B07        ldr r3, =0xE000ED00
  //  F04F5280    mov.w r2, #0x10000000
  //  605A        str r2, [r3, #4]
  __ISB();
  //  F3BF8F6F    isb                 <- PendSV exception is to be executed. PendSV vector is tried to be read from illegal address 0x00100038 causes fault exception
  //  BF00        nop
  __DSB();
  //  F3BF8F4F    dsb sy
  //  BF00        nop
  return r;
}
[r3, #4]
  __ISB();
  //  F3BF8F6F    isb                 <- PendSV exception is to be executed. PendSV vector is tried to be read from illegal address 0x00100038 causes fault exception
  //  BF00        nop
  __DSB();
  //  F3BF8F4F    dsb sy
  //  BF00        nop
  return r;
}
  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值