2009-11-09 23 views
21

Tengo que almacenar las instrucciones, los comandos que recibiré en serie. Los comandos serán de 8 bits de largo.enum de 8 bits, en C

Necesito preservar la transparencia entre el nombre del comando y su valor. Para evitar tener que traducir un número de 8 bits recibido en serie a cualquier tipo.

Me gustaría usar Enumerations para tratar con ellos en mi código. Solo una enumeración corresponde a una en esta plataforma un entero de 16 bits.

La plataforma es el microcontrolador AVR ATmega169V, en el Butterfly demo board. Es un sistema de 8 bits con cierto soporte limitado para operaciones de 16 bits. No es un sistema rápido y tiene aproximadamente 1 KB de RAM. No tiene ningún lujo como archivo de E/S o un sistema operativo.

¿Alguna sugerencia sobre qué tipo debería usar para almacenar comandos de 8 bits?
Tiene que haber algo mejor que un encabezado masivo de #defines.

+2

+1 - Buena pregunta y una optimización sensata. –

+0

El es un arco de 8 bits. –

Respuesta

34

gcc 's -fshort-enums podría ser útil:

asignar a un tipo de 'enumeración' sólo como muchos bytes, ya que necesita para el rango de posibles valores declarados. Específicamente, el tipo "enum" será equivalente a el tipo entero más pequeño que tiene suficiente espacio.

De hecho, here es una página con mucha información relevante. Espero que encuentres muchos switches GCC que nunca supiste que existían. ;)

+5

Agregaré eso a mi colección de conmutadores gcc útiles que nunca pensé que existían. –

+4

Ha, me di cuenta hoy que si completé a través de AVR studio 4 IDE, entonces está activado por defecto –

+0

Me gustaría agregar que al recibir el comando, es probable que desee asegurarse de que el valor de 8bit entrante es realmente un valor válido de su enum antes de escribir convertir y almacenarlo como su enumeración. – ndim

3

No veo por qué una enumeración no funcionaría. Las comparaciones y asignaciones de una enumeración deberían funcionar correctamente con la ampliación predeterminada. Solo tenga cuidado de que sus valores de 8 bits estén firmados correctamente (creo que querría una extensión sin firmar).

Obtendrás comparaciones de 16 bits de esta manera, espero que no sea un problema de rendimiento (no debería ser así, especialmente si tu procesador es de 16 bits como suena).

+0

Lo que es, mi entrada de serie es más definitivamente de 8 bits. No estoy seguro de si la ALU funciona en 16 u 8 bits. La mayoría de las cadenas de montaje solo funcionan en bytes de 8 bits, hay menos de 5 que funcionan en palabras de 2 bytes (ADDW, MOVW es todo lo que puedo recordar). Solo –

+0

Lo comprobé, es 8bit –

+4

@oxinabox - Todavía no estoy seguro de que eso tenga que ver con el tamaño del tipo enum. Almacene los valores de 8 bits en una variable 'uint8_t' (u otra cosa que corresponda a un byte). Aún podrá compararlos y asignarles los valores enumerados (siempre que las enumeraciones sean inferiores a 256). Simplemente no use el tipo de enumeración como el tipo de variable si el tamaño exacto es importante para la aplicación –

1

compilador de C de Microsoft le permite hacer algo como esto, pero es una extensión (que es estándar en C++ 0x):

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

Puesto que usted etiquetado GCC, no estoy del todo seguro de si mismo es posible, pero GCC puede tener una extensión en el modo gnu99 o algo así. Darle un giro.

+0

Umm, etiqueté AVR-GCC. Tendré que buscar qué extensiones admite –

+0

Me interesa lo que encuentre. Esto fue un disparo visceral. –

+0

Y parece que MS es el único que admite tal sintaxis. –

0

lo recomiendo a permanecer en la enumeración, en cualquier caso por las siguientes razones:

  • Esta solución le permite asignar valores de orden directamente a lo que su protocolo serie espera.
  • Si realmente utiliza la arquitectura de 16 bits, no hay tantas ventajas para pasar al tipo de 8 bits. Piense en aspectos distintos de 1 byte de memoria guardado.
  • En algunos compiladores utilicé el tamaño real de enum utilizado un número mínimo de bits (enumeraciones que podrían caber en byte utilizado solamente byte, luego 16 bit luego 32).

En primer lugar, no debería preocuparse por el ancho de tipo real. Solo si realmente necesita una forma efectiva de almacenamiento, debe usar indicadores de compilación como -fshort-enums en el compilador GNU, pero no los recomiendo a menos que realmente los necesite.

Como última opción puede definir 'enum' como datos de presentación para los comandos y usar la conversión a byte con 2 operaciones simples para almacenar/restaurar el valor de comando a/desde la memoria (y encapsular esto en un solo lugar). ¿Qué hay de esto? Estas son operaciones muy simples, por lo que puede incluso alinearlas (pero esto le permite utilizar realmente solo 1 byte para el almacenamiento y desde el otro lado para realizar operaciones usando la enum más útil definida como desee.

+0

arquitectura de 8 bits. Revisé el hardware dos, es 8bit –

6

Está tratando de resolver una problema que no existe.

Su pregunta está etiquetada C. En lenguaje C, los tipos enum en contexto de valor son totalmente compatibles con los tipos integrales y se comportan igual que otros tipos integrales. Cuando se usan en expresiones, están sujetos exactamente a lo mismo promociones integrales como otros tipos integrales. Una vez que tenga esto en cuenta, debe tener en cuenta que si desea almacenar los valores descritos por las constantes de enumeración en un tipo integral de 8 bits, todo lo que tiene que hacer es elegir un 8 bits genérico adecuado tipo integral (digamos int8_t) y úselo en lugar del tipo enum. No perderá absolutamente nada almacenando sus valores constantes enum en un objeto del tipo int8_t (en oposición a un objeto explícitamente declarado con el tipo enum).

El problema que describes existiría en C++, donde los tipos enum están separados mucho más lejos de otros tipos integrales. En C++ usar un tipo integral en lugar del tipo enum para guardar la memoria es más difícil (aunque posible). Pero no en C, donde no requiere ningún esfuerzo adicional de ningún tipo.

+2

@ oxinabox.ucc.asn.au: El hilo apareció en la primera página. No sé por qué. Oh ya veo. * Usted * lo editó (reemplazando "comentario" por "encomiendo", BTW :) y ahora usted acusa * me * de therad nigromancia? – AnT

+0

Por cierto, no estuvo mal a lo que él respondió porque es la mejor respuesta de todas. En C enum no es más que una declaración de constantes, el almacenamiento de los valores es independiente de la enumeración. Mis 2 centavos. –

+0

En general, debe responder la pregunta en su respuesta, no solo criticarla. – whoKnows

0

respuesta que es relevante para ARC compilador (Citado de DesignWare Metaware C/Guía del programador de C++ para ARC; sección 11.2.9.2)

Tamaño de enumeraciones El tamaño de un tipo de enumeración depende de la estado de alternar * Long_enums *.

■ Si alternar * Long_enums * está desactivado, el tipo de enumeración se correlaciona con el más pequeño de uno, dos o cuatro bytes, de modo que se puedan representar todos los valores.

■ Si alternar * Long_enums * está activado, una enumeración se asigna a cuatro bytes (que coincide con la convención del compilador de C portátil AT &).