2011-10-04 19 views
6

Sto lavorando con FreeRTOS su un STM32 (Cortex-M3) e utilizzando la libreria CMSIS di ST per eseguire il bootstrap di tutto.Alias ​​GCC per funzionare fuori dall'unità di traduzione -AKA- questo è lo strumento giusto per il lavoro?

La libreria CMSIS definisce il simbolo debole SVC_Handler nel file ".s" di avvio. Deve essere sovrascritto da qualche parte al fine di ottenere il tuo ISR nella tabella vettoriale di interrupt. FreeRTOS definisce vPortSVCHandler, che è l'ISR che voglio gestire l'interrupt SVC.

Mi piacerebbe "incollare" i due insieme usando il mio codice applicazione (cioè senza modificare FreeRTOS o il codice sorgente CMSIS). Ho pensato che un alias sarebbe lo strumento giusto per il lavoro, così ho provato questo (in un file sorgente separato, main.c):

void SVC_Handler(void) __attribute__ ((alias ("vPortSVCHandler"))); 

che si traduce in: error: 'SVC_Handler' aliased to undefined symbol 'vPortSVCHandler'

risulta, in base alle Documentazione GCC qui http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html, per utilizzare l'attributo alias, non è possibile creare un alias di un simbolo all'esterno dell'unità di traduzione. Così ho pensato di provare a extern il simbolo in main.c in questo modo:

extern void vPortSVCHandler(void) __attribute__ ((naked)); 
void SVC_Handler(void) __attribute__ ((alias ("vPortSVCHandler"))); 

Questo genera lo stesso errore. Eventuali suggerimenti???

Vorrei davvero evitare di modificare nessuna delle librerie. So che potrei scrivere una funzione SVC_Handler che chiama semplicemente vPortSVCHandler, ma che potrebbe aggiungere un sovraccarico non necessario all'ISR (probabilmente in base alle impostazioni di ottimizzazione). Nota: gli esempi di FreeRTOS eseguono questo tramite un file di avvio personalizzato. Sto cercando un modo per farlo da C o il mio script linker.

  • versione del compilatore gcc version 4.5.2 (Sourcery G ++ Lite 2.011,03-42)
  • Obiettivo: ARM-nessuno-EABI

risposta

8

Si dovrebbe essere in grado di fare questo o con uno script del linker, o passando l'opzione appropriata per il linker, per esempio. per ld, --defsym=SVC_Handler=vPortSVCHandler

Vedere la documentazione binutils per ulteriori informazioni sull'opzione ld --defsym, e assignments in linker scripts

+1

Aggiungendo semplicemente "SVC_Handler = vPortSVCHandler;" all'inizio dello script del linker viene eseguito il lavoro. Sembra ancora disordinato, ma funziona. –

+0

Si noti che questa soluzione non sembra funzionare correttamente con LTO. Sembra che il simbolo venga sempre emesso puntando a 0x0 che porta a "CALL 0" nelle istruzioni generate. –

0

Sono abbastanza sicuro gestore SVC viene utilizzato solo da FreeRTOS all'avvio iniziale, quindi l'aggiunta di un gestore di eccezioni indirette non danneggerà le prestazioni (ma il suo è brutto). Meglio chiedere questo sul forum di FreeRTOS, la risposta di solito è ottima.

Spero che questo aiuti, Cordiali saluti, Dave

+0

Vorrei aggiungere che ho bisogno di fare questo w/gestore SysTick e PendSV pure. Potrei chiedere anche sui forum di FreeRTOS, ma è davvero più una domanda sulla toolchain GCC che su FreeRTOS. –

1

Un'altra soluzione che ho raccolte da uno degli esempi FreeRTOS è quello di aggiungere quanto segue al FreeRTOSConfig.h .. .

/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS 
standard names - or at least those used in the unmodified vector table. */ 
#define vPortSVCHandler SVC_Handler 
#define xPortPendSVHandler PendSV_Handler 
#define xPortSysTickHandler SysTick_Handler 

il file originale è da FreeRTOS/Demo/CORTEX_M0_LPC1114_LPCXpresso/RTOSDemo/Fonte/FreeRTOSConfig.h che integra anche l'orologio di sistema CMSIS nella config. Un ottimo punto di partenza per un progetto CMSIS/FreeRTOS.

2

Penso che il problema con alias sia che prevede una funzione dichiarata e definita, poiché si tratta solo di un alias. Vuoi usarlo come una forward-declaration di un'altra funzione. Ho una cosa simile a lavorare così:

void SVC_Handler(void) asm("vPortSVCHandler"); 

Questo rinomina il punto di ingresso del SVC_Handler, e se poi non definiscono, dovrebbe trovare vPortSVCHandler.

Vedi: https://gcc.gnu.org/onlinedocs/gcc/Asm-Labels.html

Problemi correlati