2013-09-06 4 views
2

J'utilise le microcontrôleur AVR32 AT32UC3C0512C et le cadre ASF 3.11. Je rencontre des problèmes avec le compilateur IAR après la mise à jour de IAR Workbench de la version 4.10 vers 4.20. J'ai trouvé dans les notes de soutien technique de l'IAR que certains changements ont été apportés à l'assemblage en ligne. (Acuallly pas EWAVR32 mais EWAVR):Nouvel EWAVR32 de l'IAR (4.20). Compilateur plus strict avec l'assemblage en ligne

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."

Je vais avoir le même problème, mais le code, ce qui est en mesure de compiler appartient au port FreeRTOS. Je suppose que le compilateur ne reconnaît pas l'étiquette LABEL_INT_SKIP_RESTORE_CONTEXT_ car il n'est pas défini dans la même instruction asm. Voici le 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 

J'ai pensé à essayer de changer le contexte dans l'instruction asm (appel fonction c à l'aide d'assembleur en ligne) mais je ne suis pas sûr que ce soit la meilleure option et si elle ça marcherait vraiment. Donc, ce serait bien d'obtenir quelques conseils ici, comment restaurer le contexte d'une autre manière et éviter l'erreur de compilation. Je vous remercie! Si vous en avez besoin, vous pouvez facilement trouver ce code dans l'ASF en tant qu'exemple FreeRTOS (... asf-3.11.0 \ common \ services \ usb \ class \ msc \ device \ example_freertos \ at32uc3c0512c_uc3c_ek \ iar \ example_freertos.eww)

+0

Avez-vous trouvé une solution pour cela? –

+0

Voir ci-dessous, je réponds juste à ma question. J'apprécie votre intérêt! – nebulant

Répondre

2

Eh bien, comme je l'ai déjà dit dans ma question, j'ai juste essayé de changer le contexte à l'intérieur de l'instruction asm (fonction Call c avec une instruction assembleur en ligne). Ainsi, en utilisant « RCALL » (appel relatif au sous-programme):

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

le code de trou ressemblerait à ceci:

#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; 
} 

Cela a fonctionné pour moi et je ne voyais pas si loin des différences dans la comportement de notre système. J'espère que cela peut aider quelqu'un à migrer de IAR Workbench 4.10 à 4.20.

Questions connexes