Uso de la directiva del compilador #pragma pack (1) en aplicaciones integradas

5

Recientemente he encontrado esta directiva de preprocesador #pragma pack (1) y me preguntaba por qué se está utilizando.

Busqué en Google el uso y descubrí que tiene otras opciones como push, pop, etc. ¿Alguien lo ha usado en su aplicación incrustada?

Me gustaría saber algunos ejemplos de cómo / por qué ha usado esta directiva y en qué tipo de procesador? ¿Cuáles son las ventajas y desventajas de usar esta directiva?

Gracias.

    
pregunta IntelliChick

3 respuestas

7

#pragma pack(1) garantiza que los elementos C struct se empaquetan en orden y en los límites de bytes. Puede ahorrar RAM, lo que a menudo es valioso en un microcontrolador.

Las estructuras empaquetadas también permiten la conversión directa sobre memorias intermedias de memoria para el intercambio de datos:

void f(void *buf)
{
  struct ip_header *hdr = (struct ip_header *)buf;
  hdr->dst = 0x8000001;
}

Ten cuidado cuando usas #pragma pack . Tiene un alcance global (ya que está en el preprocesador), por lo que olvidarse de desactivarlo afectará a cualquier archivo #include . Si solo quiere empacar ciertas estructuras, considere usar __attribute__ ((packed)) de GCC.

Sin embargo, debido a problemas de alineación, las estructuras empaquetadas pueden afectar el rendimiento. Por ejemplo:

Cuando está empaquetado en bytes:

struct
{
  uint8_t  a;
  uint32_t b;
  uint8_t  c;
  uint8_t  d:
};

Se almacenará como (sin tener en cuenta el endianness):

a, b0, b1, b2, b3, c, d

Sin embargo, muchas arquitecturas requieren que los accesos de 32 bits estén alineados con las direcciones de 32 bits. Con la estructura empaquetada, la máquina tendrá que hacer varios accesos de bytes y luego volver a unirlos nuevamente.

Frente al struct anterior sin el empaque habilitado, el compilador podría reorganizarlo como:

b0, b1, b2, b3, a, c, d

    
respondido por el Toby Jaffey
5

Otra razón para empaquetar estructuras en los límites de bytes es asegurar la alineación de los miembros al transferir datos entre diferentes procesadores.

A menudo necesito transferir estructuras de datos entre una MCU y una aplicación de PC host. La PC empaquetará las estructuras en los límites de 32 bits a menos que se le indique que las incluya en los límites de 1 byte. Una MCU PIC24F empaquetará estructuras en límites de 16 bits, a menos que se le indique que las incluya en límites de 1 byte.

Al indicarles a ambos que empaqueten sus estructuras en límites de 1 byte, se asegura de que los datos estén en el mismo lugar al acceder a ellos en cualquiera de los extremos. Sin él, tendría que rellenar las estructuras con bytes de reserva para que los miembros de los datos se alineen correctamente.

    
respondido por el Louis Davis
3

El uso tradicional donde he visto que se usa es para leer información de archivos. Por ejemplo, puede definir una estructura cuyos miembros coincidan con los de un encabezado de archivo BMP y luego leer todo el encabezado en una operación de lectura rápida. Bien, entonces BMP podría no ser el mejor ejemplo (su encabezado no tiene problemas de alineación en sistemas de 32 bits), pero entiendes la idea. Supongo que esto es igual de útil en el mundo incrustado.

    
respondido por el Vilx-

Lea otras preguntas en las etiquetas