2

I'm using the AVR32 AT32UC3C0512C Microcontroller and ASF 3.11 Framework. I'm having some issues with the IAR compiler after updating IAR Workbench from 4.10 to 4.20 new version. I have found in IAR's technical support notes that some changes have been made related to inline assembly. (Acuallly not for EWAVR32 but EWAVR):

Error [Og005] + [Og006] when using inline assembler: Labels must be referred in the same assembler statement as they are declared. The behavior was not correct in earlier versions of the compiler platform. The new release uses a new internal compiler platform which is a bit more strict."

I'm having the same issue but the code, which is not able to compile belongs to the FreeRTOS port. I assume that the compiler does not recognize the label LABEL_INT_SKIP_RESTORE_CONTEXT_ because it is not defined in the same asm statement. Here is the code:

#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

I've been thinking to try to switch the context inside the asm statement (Call c function using inline assembly) but I'm not sure if this is the best option and if it really would work. So, it would be great to get some advice here, how to restore the context in another way and avoid the compiling error. Thank you!

In case you need it, you can easily find this code in the ASF as a FreeRTOS example (...asf-3.11.0\common\services\usb\class\msc\device\example_freertos\at32uc3c0512c_uc3c_ek\iar\example_freertos.eww)

4

1 回答 1

2

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

"RCALL vPortEnterCritical\n\t"
"RCALL vTaskSwitchContext\n\t"
"RCALL vPortExitCritical\n\t"

孔代码如下所示:

#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 的人。

于 2014-01-23T09:43:46.857 回答