C IAR';s新的EWAVR32(4.20)。编译器对内联汇编要求更严格

C IAR';s新的EWAVR32(4.20)。编译器对内联汇编要求更严格,c,assembly,iar,C,Assembly,Iar,我使用的是AVR32 AT32UC3C0512C微控制器和ASF3.11框架。在将IAR Workbench从4.10更新到4.20新版本后,我对IAR编译器有一些问题。我在IAR的技术支持说明中发现,已经对内联装配进行了一些更改。(并非针对EWAVR32,而是针对EWAVR): 使用内联汇编程序时出现错误[Og005]+[Og006]:标签必须在声明时在同一汇编语句中引用。该行为在早期版本的编译器平台中不正确。新版本使用了一个新的内部编译器平台,这个平台更加严格。” 我也有同样的问题,但无法编

我使用的是AVR32 AT32UC3C0512C微控制器和ASF3.11框架。在将IAR Workbench从4.10更新到4.20新版本后,我对IAR编译器有一些问题。我在IAR的技术支持说明中发现,已经对内联装配进行了一些更改。(并非针对EWAVR32,而是针对EWAVR):

使用内联汇编程序时出现错误[Og005]+[Og006]:标签必须在声明时在同一汇编语句中引用。该行为在早期版本的编译器平台中不正确。新版本使用了一个新的内部编译器平台,这个平台更加严格。”

我也有同样的问题,但无法编译的代码属于FreeRTOS端口。我假设编译器无法识别标签
label\u INT\u SKIP\u RESTORE\u CONTEXT\u,因为它未在同一asm语句中定义。代码如下:

#define portRESTORE_CONTEXT_OS_INT() { extern volatile unsigned portLONG ulCriticalNesting; 
    extern volatile void *volatile pxCurrentTCB; 
    /* Check if AVR32_INTC_INT0 or higher were being handled (case where the OS tick interrupted another */ 
    /* interrupt handler (which was of a higher priority level but decided to lower its priority */ 
    /* level and allow other lower interrupt level to occur). */ 
    /* In this case we don't want to do a task switch because we don't know what the stack */ 
    /* currently looks like (we don't know what the interrupted interrupt handler was doing). */ 
    /* Saving SP in pxCurrentTCB and then later restoring it (thinking restoring the task) */ 
    /* will just be restoring the interrupt handler, no way!!! */

    __asm__ __volatile__ ( 
        "ld.w r0, sp[9*4]\n\t" /* Read SR in stack */ 
        "bfextu r0, r0, 22, 3\n\t" /* Extract the mode bits to R0. */ 
        "cp.w r0, 1\n\t" /* Compare the mode bits with supervisor mode(b'001) */ 
        "brhi LABEL_INT_SKIP_RESTORE_CONTEXT_"ASTRINGZ(__LINE__) ); 

    /* Else */ 
    /* because it is here safe, always call vTaskSwitchContext() since an OS tick occurred. */ 
    /* A critical section has to be used here because vTaskSwitchContext handles FreeRTOS linked lists. */ 
    portENTER_CRITICAL(); 
    vTaskSwitchContext(); 
    portEXIT_CRITICAL(); 

    /* Restore all registers */ 
    __asm__ __volatile__ ( 
        /* Set SP to point to new stack */ 
        "mov r8, LWRD("ASTRINGZ(pxCurrentTCB)")\n\t" 
        "orh r8, HWRD("ASTRINGZ(pxCurrentTCB)")\n\t" 
        "ld.w r0, r8[0]\n\t" 
        "ld.w sp, r0[0]\n" 

        "LABEL_INT_SKIP_RESTORE_CONTEXT_"ASTRINGZ(__LINE__)":\n\t" 

        /* Restore ulCriticalNesting variable */ 
        "ld.w r0, sp++\n\t" 
        "mov r8, LWRD("ASTRINGZ(ulCriticalNesting)")\n\t" 
        "orh r8, HWRD("ASTRINGZ(ulCriticalNesting)")\n\t" 
        "st.w r8[0], r0\n\t" 

        /* Restore R0..R7 */ 
        "ldm sp++, r0-r7\n\t" 

        /* Now, the stack should be R8..R12, LR, PC and SR */ 
        "rete" 
    ); 

    /* Force import of global symbols from assembly */ 
    ulCriticalNesting; 
    pxCurrentTCB; } 

#endif
我一直在考虑尝试在asm语句中切换上下文(使用内联汇编调用c函数),但我不确定这是否是最好的选择,以及它是否真的有效。因此,在这里获得一些建议,如何以另一种方式还原上下文并避免编译错误,这将是非常好的。谢谢


如果您需要它,您可以在ASF中很容易地找到此代码作为FreeRTOS示例(…ASF-3.11.0\common\services\usb\class\msc\device\example\u FreeRTOS\at32uc3c0512c\u uc3c\u ek\iar\example\u FreeRTOS.eww)

,正如我在问题中已经说过的,我只是试图在asm语句中切换上下文(使用内联汇编指令调用c函数)。因此,使用“RCALL”(对子例程的相对调用):

孔代码如下所示:

#define portRESTORE_CONTEXT_OS_INT() 
{ 
    extern volatile unsigned portLONG ulCriticalNesting; 
    extern volatile void *volatile pxCurrentTCB;

    /* Check if AVR32_INTC_INT0 or higher were being handled (case where the OS tick interrupted another */ 
    /* interrupt handler (which was of a higher priority level but decided to lower its priority */ 
    /* level and allow other lower interrupt level to occur). */ 
    /* In this case we don't want to do a task switch because we don't know what the stack */ 
    /* currently looks like (we don't know what the interrupted interrupt handler was doing). */ 
    /* Saving SP in pxCurrentTCB and then later restoring it (thinking restoring the task) */ 
    /* will just be restoring the interrupt handler, no way!!! */

    __asm__ __volatile__ ( 
        "ld.w r0, sp[9*4]\n\t" /* Read SR in stack */ 
        "bfextu r0, r0, 22, 3\n\t" /* Extract the mode bits to R0. */ 
        "cp.w r0, 1\n\t" /* Compare the mode bits with supervisor mode(b'001) */ 
        "brhi    LABEL_INT_SKIP_RESTORE_CONTEXT_"ASTRINGZ(__LINE__)"\n\t" 

        /* Else */ 
        /* because it is here safe, always call vTaskSwitchContext() since an OS tick occurred. */ 
        /* A critical section has to be used here because vTaskSwitchContext handles FreeRTOS linked lists. */ 
        "RCALL vPortEnterCritical\n\t"
        "RCALL vTaskSwitchContext\n\t"
        "RCALL vPortExitCritical\n\t" 

        /* Restore all registers */  
        /* Set SP to point to new stack */ 
        "mov r8, LWRD("ASTRINGZ(pxCurrentTCB)")\n\t" 
        "orh r8, HWRD("ASTRINGZ(pxCurrentTCB)")\n\t" 
        "ld.w r0, r8[0]\n\t" 
        "ld.w sp, r0[0]\n" 

        "LABEL_INT_SKIP_RESTORE_CONTEXT_"ASTRINGZ(__LINE__)":\n\t" 

        /* Restore ulCriticalNesting variable */ 
        "ld.w r0, sp++\n\t" 
        "mov r8, LWRD("ASTRINGZ(ulCriticalNesting)")\n\t" 
        "orh r8, HWRD("ASTRINGZ(ulCriticalNesting)")\n\t" 
        "st.w r8[0], r0\n\t" 

        /* Restore R0..R7 */ 
        "ldm sp++, r0-r7\n\t" 

        /* Now, the stack should be R8..R12, LR, PC and SR */ 
        "rete" 
    ); 

    /* Force import of global symbols from assembly */ 
    ulCriticalNesting; 
    pxCurrentTCB; 
} 

这对我来说很有效,到目前为止,我没有发现我们系统的行为有任何差异。我希望这能帮助那些必须从IAR Workbench 4.10迁移到4.20的人。

你找到解决方案了吗?请看下面,我只是回答我的问题。我感谢你的兴趣!
#define portRESTORE_CONTEXT_OS_INT() 
{ 
    extern volatile unsigned portLONG ulCriticalNesting; 
    extern volatile void *volatile pxCurrentTCB;

    /* Check if AVR32_INTC_INT0 or higher were being handled (case where the OS tick interrupted another */ 
    /* interrupt handler (which was of a higher priority level but decided to lower its priority */ 
    /* level and allow other lower interrupt level to occur). */ 
    /* In this case we don't want to do a task switch because we don't know what the stack */ 
    /* currently looks like (we don't know what the interrupted interrupt handler was doing). */ 
    /* Saving SP in pxCurrentTCB and then later restoring it (thinking restoring the task) */ 
    /* will just be restoring the interrupt handler, no way!!! */

    __asm__ __volatile__ ( 
        "ld.w r0, sp[9*4]\n\t" /* Read SR in stack */ 
        "bfextu r0, r0, 22, 3\n\t" /* Extract the mode bits to R0. */ 
        "cp.w r0, 1\n\t" /* Compare the mode bits with supervisor mode(b'001) */ 
        "brhi    LABEL_INT_SKIP_RESTORE_CONTEXT_"ASTRINGZ(__LINE__)"\n\t" 

        /* Else */ 
        /* because it is here safe, always call vTaskSwitchContext() since an OS tick occurred. */ 
        /* A critical section has to be used here because vTaskSwitchContext handles FreeRTOS linked lists. */ 
        "RCALL vPortEnterCritical\n\t"
        "RCALL vTaskSwitchContext\n\t"
        "RCALL vPortExitCritical\n\t" 

        /* Restore all registers */  
        /* Set SP to point to new stack */ 
        "mov r8, LWRD("ASTRINGZ(pxCurrentTCB)")\n\t" 
        "orh r8, HWRD("ASTRINGZ(pxCurrentTCB)")\n\t" 
        "ld.w r0, r8[0]\n\t" 
        "ld.w sp, r0[0]\n" 

        "LABEL_INT_SKIP_RESTORE_CONTEXT_"ASTRINGZ(__LINE__)":\n\t" 

        /* Restore ulCriticalNesting variable */ 
        "ld.w r0, sp++\n\t" 
        "mov r8, LWRD("ASTRINGZ(ulCriticalNesting)")\n\t" 
        "orh r8, HWRD("ASTRINGZ(ulCriticalNesting)")\n\t" 
        "st.w r8[0], r0\n\t" 

        /* Restore R0..R7 */ 
        "ldm sp++, r0-r7\n\t" 

        /* Now, the stack should be R8..R12, LR, PC and SR */ 
        "rete" 
    ); 

    /* Force import of global symbols from assembly */ 
    ulCriticalNesting; 
    pxCurrentTCB; 
}