2010-11-01 4 views
19

La RealView ARM C Compiler supports mettendo una variabile ad un dato indirizzo di memoria utilizzando l'attributo variabile at(address):Come posizionare una variabile ad un dato indirizzo assoluto in memoria (con GCC)

int var __attribute__((at(0x40001000))); 
var = 4; // changes the memory located at 0x40001000 

Vuol GCC hanno un attributo variabile simile?

+1

Ho scritto un [articolo] (http://a3f.at/articles/register-syntax-sugar), dove enumero i mezzi per farlo. Potrebbe essere utile per alcuni. – a3f

risposta

18

Non lo so, ma è possibile creare facilmente una soluzione del genere:

int *var = (int*)0x40001000; 
*var = 4; 

Non è esattamente la stessa cosa, ma nella maggior parte delle situazioni un perfetto sostituto. Funzionerà con qualsiasi compilatore, non solo GCC.

Se si utilizza GCC, si presume che si utilizzi anche GNU ld (sebbene non sia una certezza, ovviamente) e ld ha il supporto per il posizionamento delle variabili wherever you want them.

Immagino che lasciare che il linker faccia quel lavoro è abbastanza comune.

Ispirato dalla risposta di @rib, aggiungo che se l'indirizzo assoluto è per qualche registro di controllo, aggiungerei volatile alla definizione del puntatore. Se è solo RAM, non importa.

+0

+1 per la creatività. Non so se funziona davvero, ma suona davvero plausibile, oltre che portatile (nel senso che dovrebbe funzionare per tutti i compilatori). – falstro

+1

@roe: È un trucco abbastanza standard utilizzabile nei driver di periferica per l'hardware con registri di controllo mappati a memoria fissa. In un'applicazione utente standard, non ha alcuna utilità a cui possa pensare. – JeremyP

+0

@JeremyP, nei dispositivi embedded, specialmente quelli senza MMU, è fin troppo comune lasciare che le "applicazioni utente" colpiscano l'hardware. –

8

è possibile utilizzare la section attributes e un ld linker script per definire l'indirizzo desiderato per quella sezione. Questo è probabilmente più disordinato delle tue alternative, ma è un'opzione.

+3

Si noti che questo approccio * riserva effettivamente * lo spazio per la variabile, piuttosto che semplicemente supponendo che esista all'indirizzo specificato. In molti casi, questo è quello che vuoi. – larskholte

+0

Un link più diretto per gli attributi della sezione: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#Common-Variable-Attributes e ctrl + f per "section" – Ponkadoodle

0
extern const uint8_t dev_serial[12]; 
    asm(".equ dev_serial, 0x1FFFF7E8"); 
/* or asm("dev_serial = 0x1FFFF7E8"); */ 
    ... 

    for (i = 0 ; i < sizeof(dev_serial); i++) 
     printf((char *)"%02x ", dev_serial[i]); 
+0

Cosa aggiunge alle risposte esistenti? – OrangeDog

+0

Anche se questo snippet di codice può risolvere la domanda, [compresa una spiegazione] (https://meta.stackexchange.com/questions/114762/explaining-entually-code-based-answers) aiuta davvero a migliorare la qualità del tuo post. Ricorda che stai rispondendo alla domanda per i lettori in futuro, e queste persone potrebbero non conoscere le ragioni del tuo suggerimento sul codice. Cerca anche di non affollare il tuo codice con commenti esplicativi, questo riduce la leggibilità sia del codice che delle spiegazioni! –

Problemi correlati