2009-11-09 7 views
21

Devo memorizzare istruzioni, comandi che riceverò via seriale. I comandi saranno lunghi 8 bit.8 bit enum, in C

Devo mantenere la trasparenza tra il nome del comando e il suo valore. Al fine di evitare di dover tradurre un numero a 8 bit ricevuto in serie in qualsiasi tipo.

Mi piacerebbe utilizzare Enumerazioni per gestirle nel mio codice. Solo un'enumerazione corrisponde a su questa piattaforma un numero intero a 16 bit.

La piattaforma è microcontroller AVR ATmega169V, su Butterfly demo board. È un sistema a 8 bit con un supporto limitato per le operazioni a 16 bit. Non è un sistema veloce e ha circa 1 KB di RAM. Non ha alcun lusso come I/O di file o sistemi operativi.

Quindi qualche suggerimento su quale tipo dovrei usare per memorizzare comandi a 8 bit?
Deve esserci qualcosa di meglio di un enorme header di #defines.

+2

+1 - Buona domanda e ottimizzazione sensibile. –

+0

L'arco è a 8 bit. –

risposta

34

gcc s' -fshort-enums potrebbe essere utile:

assegnare a un tipo 'enum' solo come tanti byte come ha bisogno per la range dichiarato di valori possibili. In particolare, il tipo "enum" sarà equivalente a il tipo intero più piccolo che ha spazio sufficiente.

Infatti, here è una pagina con molte informazioni pertinenti. Spero che vi imbattete in molti switch GCC che non sapevate esistessero. ;)

+5

Aggiungo che alla mia collezione di utili switch gcc che non sapevo mai esistessero. –

+4

Ha, ho realizzato oggi che se eseguo il compilatore tramite AVR studio 4 IDE, è attivato per impostazione predefinita –

+0

Vorrei aggiungere che alla ricezione del comando, probabilmente si desidera assicurarsi che il valore in entrata di 8 bit sia effettivamente un valore valido dal proprio enum prima di digitare convert e memorizzarlo come enum. – ndim

3

Non vedo perché un enum non funzionerebbe. Confronti con, e assegnazioni da, un enum dovrebbero funzionare tutti bene con l'allargamento predefinito. Fai attenzione che i tuoi valori a 8 bit siano firmati correttamente (penso che vorrai un'estensione senza segno).

Si otterranno i confronti a 16 bit in questo modo, spero che non sia un problema di prestazioni (non dovrebbe esserlo, specialmente se il processore è a 16 bit come sembra).

+0

la cosa è, il mio ingresso seriale è più deinititly 8 bit. Non sono sicuro che l'ALU funzioni a 16 o 8 bit. La maggior parte delle console di assemblaggio funzionano solo con byte da 8 bit, ci sono meno di 5 che funzionano con parole da 2 byte (ADDW, MOVW è tutto ciò che posso ricordare). Solo –

+0

Ho controllato, è 8bit –

+4

@oxinabox - Non sono ancora sicuro che ciò abbia a che fare con la dimensione del tipo di enum. Memorizza i valori a 8 bit in una variabile 'uint8_t' (o qualcos'altro che corrisponde a un byte). Sarai comunque in grado di confrontare e assegnare loro i valori enum (a patto che l'enumerazione sia inferiore a 256). Basta non usare il tipo di enum come tipo di variabile se la dimensione esatta è importante per l'applicazione –

1

compilatore di Microsoft C ti permette di fare qualcosa di simile, ma è un'estensione (è di serie in C++ 0x):

enum Foo : unsigned char { 
    blah = 0, 
    blargh = 1 
}; 

Dal momento che hai contrassegnato GCC, io non sono del tutto sicuro se lo stesso la cosa è possibile, ma GCC potrebbe avere un'estensione nella modalità gnu99 o qualcosa del genere. Dagli un giro.

+0

Umm, I tagged AVR-GCC. Dovrò cercare quali estensioni supporta –

+0

Sono interessato a quello che trovi. Questo è stato un colpo istintivo. –

+0

E sembra che MS sia l'unico che supporta tale sintassi. –

0

mi consiglia di rimanere enum in ogni caso, per le seguenti ragioni:

  • Questa soluzione consente di mappare valori di comando direttamente a ciò che il vostro protocollo seriale si aspetta.
  • Se si utilizza realmente l'architettura a 16 bit, non c'è un così grande numero di vantaggi da passare al tipo a 8 bit. Pensa ad aspetti diversi da 1 byte di memoria salvati.
  • In alcuni compilatori ho utilizzato la dimensione effettiva dell'enumerazione utilizzata numero minimo di bit (le enumerazioni che potevano essere adattate nel byte utilizzavano solo byte, quindi 16 bit e poi 32).

Innanzitutto non dovresti preoccuparti della larghezza del tipo reale. Solo se hai davvero bisogno di un modo efficace di archiviazione dovresti usare i flag del compilatore come -fshort-enums sul compilatore GNU ma non li consiglio a meno che tu non ne abbia davvero bisogno.

Come ultima opzione è possibile definire "enum" come dati di presentazione per i comandi e utilizzare la conversione in byte con 2 semplici operazioni per memorizzare/ripristinare il valore di comando in/dalla memoria (e incapsulare questo in un unico punto). Che dire di questo? Si tratta di operazioni molto semplici che consentono anche di incorporarle (ma consente di utilizzare realmente solo 1 byte per l'archiviazione e dall'altra parte per eseguire operazioni utilizzando la maggior parte dell'enumerazione utilizzabile.

+0

Architettura a 8 bit. ho controllato il dos hardware, è 8bit –

6

Si sta tentando di risolvere un problema

La tua domanda è codificata C. Nel linguaggio C i tipi di enum nel contesto del valore sono completamente compatibili con i tipi interi e si comportano esattamente come altri tipi integrali.Quando vengono utilizzati nelle espressioni, sono sottoposti esattamente allo stesso promozioni integrali come altri tipi integrali. Una volta preso in considerazione, dovresti rend contoere che se si desidera memorizzare valori descritti da costanti di enumerazione in un tipo integrale a 8 bit, tutto ciò che si deve fare è scegliere un adatto 8-bit generico tipo integrale (ad esempio int8_t) e usarlo al posto del tipo enum. Perderai assolutamente nulla memorizzando i tuoi valori costanti enum in un oggetto di tipo int8_t (al contrario di un oggetto dichiarato esplicitamente con tipo enum).

Il problema che descriveresti esisterebbe in C++, dove i tipi di enum sono separati molto più da altri tipi di integrale. In C++ usando un tipo integrale al posto del tipo enum allo scopo di risparmiare memoria è più difficile (anche se possibile). Ma non in C, dove non richiede alcuno sforzo aggiuntivo.

+2

@ oxinabox.ucc.asn.au: il thread è comparso sulla prima pagina. Non so perché. Oh, capisco. * Lo hai * modificato (sostituendo "commento" con "encomio", BTW :) e ora accusi * me * di therad necromancy? – AnT

+0

BTW, non è stato male ha risposto perché è la migliore risposta di tutti. In C enum non è altro che una dichiarazione di costanti, la memorizzazione dei valori è indipendente dall'enumerazione. I miei 2 centesimi. –

+0

In generale, dovresti rispondere alla domanda nella tua risposta, non solo criticarla. – whoKnows

0

risposta che è rilevante per ARC compilatore (Citato da DesignWare Metaware C/Guida di C++ Programmer per ARC; sezione 11.2.9.2)

Dimensioni di enumerazioni Le dimensioni di un tipo enum dipende dalla stato di attivazione/disattivazione * Long_enums *.

■ Se l'opzione * Long_enums * è disattivata, il tipo di enum è il più piccolo di uno, due o quattro byte, in modo che tutti i valori possano essere rappresentati.

■ Se si attiva o disattiva * Long_enums *, un enum viene mappato su quattro byte (corrispondente alla convenzione AT & T Portable C Compiler).