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:使用#pragma pack不更改struct的打包

Guru**** 2524550 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1098370/ek-tm4c123gxl-using-pragma-pack-do-not-change-the-packing-for-struct

部件号:EK-TM4C123GXL

大家好,

我想为GSM模块(SIM868)编写一个微MQTT库,但在这样做时遇到了非常奇怪的行为。 对于paket传输,我想创建打包的结构,在其中保存MQTT包(固定标头,变量标头和有效负载)所需的所有信息。 因此,必须使用每个Byte,并且不能将任何字节留空。 我正在使用Code Composer Studio 11和TI-RTOS。 因为现在我真的不使用任何RTOS功能,所以我刚刚创建了一个任务,该任务应该设置连接并向我的服务器发送消息。 我用于创建结构的代码如下:

声明:

* ***** 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)

初始化:

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);
}

我对这个问题比较陌生,我第一次特别使用#pragma包。 我的结构被全局定义为以下内容:

static mqtt_paket_Connect_struct conpak;
static mqtt_paket_Publish_struct pubpak;

我在实现我的结构后意识到,在记忆中,我的结构是像以下那样被分层的:   

您会看到该conpak (MQTT_paket_Connet_structt以19字节的方式显示出来,这是正确的(固定标头(2字节)+变量标头(10字节)+有效负载=(6字节)+转义字符=19字节)。 我不明白为什么我的pubpak (MQTT_paket_publish_struct)是32字节,而它应该是17字节(固定标头(2字节)+变量标头 (8字节)+有效负载(6字节)+退出字符=17字节)。 我在两种情况下都使用了相同类型的pragma pack操作,所以我不明白为什么它适用于我的connect paket,而不适用于我的发布paket。 我还发现奇怪的是,尽管如此,sizeof(pubpak)还是给了我17个值。  

任何帮助都是高精度的。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    pubpak的大小为17字节。  当我为它编译代码时,这是编译器生成的汇编代码,用于创建它...

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

    这17表示保留17字节。   

    我想您的问题真的是: 为什么pubpak的结尾ti_uia_loggers_LoggerStopMode_Instance_State_0_HDR__的开头之间有15个字节的间距?  一种猜测是 ,ti_uia_loggers_LoggerStopMode_Instance_State_0_HDR__的类型要求它与16字节地址对齐。  是这样吗?

    谢谢,此致,

    -George