打印
[应用相关]

一个STM32(IAR)对齐的警告,不知如何消除?

[复制链接]
10806|21
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
bear1|  楼主 | 2014-12-3 17:28 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

#pragma pack(push)
#pragma pack(1)        //按字节对齐
typedef struct
{
    uint8    cmd_head;  //帧头

    uint8    cmd_type;  //命令类型(UPDATE_CONTROL)
    uint8    ctrl_msg;   //CtrlMsgType-指示消息的类型
    uint16   screen_id;  //产生消息的画面ID
    uint16   control_id;  //产生消息的控件ID
    uint8    control_type; //控件类型

    uint8    param[256];//可变长度参数,最多256个字节

    uint8  cmd_tail[4];   //帧尾
} CTRL_MSG,*PCTRL_MSG;
#pragma pack(pop)

Warning[Pa039]: use of address of unaligned structure member E:\a_sw\stm32_sw_xx\t106\user\b01_hmi_06.c 47
沙发
mmuuss586| | 2014-12-3 17:50 | 只看该作者
uint8    param[256];//可变长度参数,最多256个字节
应该是这句报警吧?
是的话想办法改成其它方式;

使用特权

评论回复
板凳
bear1|  楼主 | 2014-12-3 17:57 | 只看该作者
mmuuss586 发表于 2014-12-3 17:50
uint8    param[256];//可变长度参数,最多256个字节
应该是这句报警吧?
是的话想办法改成其它方式; ...

老师,不是。
用CTRL_MSG 定义变量时,是在调用变量的地方报警。

使用特权

评论回复
地板
mmuuss586| | 2014-12-3 18:30 | 只看该作者
bear1 发表于 2014-12-3 17:57
老师,不是。
用CTRL_MSG 定义变量时,是在调用变量的地方报警。

换下这个定义的变量名字;

我不是老师;

使用特权

评论回复
5
aozima| | 2014-12-3 19:21 | 只看该作者
不建议这样定义结构体,建议做手动对齐。
可以的话,可以调整前后位置,有必要的话,对不足的部分做填充。

使用特权

评论回复
6
styleno1| | 2014-12-3 20:17 | 只看该作者
数据结构不评论,从警告来看,取不对齐的地址报警告是正常的

使用特权

评论回复
7
bear1|  楼主 | 2014-12-3 20:29 | 只看该作者
可是我已经设置1字节对齐了啊。
#pragma pack(1)

使用特权

评论回复
8
bear1|  楼主 | 2014-12-4 09:03 | 只看该作者

大家请看图:

本帖最后由 bear1 于 2014-12-4 09:08 编辑



大家请看图,使用变量msg的这2个地方都有警告。

使用特权

评论回复
9
bear1|  楼主 | 2014-12-4 09:22 | 只看该作者
styleno1 发表于 2014-12-3 20:17
数据结构不评论,从警告来看,取不对齐的地址报警告是正常的

那这个警告可以忽略吗?

使用特权

评论回复
10
kseeker| | 2014-12-4 10:11 | 只看该作者
查查iar带的帮助手册吧。关于#pragma 的部分也许有关闭警报的功能。

使用特权

评论回复
11
sjnh| | 2014-12-4 10:22 | 只看该作者
结构体定义采用了字节对齐,这两个数据都不是2字节对齐的;
uint16   screen_id;  //产生消息的画面ID
uint16   control_id;  //产生消息的控件ID

但ARM的uint16访问是2字节对齐的,所以47这条语句访问screen_id不会得到正确的数据;
不按标准对齐,可能接收数据方便,但访问就要费点时间、手段;

使用特权

评论回复
12
wlq_9| | 2014-12-4 11:02 | 只看该作者
#pragma pack(1)
struct xxxx{
};
#pragma pack()
用不着push,pop,那是MFC里的事情。
对齐以后,访问内部成员用指针要小心了。
比如某uint16成员在某奇地址上,用uint16指针访问,后果可以猜到的。

使用特权

评论回复
13
bear1|  楼主 | 2014-12-4 21:40 | 只看该作者
wlq_9 发表于 2014-12-4 11:02
#pragma pack(1)
struct xxxx{
};

还是不大懂,会有什么样的后果?

使用特权

评论回复
14
bear1|  楼主 | 2014-12-8 08:53 | 只看该作者
学习 ,顶

使用特权

评论回复
15
匿名  2014-12-10 01:12
如果是用keil的话,可以按菜单上的debug进入调试模式,然后可以看到左边多了一个窗口,里面会显示当前各个寄存器、堆栈、PC指针的值,其中有一个项是sec,就是表示程序运行时间的。
想知道一条指令的执行时间,可以把PC指针指向这条指令,然后在下一条指令处设置断点,先按“reset”清零一下sec的值,再按“RUN”运行程序,从sec处就可以知道这条指令的运行时间了。请查看EWARM_CompilerReference.pdf试试这样?#pragma data_alignment=2u8    xBu[10]; struct {   u16  xx;   u16  Park[4];} Info;

使用特权

评论回复
16
bear1|  楼主 | 2014-12-10 09:08 | 只看该作者
wlq_9 发表于 2014-12-4 11:02
#pragma pack(1)
struct xxxx{
};

能否具体讲讲?
谢谢。

使用特权

评论回复
17
bear1|  楼主 | 2014-12-17 09:29 | 只看该作者
大侠们,这个警告可以忽略吗?
暂时没发现什么问题。

使用特权

评论回复
18
gotofly21| | 2014-12-25 10:19 | 只看该作者
typedef struct
{
     uint8    cmd_head;  //帧头

    uint8    cmd_type;  //命令类型(UPDATE_CONTROL)
     uint8    ctrl_msg;   //CtrlMsgType-指示消息的类型
uint8          baoliu8;
   

    uint16   screen_id;  //产生消息的画面ID
     uint16   control_id;  //产生消息的控件ID
     uint8    control_type; //控件类型

    uint8    param[256];//可变长度参数,最多256个字节

    uint8  cmd_tail[4];   //帧尾
} CTRL_MSG,*PCTRL_MSG;

结构体最好还是自己对齐,还省空间,方法就是让16位数据在偶数位上,32位在4倍数为上,不够就凑
当然你这个可以把   uint8    control_type; //控件类型方前面去
typedef struct
{
     uint8    cmd_head;  //帧头

    uint8    cmd_type;  //命令类型(UPDATE_CONTROL)
     uint8    ctrl_msg;   //CtrlMsgType-指示消息的类型
     uint8    control_type; //控件类型
   

    uint16   screen_id;  //产生消息的画面ID
     uint16   control_id;  //产生消息的控件ID


    uint8    param[256];//可变长度参数,最多256个字节

    uint8  cmd_tail[4];   //帧尾
} CTRL_MSG,*PCTRL_MSG;


使用特权

评论回复
19
//YZC| | 2014-12-25 14:42 | 只看该作者
因为你是字节对齐,三个8位变量后面直接16位变量,明显这样对不齐,解决方法楼上已给出,或者试试双字节、四字节对齐

使用特权

评论回复
20
gaobc| | 2014-12-25 14:54 | 只看该作者
同意18楼的,不要还在8位机空间里,现在M3比arm7tdmi好多了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

151

主题

964

帖子

1

粉丝