S32K144异常处理代码的编译问题分析

NXP S32 DS for ARM与MDK for ARM编译异常处理程序的不同

在实践嵌入式RTOS的代码编写过程中,发现在MDK下运行很好的任务切换代码,在NXP DS中运行就会莫名的死机,异常为3. 调试了几个星期,最后确定是编译引起。对比NXP DS下的FreeeRTOS代码(运行正常),感觉应该以下红色部分的不同。

FreeRTOS:

#define xPortPendSVHandler                          PendSV_Handler

void xPortPendSVHandler( void ) __attribute__ (( naked ));

void xPortPendSVHandler( void )
{
    /* This is a naked function. */

    __asm volatile
    (
    "    mrs r0, psp                            \n"
    "    isb                                    \n"
    "                                        \n"
    "    ldr    r3, pxCurrentTCBConst            \n" /* Get the location of the current TCB. */
    "    ldr    r2, [r3]                        \n"
    "                                        \n"
    "    tst r14, #0x10                        \n" /* Is the task using the FPU context?  If so, push high vfp registers. */
    "    it eq                                \n"
    "    vstmdbeq r0!, {s16-s31}                \n"
    "                                        \n"
    "    stmdb r0!, {r4-r11, r14}            \n" /* Save the core registers. */
    "                                        \n"
    "    str r0, [r2]                        \n" /* Save the new top of stack into the first member of the TCB. */
    "                                        \n"
    "    stmdb sp!, {r3}                        \n"
    "    mov r0, %0                             \n"
    "    msr basepri, r0                        \n"
    "    dsb                                    \n"
    "   isb                                    \n"
    "    bl vTaskSwitchContext                \n"
    "    mov r0, #0                            \n"
    "    msr basepri, r0                        \n"
    "    ldmia sp!, {r3}                        \n"
    "                                        \n"
    "    ldr r1, [r3]                        \n" /* The first item in pxCurrentTCB is the task top of stack. */
    "    ldr r0, [r1]                        \n"
    "                                        \n"
    "    ldmia r0!, {r4-r11, r14}            \n" /* Pop the core registers. */
    "                                        \n"
    "    tst r14, #0x10                        \n" /* Is the task using the FPU context?  If so, pop the high vfp registers too. */
    "    it eq                                \n"
    "    vldmiaeq r0!, {s16-s31}                \n"
    "                                        \n"
    "    msr psp, r0                            \n"
    "    isb                                    \n"
    "                                        \n"
    #ifdef WORKAROUND_PMU_CM001 /* XMC4000 specific errata workaround. */
        #if WORKAROUND_PMU_CM001 == 1
    "            push { r14 }                \n"
    "            pop { pc }                    \n"
        #endif
    #endif
    "                                        \n"
    "    bx r14                                \n"
    "                                        \n"
    "    .align 2                            \n"
    "pxCurrentTCBConst: .word pxCurrentTCB    \n"
    ::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY)
    );
}

我的实验代码:

void PendSV_Handler(void)
{
    __asm volatile(
            "mrs r0, psp\n"
            "cbz r0, PendSVHander_nosave\n"
            "stmdb r0!, {r4-r11}\n"
            "ldr r1, =currenttask\n"
            "ldr r1, [r1]\n"
            "str r0, [r1]\n"
            "PendSVHander_nosave:\n"
            "ldr r0, =currenttask\n"
            "ldr r1, =nexttask\n"
            "ldr r2, [r1]\n"
            "str r2, [r0]\n"
            "ldr r0, [r2]\n"
            "ldmia r0!, {r4-r11}\n"
            "msr psp, r0\n"
            "orr lr, lr, #0x04\n"
            "bx lr\n"
    );
}

结果:大神的博客里说:“对于nake的不理解,查看了arm的文档。发现就是指定编译器不要产生序言和结尾。只能用__asm ”

加了 nake后,运行OK :)。

https://download.csdn.net/download/holmes_sun5/11869848

 

你可能感兴趣的:(S32K144异常处理代码的编译问题分析)