公告

大中华汽车电子生态圈社区并入开发者社区- 更多资讯点击此

Tip / 登入 to post questions, reply, level up, and achieve exciting badges. Know more

cross mob

XMC实验分享之八十八: 一个HardFault bug定位实验

XMC实验分享之八十八: 一个HardFault bug定位实验

User12775
Level 5
Level 5
First solution authored First like received

这个话题之前发过, 但是好像很多人没有明白当中的原理. 不停地有人问我, 加上Dave这工具虽然好用, 但是小毛病其实不少, 尤其是几种特殊情况撞在一起了, 不用例子说明好难理解. 所以再来发一贴分享下使用Dave定位HardFault的一个过程.


首先要讲的是XMC1系列的MCU没有按照ARM公司的初衷来设计,具体表现是HardFault以及之下的Exception不是真正的向量式设计. XMC4纠正了这一不规范的行为. TLE等其他英飞凌公司的Cortex M系列的MCU都没有这问题. 这个严格来讲不是bug, 但是毫无意义的给程序员添堵. 如果你要使用XMC1系列的MCU, 调试HardFault的时候不得不把这个差异了解透, 但是这个知识在其他Cortex M的MCU上用不着. 非常D疼, 也没有办法.


按照向量式的的设计, Flash的向量表中都存放的ISR的函数指针, 比如另外一家的Cortex M0的向量表(没有贴完全,但可以说明问题):

__Vectors       DCD     __initial_sp                   ; Top of Stack
                DCD     Reset_Handler                  ; Reset Handler
                DCD     NMI_Handler                    ; NMI Handler
                DCD     HardFault_Handler              ; Hard Fault Handler
                DCD     0                              ; Reserved
                DCD     0                              ; Reserved
                DCD     0                              ; Reserved
                DCD     0                              ; Reserved
                DCD     0                              ; Reserved
                DCD     0                              ; Reserved
                DCD     0                              ; Reserved
                DCD     SVC_Handler                    ; SVCall Handler
                DCD     0                              ; Reserved
                DCD     0                              ; Reserved
                DCD     PendSV_Handler                 ; PendSV Handler
                DCD     SysTick_Handler                ; SysTick Handler

XMC1系列的向量表:

    .align 1
    
    .thumb_func
    .weak Default_handler
    .type Default_handler, %function
Default_handler:
    b  .
    .size Default_handler, . - Default_handler

    Insert_ExceptionHandler HardFault_Handler
    Insert_ExceptionHandler SVC_Handler
    Insert_ExceptionHandler PendSV_Handler
    Insert_ExceptionHandler SysTick_Handler
/* A couple of macros to ease definition of the various handlers */
.macro Insert_ExceptionHandler Handler_Func 
    .weak Handler_Func
    .thumb_set Handler_Func, Default_handler
.endm
    .globl HardFault_Veneer
HardFault_Veneer:
    MOVS r0, #4
    MOV r1, LR
    TST r0, r1
    BEQ stacking_used_MSP
    MRS R0, PSP // first parameter - stacking was using PSP
    B get_LR_and_branch
stacking_used_MSP:
    MRS R0, MSP // first parameter - stacking was using MSP
get_LR_and_branch:
    MOV R1, LR // Second parameter is LR current value
    LDR R2,=HardFault_Handler
    BX R2

    .long 0
    .long 0

最后为什么要放两个.long 0?

因为XMC1系列的MCU:

除了Reset也就是上电复位这个向量是在Flash当中, 其余向量都在固定的SRAM中. 所以汇编语言写的Handler不能超过所留的固定位置. 幸亏Cortex M0只有HardFault这一个Fault, 所以留的空间有一点.可以完成上面的Hard Fault的预处理.

因为Cortex M0的指令集又有16bit的Thumb,又有几个32bit的Thumb2指令, 这里的处理非常讨厌. 之所以增加两个.long 0是要最后生成的map文件这样:

 *(.XmcVeneerCode)
 .XmcVeneerCode
                0x2000000c      0x110 ./Startup/startup_XMC1100.o
                0x2000000c                HardFault_Veneer
                0x2000002c                SVC_Veneer

也就是HardFault_Veneer必须在0x2000000C, SVC_Veneer必须在0x2000002C. 如果汇编的Hard Fault的预处理代码超过了0x20个Byte, 那么要么你不用SVC这个Exception,要么就得压缩你的代码.


0 点赞
1129 次查看
3 评论