2

AVR32 AT32UC3C0512Cマイクロコントローラーと ASF 3.11 フレームワークを使用しています。IAR Workbench を 4.10 から 4.20 の新しいバージョンに更新した後、IAR コンパイラに問題が発生しました。IAR のテクニカル サポート ノートで、インライン アセンブリに関連するいくつかの変更が行われたことを発見しました。(実際には EWAVR32 ではなく 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."

私は同じ問題を抱えていますが、コンパイルできないコードは FreeRTOS ポートに属しています。LABEL_INT_SKIP_RESTORE_CONTEXT_同じ 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_freertos\at32uc3c0512c_uc3c_ek\iar\example_freertos.eww )

4

1 に答える 1