硬汉嵌入式论坛

 找回密码
 立即注册
查看: 3622|回复: 9
收起左侧

调试结构体时出现奇怪的问题,不知道咋回事

[复制链接]

8

主题

36

回帖

60

积分

初级会员

积分
60
发表于 2016-7-10 23:01:34 | 显示全部楼层 |阅读模式
我有一个结构体定义如下:

typedef struct
{
  uint16_t    macFcf;
  uint8_t     macSeq;
  uint16_t    macDstPanId;
  uint16_t    macDstAddr;
  uint16_t    macSrcAddr;

  struct PACK
  {
    uint8_t   ackRequest : 1;
    uint8_t   security   : 1;
    uint8_t   linkLocal  : 1;
    uint8_t   multicast  : 1;
    uint8_t   reserved   : 4;
  }           nwkFcf;
  uint8_t     nwkSeq;
  uint16_t    nwkSrcAddr;
  uint16_t    nwkDstAddr;
  struct
  {
    uint8_t   nwkSrcEndpoint : 4;
    uint8_t   nwkDstEndpoint : 4;
  };
} NwkFrameHeader_t;

这个结构体定义的数据与一个数据缓冲区定义在同一个地址上如下:

union
  {
    NwkFrameHeader_t header;
    uint8_t    data[64];
  }nwkHearder;
当我向data中写入数据如下,出现数据错位错误:data[3]数据没掉了。

数据错误

数据错误



用sizeof获取结构体NwkFrameHeader_t的大小,结果竟然是18,按理应该是16才对,不知道咋回事。


希望有人能够帮忙解决下!
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107470
QQ
发表于 2016-7-11 09:24:09 | 显示全部楼层
结构体有字节对齐问题,如果你希望是你定义的几个字节,sizeof就是多个字节大小,可以改成:

__packed typedef struct  ,加上关键字__packed
回复

使用道具 举报

336

主题

2045

回帖

3058

积分

版主

Rank: 7Rank: 7Rank: 7

积分
3058
发表于 2016-7-11 09:37:56 | 显示全部楼层
你这个定义晦涩难懂,似乎在计算机考试啊。。。。

建议code还是简单明了好。
回复

使用道具 举报

6

主题

231

回帖

249

积分

高级会员

积分
249
发表于 2016-7-13 17:05:59 | 显示全部楼层
楼主没有说出你的对齐设置,你说结构的大小是18个字节,那么我推断是2字节对齐,因此分析如下:

typedef struct
{
  uint16_t    macFcf;
  uint8_t     macSeq;  // 这里占两个字节。
  uint16_t    macDstPanId;
  uint16_t    macDstAddr;
  uint16_t    macSrcAddr;

  struct PACK
  {
    uint8_t   ackRequest : 1;
    uint8_t   security   : 1;
    uint8_t   linkLocal  : 1;
    uint8_t   multicast  : 1;
    uint8_t   reserved   : 4;
  }           nwkFcf;
  uint8_t     nwkSeq;
  uint16_t    nwkSrcAddr;
  uint16_t    nwkDstAddr;
  struct
  {
    uint8_t   nwkSrcEndpoint : 4;
    uint8_t   nwkDstEndpoint : 4;
  };
} NwkFrameHeader_t;

所以这个结构实际的字节数是17字节,因为是2字节对齐,所以必须完整到2的整数倍,最后结构的大小是18字节。
回复

使用道具 举报

8

主题

36

回帖

60

积分

初级会员

积分
60
 楼主| 发表于 2016-7-14 11:07:39 | 显示全部楼层

回 eric2013 的帖子

eric2013:结构体有字节对齐问题,如果你希望是你定义的几个字节,sizeof就是多个字节大小,可以改成:

__packed typedef struct  ,加上关键字__packed (2016-07-11 09:24) 
加上关键字__packed后没有错了,可以对上了,确实是对齐的问题。上位机用V6板,下位机用的是stm8,通信传输时,堆栈有大小端问题,需要对换高低位数据,现在通信正常,非常感谢。
回复

使用道具 举报

8

主题

36

回帖

60

积分

初级会员

积分
60
 楼主| 发表于 2016-7-14 11:09:33 | 显示全部楼层

回 caicaptain2 的帖子

caicaptain2:你这个定义晦涩难懂,似乎在计算机考试啊。。。。

建议code还是简单明了好。 (2016-07-11 09:37) 
不是,这个是个协议栈。
回复

使用道具 举报

27

主题

82

回帖

163

积分

初级会员

积分
163
发表于 2016-7-15 09:08:43 | 显示全部楼层

回 eric2013 的帖子

eric2013:结构体有字节对齐问题,如果你希望是你定义的几个字节,sizeof就是多个字节大小,可以改成:

__packed typedef struct  ,加上关键字__packed (2016-07-11 09:24) 
[s:151]
回复

使用道具 举报

336

主题

2045

回帖

3058

积分

版主

Rank: 7Rank: 7Rank: 7

积分
3058
发表于 2016-7-15 13:32:26 | 显示全部楼层
在ARM平台的编译器中,没有提供象“#pragma pack”这么丰富的带参数对齐指令,只有一个关键字“__packed”。

__packed 限定符将所有有效类型的对齐边界设置为 1,如果一个结构没有这个限定符,默认向表数能力最强的那个数据类型对齐。



typedef __packed struct
{
    double dValue1;
    char   u8Value2;
    int    u32Value3;
} ASampleStructor;



上例中,size值为13,说明1字节对齐后,该结构总长为13字节。去掉__packed对齐后,为16字节。
回复

使用道具 举报

614

主题

3068

回帖

4930

积分

至尊会员

积分
4930
发表于 2016-7-15 16:19:58 | 显示全部楼层

回 365497604 的帖子

365497604:加上关键字__packed后没有错了,可以对上了,确实是对齐的问题。上位机用V6板,下位机用的是stm8,通信传输时,堆栈有大小端问题,需要对换高低位数据,现在通信正常,非常感谢。 (2016-07-14 11:07)
你这个堆栈大小端是如何处理的 ??
回复

使用道具 举报

8

主题

36

回帖

60

积分

初级会员

积分
60
 楼主| 发表于 2016-7-26 16:03:59 | 显示全部楼层

回 hpdell 的帖子

hpdell:你这个堆栈大小端是如何处理的 ?? (2016-07-15 16:19) 
我是直接用一个函数把数据对换过来。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-6-3 05:31 , Processed in 0.281822 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表