This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

EK-TM4C123GXL: Using #pragma pack do not change the packing for struct

Part Number: EK-TM4C123GXL

Hey folks,

I want to write a little MQTT ibrary for GSM module (SIM868) and I encountert a very strange behavior while doing so. For paket transmitting I wanted to create packed structs in which I save all the information needed for a MQTT-packet (fixed header, variable header and payload). Therefor its important that every Byte is used and no Bytes are leaved empty. I am using Code Composer Studio 11 and TI-RTOS. Since now I dont really use any of the RTOS features, I have just created a task which should set up the connection and send a message to my server. The code I am using for creating the Structs is the following:

Deklaration:

* ***** Typdef Structs *****
 *
 * All Structs needed to represent MQTT-control-packets
 *
 * */

/* Fixed Header Struct */

#pragma pack(push,1)
typedef struct {
    char flags : 4;
    char paket_type : 4;
    char remaining_length : 8;
}fh_struct;
#pragma pack(pop)

/* ===== Connect Paket ===== */

/* Variable-Header-Struct for Connect */

#pragma pack(push,1)
typedef struct {
    char length_protokol_name_msb;
    char length_protokol_name_lsb;
    uint32_t  protokol_name;             // M Q T T
    char generation;                     // 4
    char flags;
    char keepalive_msb;
    char keepalive_lsb;
}vh_Connect_struct;
#pragma pack(pop)

/* Payload-Struct for Connect */

#pragma pack(push,1)
typedef struct {
    char client_id_length_msb;
    char client_id_length_lsb;
    uint32_t client_id;
}pl_Connect_struct;
#pragma pack(pop)

/* MQTT overall construct for Connect */

#pragma pack(push,1)
typedef struct {
    fh_struct fh_Connect;
    vh_Connect_struct vh_Connect;
    pl_Connect_struct pl_Connect;
    char escape;
}mqtt_paket_Connect_struct;
#pragma pack(pop)


/* ===== Publish Paket ===== */


/* Topic Struct */

#pragma pack(push,1)
typedef struct {
    char quantity1;
    char quantity2;
    uint16_t id;
}topic_struct;
#pragma pack(pop)

/* Variable-Header-Struct for Publish */

#pragma pack(push,1)
typedef struct {
    char topiclength_msb;
    char topiclength_lsb;
    topic_struct topic;
    char paket_id_msb;
    char paket_id_lsb;
}vh_publish_struct;
#pragma pack(pop)

/* Payload-Struct for Publish*/

#pragma pack(push,1)
typedef struct {
    char message_length_msb;
    char message_length_lsb;
    float message;
}pl_Publish_struct;
#pragma pack(pop)

/* MQTT overall construct for Publish */

#pragma pack(push,1)
typedef struct {
    fh_struct fixed_header;
    vh_publish_struct vh_Publish;
    pl_Publish_struct payload;
    char escape;
}mqtt_paket_Publish_struct;
#pragma pack(pop)

initialization:

mqtt_paket_Connect_struct mqtt_init_connect (void){

    conpak.fh_Connect.paket_type=1;
    conpak.fh_Connect.flags=0;
    conpak.fh_Connect.remaining_length=15;

    conpak.vh_Connect.length_protokol_name_msb=0;
    conpak.vh_Connect.length_protokol_name_lsb=4;
    conpak.vh_Connect.protokol_name=1414811981;        //MQTT
    conpak.vh_Connect.generation=4;
    conpak.vh_Connect.flags=2;
    conpak.vh_Connect.keepalive_msb=0;
    conpak.vh_Connect.keepalive_lsb=128;

    conpak.pl_Connect.client_id_length_msb=0;               
    conpak.pl_Connect.client_id_length_lsb=4;               
    conpak.pl_Connect.client_id=827151175;                 //GSM1

    conpak.escape=26;

    return(conpak);
}

mqtt_paket_Publish_struct mqtt_init_publish (void){

    pubpak.fixed_header.paket_type=3;
    pubpak.fixed_header.flags=0;
    pubpak.fixed_header.remaining_length=14;

    pubpak.vh_Publish.topiclength_msb=0;
    pubpak.vh_Publish.topiclength_lsb=4;
    pubpak.vh_Publish.topic.quantity1=116;      //t
    pubpak.vh_Publish.topic.quantity2=112;      //p -> Temperatur
    pubpak.vh_Publish.topic.id=2415;            //Dummie ID
    pubpak.vh_Publish.paket_id_msb=0;
    pubpak.vh_Publish.paket_id_lsb=1;

    pubpak.payload.message_length_msb=0;
    pubpak.payload.message_length_lsb=4;
    pubpak.payload.message=24.3;

    pubpak.escape=26;

    return(pubpak);
}

Im relativly new to this and I especially used #pragma pack for the first time. My structs are globaly defined as the following:

static mqtt_paket_Connect_struct conpak;
static mqtt_paket_Publish_struct pubpak;

What I realised after implementing my structs like this is, that in memory my structs are layet out like the following:  

You see that conpak (the mqtt_paket_Connet_struct ist layed out like it should with 19 Bytes which is correct (Fixed Header (2 Bytes) + Variable Header (10 Bytes) + Payload =(6 Bytes) + Escape Char = 19 Bytes). I just dont get why my pubpak (the mqtt_paket_publish_struct) is 32 Bytes when it should be 17 Bytes (Fixed Header (2 Bytes) + Variable Header  (8 Bytes) + Payload (6 Bytes) + Escape Char = 17 Bytes). I used the same kind of pragma pack operations in both cases so I just dont understand why it works for my connect paket but not for my publish paket. What I also found weird was, that sizeof(pubpak) gives me 17 as value nevertheless. 

Any help is highly aprreciatet . 

  • The size of pubpak is 17 bytes.  When I compile the code for it, this is the assembly code generated by the compiler to create it ...

    pubpak: .usect  ".bss:pubpak",17,1

    That 17 means reserve 17 bytes.  

    I think your question really is:  Why is there a gap of 15 bytes between the end of pubpak and the beginning of ti_uia_loggers_LoggerStopMode_Instance_State_0_hdr__?  One guess is that the type of ti_uia_loggers_LoggerStopMode_Instance_State_0_hdr__ requires that it be aligned to a 16 byte address.  Is that the case?

    Thanks and regards,

    -George