RTOS调试专题移植问题

RTOS调试技术专题训练营中,我在freeRTOS工程移植coredump方法
课程只介绍了裸机HardFault 和 操作系统切换的PendSV上栈帧保存方式
所以我的问题是

  1. 异常中断还有MemManage,BusFault,UsageFault,是否可以统一使用HardFault 汇编处理方式呢?
  2. 在实际项目中,我使用课程上freeRTOS的PendSV汇编处理方式后,我系统跑不起来,还原后才能跑起来。这个处理方式需要注意什么?
    下图是我根据课程设置的异常处理方式,除了PendSV用不了课程的汇编配置,其余的默认用HardFault 的方式,


/*
	这是课程中 裸机的 HardFault栈帧处理方式,其他异常我都加载这份操作
*/
static void NAKED hal_trace_HardFault_handler(void)
{
    asm volatile (
        // 栈帧保存在MSP还是PSP?
        "TST     lr, #0x04         ;" // if(!EXC_RETURN[2]) 看看LR寄存器的BIT2是否为0
        "it eq                     ;" // 如果相等,则执行以下指令
        "MRSEQ   r0, msp           ;" // [2]=0 ==> 为0则使用MSP
        "it ne                     ;" // 如果不相等,则执行以下指令
        "MRSNE   r0, psp           ;" //[2]=1 ==> 为1则使用PSP

        "STMFD   r0!, {lr}         ;" //把LR即exec_return也保存起来
        "STMFD   r0!, {r4 - r11}   ;" //软件保存r4 - r11

        "TST     lr, #0x04         ;" //if(!EXC_RETURN[2]) // 看看LR寄存器的BIT2是否为0
        "it eq                     ;" // 如果相等,则执行以下指令
        "MSREQ   msp, r0           ;" //[2]=0 ==> 更新MSP, 下面要恢复MSP

        "PUSH    {lr}              ;"
        "BL      DumpCore          ;"
        "POP     {lr}              ;"

        "TST     lr, #0x04         ;" //if(!EXC_RETURN[2]) // 看看LR寄存器的BIT2是否为0
        "it eq                     ;" // 如果相等,则执行以下指令
        "POPEQ   {r4 - r11}        ;" //恢复MSP
        "it eq                     ;" // 如果相等,则执行以下指令
        "POPEQ   {lr}              ;" //恢复MSP
    );
}

/*
	这是课程中 freeRTOS的 PendSV栈帧处理方式,使用后,系统无法启动
*/
static void NAKED hal_trace_PendSV_handler(void)
{
    __asm volatile
    (
        "mrs r0, psp  \n"
        "isb  \n"
        /* Get the location of the current TCB. */
        "ldr	r3, =pxCurrentTCB  \n"
        "ldr	r2, [r3]  \n"

        /* Is the task using the FPU context?  If so, push high vfp registers. */
        "tst r14, #0x10  \n"
        "it eq  \n"
        "vstmdbeq r0!, {s16-s31}  \n"

        /* Save the core registers. */
        "stmdb r0!, {r4-r11, r14}  \n"

        /* Save the new top of stack into the first member of the TCB. */
        "str r0, [r2]  \n"

        "stmdb sp!, {r0, r3}  \n"
        "mov r0, %0            \n"  // 使用 %0 引用输入操作数
        "msr basepri, r0  \n"
        "dsb  \n"
        "isb  \n"
        "bl vTaskSwitchContext  \n"
        "mov r0, #0 \n"
        "msr basepri, r0 \n"
        "ldmia sp!, {r0, r3} \n"

        /* The first item in pxCurrentTCB is the task top of stack. */
        "ldr r1, [r3] \n"
        "ldr r0, [r1] \n"

        /* Pop the core registers. */
        "ldmia r0!, {r4-r11, r14}  \n"

        /* Is the task using the FPU context?  If so, pop the high vfp registers
        too. */
        "tst r14, #0x10  \n"
        "it eq  \n"
        "vldmiaeq r0!, {s16-s31}  \n"

        "msr psp, r0 \n"
        "isb  \n"
        #ifdef WORKAROUND_PMU_CM001 /* XMC4000 specific errata */
          #if WORKAROUND_PMU_CM001 == 1
        "    push { r14 }  \n"
        "    pop { pc }  \n"
        "    nop    \n"
          #endif
        #endif

        "bx r14 \n"
        :
        : "i" (configMAX_SYSCALL_INTERRUPT_PRIORITY)
    );
}

/*
	这是目前我工程能正常启动的 PendSV
*/
static void NAKED hal_trace_PendSV_handler(void)
{
	asm volatile (
        // Get special_regs(primask/faultmask/basepri/control)
        "mrs r0, primask;"
        "mrs r1, faultmask;"
        "mrs r2, basepri;"
        "mrs r3, control;"
        "bfi r12, r0, #0, #8;"
        "bfi r12, r1, #8, #8;"
        "bfi r12, r2, #16, #8;"
        "bfi r12, r3, #24, #8;"
        // Check EXC_RETURN.MODE (bit[3]) and EXC_RETURN.SPSEL (bit[2])
        "and r3, lr, #0x0C;"
        "teq r3, #0x0C;"
        "ite eq;"
        // Using PSP
        "mrseq r3, psp;"
        // Using MSP
        "mrsne r3, msp;"
        "_save_msp_lr:;"
        // Save original MSP and current exception lr
        "mrs r0, msp;"
        "push {r0, lr};"
        ".cfi_def_cfa_offset 4*2;"
        ".cfi_rel_offset lr, 4*1;"
        "_check_fp_cntx:;"
        // Check EXC_RETURN.FType (bit[4])
        "tst lr, #0x10;"
        "ite eq;"
        // FPU context saved
        "moveq r1, #1;"
        // No FPU context
        "movne r1, #0;"
        // Make room for r0-r15,psr,special_regs(primask/faultmask/basepri/control)
        "sub sp, #4*18;"
        ".cfi_adjust_cfa_offset 4*18;"
        // Save r4-r11
        "add r0, sp, #4*4;"
        "stm r0, {r4-r11};"
        ".cfi_rel_offset r4, 4*4;"
        ".cfi_rel_offset r5, 4*5;"
        ".cfi_rel_offset r6, 4*6;"
        ".cfi_rel_offset r7, 4*7;"
        ".cfi_rel_offset r8, 4*8;"
        ".cfi_rel_offset r9, 4*9;"
        ".cfi_rel_offset r10, 4*10;"
        ".cfi_rel_offset r11, 4*11;"
        // Save r0-r3
        "ldm r3, {r4-r7};"
        "stm sp, {r4-r7};"
        ".cfi_rel_offset r0, 4*0;"
        ".cfi_rel_offset r1, 4*1;"
        ".cfi_rel_offset r2, 4*2;"
        ".cfi_rel_offset r3, 4*3;"
        // Save r12
        "ldr r0, [r3, #4*4];"
        "str r0, [sp, #4*12];"
        ".cfi_rel_offset r12, 4*12;"
        // Save sp
        "teq r1, 0;"
        "itt eq;"
        "addeq r0, r3, #4*8;"
        "beq _done_stack_frame;"
        "add r0, r3, #4*(8+18);"
        "_done_stack_frame:;"
        // -- Check RETPSR.SPREALIGN (bit[9])
        "ldr r4, [r3, #4*7];"
        "tst r4, #(1 << 9);"
        "it ne;"
        "addne r0, #4;"
        "str r0, [sp, #4*13];"
        // Save lr
        "ldr r0, [r3, #4*5];"
        "str r0, [sp, #4*14];"
        // Save pc
        "ldr r0, [r3, #4*6];"
        "str r0, [sp, #4*15];"
        // Save PSR
        "ldr r0, [r3, #4*7];"
        "str r0, [sp, #4*16];"
        // Save special_regs(primask/faultmask/basepri/control)
        "str r12, [sp, #4*17];"
        "_call_fault_handler:;"
        // Invoke the fault handler
        "mov r0, sp;"
        "mov r1, 0;"
        "mov r2, 0;"
        "ldr r3, =hal_trace_fault_dump;"
        "blx r3;"
        // Restore r4-r7
        "add r0, sp, #4*4;"
        "ldm r0, {r4-r7};"
        // Restore sp
        "add sp, #18*4;"
        ".cfi_adjust_cfa_offset -4*18;"
        "pop {r0, lr};"
        ".cfi_adjust_cfa_offset -4*2;"
        ".cfi_restore lr;"
        ".cfi_def_cfa_offset 0;"
        "bx lr;"
        ""
        );
}
  1. 异常中断还有MemManage,BusFault,UsageFault,是否可以统一使用HardFault 汇编处理方式呢?
    可以
  1. 在实际项目中,我使用课程上freeRTOS的PendSV汇编处理方式后,我系统跑不起来,还原后才能跑起来。这个处理方式需要注意什么?

我不理解你这句话,你改了哪些异常处理函数,导致系统无法运行?
你谈到的MemManage,BusFault,UsageFault,它们发生时都是系统崩溃了。所以你再怎么改MemManage,BusFault,UsageFault,都不会导致系统无法运行。