es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Alinea la estructura empaquetada en C para una alineación de 32 bits.

Tengo una estructura definida que se utiliza para mensajes enviados a través de dos interfaces diferentes. Uno de ellos requiere una alineación de 32 bits, pero necesito minimizar el espacio que ocupan. Básicamente, estoy tratando de empaquetar los bytes de las estructuras, es decir, #pragma pack(1), pero asegurándome de que la estructura resultante sea múltiplo de 32 bits. Estoy utilizando un compilador cruzado gcc arm para un procesador M3 de 32 bits. Lo que creo que quiero hacer es algo como esto:

#pragma pack(1)
typedef struct my_type_t
{
uint32_t someVal;
uint8_t anotherVal;
uint8_t reserved[];
}
#pragma pack()

donde asegura que el tamaño de my_type_t sea divisible por 4 bytes, pero sin codificar el tamaño de relleno. Puedo hacer algo así:

#pragma pack(1)
typedef struct wrapper_t
{
my_type_t m;
uint8_t reserved[sizeof(my_type_t) + 4 – (sizeof(my_type_t) % 4)]
}
#pragma pack()

pero me gustaría evitarlo.

En última instancia, lo que necesito hacer es copiar esto en un búfer que tenga una dirección de memoria de 32 bits, como:

static my_type_t t; //Si hace alguna diferencia, esto se declarará estáticamente en mi archivo de origen en C

memcpy(bufferPtr, (uint32_t*)&t, sizeof(t)) //o como quiera que deba hacer esto

He mirado el atributo attribute((align(N))), que me da la dirección de memoria alineada en 32 bits para la estructura, pero no la empaqueta en bytes. Estoy confundido acerca de cómo (o si) esto se puede combinar con pack(1).

Mi pregunta es la siguiente:

¿Cuál es la forma correcta de declarar estas estructuras para que pueda minimizar su huella en memoria pero permita copiarlas/configurarlas en incrementos de 4 bytes con un puntero sin signo de 32 bits? (Hay un montón de estos tipos de tamaño y contenido arbitrarios). Si mi enfoque anterior de combinar empaquetado y relleno va totalmente mal, aceptaría alternativas.

Editar:

Algunas limitaciones: No tengo control sobre una de las interfaces. Está esperando tramas empaquetadas en bytes. El otro lado son registros de memoria direccionable de 32 bits. Tengo 64 KB de memoria para todo el ejecutable, y estoy limitado en las bibliotecas, etc. que puedo usar. Ya he tenido que hacer una gran cantidad de optimización de espacio.

La estructura en esta pregunta fue solo para explicar mi pregunta. Tengo numerosos mensajes de contenido y tamaño variable a los que esto se aplica.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Se puede usar el atributo __attribute__((aligned(N))) para asegurar que la estructura esté alineada en una frontera de 32 bits. Esto asegurará que la estructura esté empaquetada en bytes y que se pueda copiar / configurar en incrementos de 4 bytes con un puntero de 32 bits.

    Por ejemplo:

    #pragma pack(1)
    typedef struct __attribute__((aligned(4))) my_type_t
    {
        uint32_t someVal;
        uint8_t anotherVal;
    }
    #pragma pack()
    

    Esto asegurará que la estructura esté empacada en bytes y que esté alineada en una frontera de 32 bits. Luego, se puede usar memcpy para copiar la estructura en un búfer que sea direccionable de 32 bits.

Comments are closed.