2013-06-07 14 views
6

Ho creato una sezione chiamata .co_stack nel mio file C e ho un array chiamato pulStack per definire l'area.Importazione di un simbolo dal file C nello script linker

#define STACK_SIZE  0x00003000  /*!< Stack size (in Words)   */ 
__attribute__ ((section(".co_stack"))) 
unsigned long pulStack[STACK_SIZE]; 

mio gcc script del linker che definisce la sezione pila assomiglia a questo

.co_stack : { 
    _fstackptr = ORIGIN(ram) + LENGTH(ram) - 4; 
    _fstacksize = 0x00003000 * 4;  
    . = (_fstackptr - _fstacksize); 
    *(.co_stack .co_stack.*) 
} 

Come potete vedere io alla fine di definire la dimensione dello stack in 2 posti. Uno come STACK_SIZE nel mio file .c e _fstacksize nel mio file .ld.

Come posso definire questo in un solo posto?

Ad es. Voglio creare una variabile pulStackSize come segue.

const unsigned long pulStackSize = sizeof(pulStack); 

voglio definire _fstacksize nel file di .LD come

_fstacksize = STACK_SIZE * 4; 

Se faccio questo, ottengo un errore che dice di stack traboccato da 48K byte.

Come posso importare un simbolo da .c nel mio file .ld?

+0

STACK_SIZE non ha un simbolo, è una MACRO. Puoi importare in file ld usando EXTERN – neagoegab

risposta

10

Alcune soluzioni (alla domanda più generale "come condividere i valori tra C e lo script LD?"):

1) (NOTA: per questa soluzione darò per scontato che si sta utilizzando una versione recente di GNU ld, docs qui: http://www.math.utah.edu/docs/info/ld_3.html)

È possibile associare un valore assoluto a un simbolo all'interno dello script definendolo al di fuori dei composti della sezione (ad esempio all'inizio dello script). Di quanto tu possa importare il simbolo in C definendolo come extern. Attenzione che il valore è necessario in C è l'indirizzo del simbolo:

Script:

StackSize = 0x00003000 * 4; /* the size */ 
.co_stack : { 
    _fstackptr = ORIGIN(ram) + LENGTH(ram) - 4; 
    _fstacksize = StackSize;  
    . = (_fstackptr - _fstacksize); 
    *(.co_stack .co_stack.*) 
} 

C:

extern long StackSize; 
#define STACK_SIZE (((size_t)&StackSize)/sizeof(long)) 

Questa soluzione può imporre restrizioni nell'uso del valore ottenuto, per esempio maggior parte dei compilatori non accetteranno una linea come questa:

long my_stack[STACK_SIZE]; 

ma non hai bisogno di più, dal momento che si può definire la "my_stack" simbolo all'interno dello script e importarlo come "lungo my_stack extern [];" . Penso che sia comunque una limitazione accettabile.

2) Un altro modo è definire nello script due simboli situati all'inizio e alla e della sezione e importarli come "extern char" in C. La dimensione della sezione in byte è la differenza della loro due indirizzi. Questa soluzione ha la stessa limitazione di (1)

3) Se il linker non è abbastanza intelligente, è possibile utilizzare il preprocessore C per produrre uno script adatto in fase di compilazione espandendo la macro STACK_SIZE come in C. È necessario

a) creare il file "stacksize".h" contenente

#define STACK_SIZE 0x3000 

b) Aggiungere la riga # include "stacksize.h" all'inizio dello script e utilizzare STACK_SIZE quando ne hai bisogno. Salvare lo script come "ldscript.c".

c) nel makefile (o procedura di compilazione equivalente) invocare il preprocessore Se si dispone di GCC il comando è:..

gcc -P -E ldscript.c -o ldscript.ld 

si prega di notare che alcune versioni di gcc danno un significato speciale per l'estensione del file di input Quindi suggerisco di usare ".c", è il modo più sicuro.

d) Utilizzare il file "ldscript.ld" prodotto dal preprocessore C come script di collegamento

+0

Grazie per le risposte. (1) e (2) non sono applicabili perché ho bisogno di definire l'ultimo indirizzo della pila nella mia tabella vettoriale. Non posso farlo per i motivi che hai menzionato in (2). Ho provato a fare (3) ma non è stato generato ldscript.ld. Invece un messaggio "arm-none-eabi-gcc.exe: warning: ldsource.script: file di input del linker non usato perché il collegamento non è stato eseguito". Quindi (3) non è utile. Alla fine (4) sembrava essere giusto. Ma vedo ". = _fstackptr - SIZEOF (.co_stack);" non funziona come SIZEOF() è applicabile alla sezione OUTPUT solo mentre ho bisogno della dimensione della sezione di input. –

+0

@dexkid Uhm, provato (3) con alcune estensioni di file di input differenti. Tutto ha funzionato, tranne ".ld" (come INPUT). La tua versione gcc probabilmente interpreta l'estensione ".source" come ld script! Il mio usa infatti ".src" e ".ld". Ti suggerisco di scegliere un'estensione diversa per il file di input (ad esempio ".c", anche se è piuttosto strano). Per favore fatemi sapere se avete successo. –

+1

PS: ho usato il trucco (3) per anni ... –

Problemi correlati