2011-12-15 22 views
5

Ho una struttura di configurazione che vorrei salvare sul flash interno di ARM cortex M3. Secondo le specifiche, i dati salvati nel flash interno devono essere allineati a 32 bit. Poiché ho un sacco di booleani e caratteri nella mia struttura, non voglio usare 32 bit per archiviare 8 bit ... Ho deciso di impacchettare la struttura usando il pragma del preprocessore __packed, quindi quando lo salvo come struttura intera , Devo solo assicurarmi che la dimensione della struttura sia divisibile per 4 (4 byte = 32 bit), lo faccio aggiungendo i byte di riempimento se necessario. Attualmente, durante lo sviluppo altero molto la struttura, e per renderla allineata con i 32 bit, ho bisogno di cambiare i byte del padding tutto il tempo. Attualmente, la struttura di guardare slike questoAllineamento della struttura C nella memoria FLASH interna

typedef __packed struct 
{ 
uint8_t status; 
uint16_t delay; 
uint32_t blabla; 
uint8_t foo[5]; 
uint8_t padding[...] // this has to be changed every time I alter the structure. 
} CONFIG; 

C'è un modo migliore per ottenere quello che sto facendo? Sono abbastanza nuovo nella programmazione Embedded, e voglio essere sicuro di non sbagliare.

Modifica: Nota. I dati viene mantenuto alla fine della interno-flash, in modo omettendo l'imbottitura non funzionerà ...

+1

Ho creduto che la tua comprensione non sia corretta. Le istruzioni nella memoria flash potrebbero dover essere allineate e ciò sarà garantito dal compilatore. Ma i dati memorizzati in flash anche non allineati possono essere gestiti da core di corte cortex m3. Quale MCU della tua azienda usi? –

risposta

4

Forse questa è un'idea:

typedef __packed struct { 
    uint8_t status; 
    uint16_t delay; 
    uint32_t blabla; 
    uint8_t foo[5]; 
} CONFIG; 

typedef __packed struct { 
    CONFIG cfg; 
    uint8_t padding[4 - (sizeof(CONFIG) % 4)] 
} CONFIGWRAPPER; 
+0

In realtà quando ci penso. Se è già allineato, aggiungiamo 4 byte per nulla – stdcall

4

Soluzione 1: Si potrebbe mettere dentro un sindacato contenente la vostra struttura e una serie di personaggi:

union 
{ 
    CONFIG config; 
    uint8_t total_size[32]; 
} my_union; 
+0

Questo è interessante, diciamo che la dimensione di (CONFIG) è inferiore alla dimensione di total_size. e ho impostato la configurazione nel sindacato. quale sarà la sizeof (mia_union)? – stdcall

+0

Se 'CONFIG' è minore di' total_size', 'sizeof (mia_union)' sarà la dimensione di 'total_size', concretamente 32. – Lindydancer

1

Soluzione 2: Si potrebbe utilizzare la funzione IAR-specifica #pragma location per inserire i dati di configurazione in un luogo specifico, come 32 dalla fine del flash. In questo modo non avrebbe bisogno di pad struttura in alcun modo:

/* Fictitious end of flash location. */ 
#pragma location=0x1234FFE0 
struct [... your struct goes here ...] 
3

In primo luogo, l'allineamento al sacco è di solito da evitare, se si finisce con dati non allineati ai loro confini naturali, alcune CPU sarà solo emettere un trappola quando si tenta di accedervi.

Prima di tutto, memorizzare i membri in un ordine in modo che il compilatore non aggiunga spazi per l'allineamento (o se lo fa, lo aggiunge alla fine). Se puoi, chiedi al membro 1. di avere il requisito di allineamento che desideri, in quanto ciò costringe il compilatore a fornire almeno alla struttura un simile allineamento.

Ciò richiede alcune conoscenze su come i requisiti di allineamento della piattaforma e del compilatore, ad es. Sbarazzarsi di matrice imbottitura, e cambiare

typedef struct 
{ 
uint8_t status; 
uint16_t delay; 
uint32_t blabla; 
uint8_t foo[5]; 
uint8_t padding[...]; 
} CONFIG; 

a

typedef struct 
{ 
uint32_t blabla; 
uint16_t delay; 
uint8_t status; 
uint8_t foo[5]; 
} CONFIG; 

Poi dire al compilatore che questa struct ha bisogno di 4 byte di allineamento (in questo caso è probabile che già sarà come il primo membro ha 4 byte o più requisiti di allineamento). per esempio. con l'utilizzo gcc attribute((__aligned__(4))

poi scrivere un piccolo programma di test che convalida i requisiti di allineamento che avete (che è solo un piccolo programma che utilizza sizeof() e alignof() sul tuo struct), questo sarà anche dirvi se si è necessario aggiungere istruzioni per la struttura da allineare. Esegui quel programma come parte della build/packaging.

+0

Risposta eccellente e ben dichiarata. Il programma di test di esempio è fondamentale per il successo o l'insuccesso, NON è possibile saltare questo passaggio se si desidera eseguire ciò che si sta tentando di fare con le strutture nei domini di compilazione (considerare l'hardware come dominio di compilazione). –