OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2449|回复: 8

STM32F103 结构体指针问题

[复制链接]

4

主题

19

帖子

0

精华

初级会员

Rank: 2

积分
69
金钱
69
注册时间
2013-10-15
在线时间
8 小时
发表于 2019-4-4 16:04:46 | 显示全部楼层 |阅读模式
5金钱
结构体如下:
__packed struct AD9362_TypeDef  //
{
        uint8_t                 id_no;
        //uint8_t                 id_no1;
        uint32_t    data_t[8];               
        bool                          bbdc_track_en;  ////
        bool                          quad_track_en; /////
        uint32_t                bist_tone_level_dB;
        uint32_t                bist_tone_mask;

} ;
单字节对齐,当结构体中间数组是data_t[7];        时运行正常,如下图:
8dui.png
当结构体中间数组是data_t[8];        时运行不正常,函数形参结构体指针自动改变,如下图:
8cuo.png
网上查说字节对齐问题,我改为4字节对齐
__align(4) struct AD9362_TypeDef  //
{
        uint8_t                 id_no;
        //uint8_t                 id_no1;
        uint32_t            data_t[30];               
        bool                          bbdc_track_en;  ////
        bool                          quad_track_en; /////
        uint32_t                bist_tone_level_dB;
        uint32_t                bist_tone_mask;

} ;
中间数组为 data_t[8];时确实没问题,但是数组改为 data_t[30];或者以上时,同样会出现地址改变的情况。
30cuo.png
哪位大神遇到过,求解决办法

最佳答案

查看完整内容[请看2#楼]

__align(4)只保证 id_no的地址可以被4整除, 那data_t[0]的地址呢?是不是等于id_no的地址加1? 这能对齐吗? 你访问data_t[0]能不报错吗? __packed struct AD9362_TypeDef // { uint32_t data_t[8]; uint32_t bist_tone_level_dB; uint32_t bist_tone_mask; bool bbdc_track_en; //// bool ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

3

主题

1907

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4106
金钱
4106
注册时间
2018-8-14
在线时间
696 小时
发表于 2019-4-4 16:04:47 | 显示全部楼层
本帖最后由 edmund1234 于 2019-4-10 15:13 编辑
fuluoce 发表于 2019-4-10 11:58
我使用的是keil编译器,默认是四字节对齐,和我加__align(4)是一样的,问题是4字节对齐了,加大数组还是 ...

__align(4)只保证 id_no的地址可以被4整除, 那data_t[0]的地址呢?是不是等于id_no的地址加1? 这能对齐吗? 你访问data_t[0]能不报错吗?

__packed struct AD9362_TypeDef  //
{
        uint32_t    data_t[8];               
        uint32_t                bist_tone_level_dB;
        uint32_t                bist_tone_mask;
        bool                          bbdc_track_en;  ////
        bool                          quad_track_en; /////
        uint8_t                 id_no;
        //uint8_t                 id_no1;

} ;   这就能对齐了

typedef struct {
u8 A;
u16 B;
} __attribute__((packed)) ABC;加了packed后, 编译器就不会帮你重新定义结构体内的字段

否则, 编译器很可能会帮你把结构体改成
typedef struct {
u16 B;
u8 A;
} ABC; // 因为u16在前面可以解决对齐的问题, 否则你一访问B, 就马上报错

不加packed的问题就在于,如果是,两个CPU通过串口通信, 要把一结构传到另一方, 除非相方的软件是一模一样, 否则你没办法保证编译器的重新安排顺序是一模一样的
发送方B是放前面的, 而接收方B放后面, 你说这能通信么, 所以说要通信的话要加__packed
但加了__packed后, 等于是编译器不会管你的字段对齐的问题, 你必须要自己解决
比如
typedef struct {
u8 A;
u16 B;
u32 C;
}__attribute__((packed)) ABC;
B及C都会有对齐的问题, 自己动手写成

typedef struct {
u32 C;
u16 B;
u8 A;
}__attribute__((packed)) ABC;
这就不会有对齐问题

所以我说, 如果不是传送数据的话就不要用__packed, 编译器会帮你安排到所有字段都对齐


明白?


回复

使用道具 举报

4

主题

56

帖子

0

精华

初级会员

Rank: 2

积分
129
金钱
129
注册时间
2015-3-9
在线时间
9 小时
发表于 2019-4-4 17:05:49 | 显示全部楼层
栈溢出了?
回复

使用道具 举报

3

主题

1907

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4106
金钱
4106
注册时间
2018-8-14
在线时间
696 小时
发表于 2019-4-4 19:41:42 | 显示全部楼层
ARM系统下用struct要特别的注意
如果说, 不汲及远程传送, 不要加__packed, 让编译器给你处理, 反正准确位置在哪儿你就别管了

若是要加__packed, 就是你已告知编译器, 对齐的事我会自己管好的,你别管闲事了
加__packed了你又不管对齐的事, 出问题是必然的啊
回复

使用道具 举报

3

主题

1907

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4106
金钱
4106
注册时间
2018-8-14
在线时间
696 小时
发表于 2019-4-4 19:47:27 | 显示全部楼层
bool你是否定义成uint32_t? 如果是

__packed struct AD9362_TypeDef  //
{
        uint8_t                 id_no;         // <---- 要不把它改为uint32_t, 要不就把它放到结构最后面去
        //uint8_t                 id_no1;
        uint32_t    data_t[8];               
        bool                          bbdc_track_en;  ////
        bool                          quad_track_en; /////
        uint32_t                bist_tone_level_dB;
        uint32_t                bist_tone_mask;

} ;
回复

使用道具 举报

3

主题

1907

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4106
金钱
4106
注册时间
2018-8-14
在线时间
696 小时
发表于 2019-4-4 20:05:47 | 显示全部楼层
还是那一句, 如果不是以此结构体包装数据来传送, 不要加__packed
回复

使用道具 举报

4

主题

19

帖子

0

精华

初级会员

Rank: 2

积分
69
金钱
69
注册时间
2013-10-15
在线时间
8 小时
 楼主| 发表于 2019-4-10 11:58:06 | 显示全部楼层
edmund1234 发表于 2019-4-4 20:05
还是那一句, 如果不是以此结构体包装数据来传送, 不要加__packed

我使用的是keil编译器,默认是四字节对齐,和我加__align(4)是一样的,问题是4字节对齐了,加大数组还是会地址自动增加?

不是太明白远程传送?
回复

使用道具 举报

4

主题

19

帖子

0

精华

初级会员

Rank: 2

积分
69
金钱
69
注册时间
2013-10-15
在线时间
8 小时
 楼主| 发表于 2019-4-10 11:58:53 | 显示全部楼层
edmund1234 发表于 2019-4-4 19:47
bool你是否定义成uint32_t? 如果是

__packed struct AD9362_TypeDef  //

bool定义的是uint8_t  

也就是__packed struct AD9362_TypeDef  //
{
        uint8_t                 id_no;         //
        //uint8_t                 id_no1;
        uint32_t    data_t[8];               
        uint8_t                          bbdc_track_en;  ////
        uint8_t                          quad_track_en; /////
        uint32_t                bist_tone_level_dB;
        uint32_t                bist_tone_mask;

} ;
回复

使用道具 举报

4

主题

19

帖子

0

精华

初级会员

Rank: 2

积分
69
金钱
69
注册时间
2013-10-15
在线时间
8 小时
 楼主| 发表于 2019-4-10 11:59:19 | 显示全部楼层

没有堆栈溢出,增大堆栈也是一样的
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-22 18:28

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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