PORTING DEL CODICE
Per chi usa microcontrollori AVR, può essere utile sapere che con piccoli accorgimenti è possibile compilare con GCC/WinAVR il codice scritto per IAR-C. Ecco alcuni utilissimi consigli.
- Registri e locazioni di memoria possono avere diversi alias definiti nei files .H di IAR e di WinAVR. È dunque consigliato editare tali file per avere uniformità nella nomenclatura. Inoltre i file .H non vengono richiamati automaticamente ma devono essere inclusi esplicitamente utilizzando la direttiva #INCLUDE.
- In IAR le routines di interruzione vengono gestite utilizzando la direttiva #PRAGMA:
#pragma vector=TIMER0_0VF_vect __interrupt void NomeRoutine(){ //codice della routine }
In WinAVR la gestione delle routines di interruzione è estremamente semplificata usando la funzione ISR() come segue:
ISR(PCINT1_vect){ //codice della routine }
Le definizioni dei vettori di interruzione sono fatte nei relativi headers file e in WinAVR si dovrà includere il file avr/io.h. Si ricorda inoltre di includere anche il file avr/interrupt.h per evitare un comportamento errato del programma.
- Il compilatore IAR dispone di diverse funzioni intrinseche che hanno una corrispondente in WinAVR con nome sicuramente diverso. Queste funzioni sono in realtà blocchi di istruzioni assembler definite con una sintassi del tpo asm(“SEI”) seguita dal codice della funzione. È bene tenere presente che in WinAVR tali funzioni non sono definite in un header specifico, ma sono definite come macro dei diversi file .H.
- Il compilatore IAR consente di bloccare alcuni registri (da R15 a scendere) utilizzando la seguente sintassi: regvar no_init volatile unsigned int pippo @14. La linea precedente blocca il registro R14 fintanto che non viene esplicitamente referenziato nel codice dalla variabile pippo. È possibile fare una cosa analoga in WinAVR mediante la seguente sintassi:
register unsigned char pippo asm(“r14”);
- Il compilatore IAR dispone di comandi non standard per definire dati da memorizzare nell’area FLASH. WinAVR dispone di analoghi comandi abbinati a differenti parole chiave. È possibile prevedere la gestione dei due compilatori con i seguenti comandi:
// Uso con compilatore IAR C #if defined(__ICCAVR__) #define FLASH_DECLARE(x) __flash x #endif //Uso con compilatore GNU #if defined(__GNUC__) #define FLASH_DECLARE(x) x __attribute__((__progmem__)) #endif
In questo modo è possibile dichiarare una variabile pippo in Flash semplicemente con il comando FLASH_DECLARE(pippo) indipendentemente dal compilatore utilizzato. In WinAVR tutte le macro relative alla gestione delle variabili in Flash sono definite in avr/pgmspace.h.
- Entrambi i compilatori prevedono la dichiarazione del main() come funzione non-returning. Mentre in IAR la sintassi è __C_task void main(void){ //…codice…} in GCC si deve usare prima il prototipo della funzione quindi la funzione stessa:
void main(void) __attribute__((noreturn)); void main(void) { //…codice… }
La direttiva ‘#pragma’ è il metodo specificato dallo standard C per fornire ulteriori informazioni al compilatore. Specificano un metodo attraverso il quale fornisce funzionalità al sistema operativo. In genere sono diversi da compilatori a compilatori, impiegati proprio per descrivere operazioni preliminari al preprocessore prima di eseguire la compilazione.