[应用相关] 一个STM32(IAR)对齐的警告,不知如何消除?

[复制链接]
11551|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 定义变量时,是在调用变量的地方报警。

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

我不是老师;
aozima 发表于 2014-12-3 19:21 | 显示全部楼层
不建议这样定义结构体,建议做手动对齐。
可以的话,可以调整前后位置,有必要的话,对不足的部分做填充。
styleno1 发表于 2014-12-3 20:17 | 显示全部楼层
数据结构不评论,从警告来看,取不对齐的地址报警告是正常的
 楼主| bear1 发表于 2014-12-3 20:29 来自手机 | 显示全部楼层
可是我已经设置1字节对齐了啊。
#pragma pack(1)
 楼主| bear1 发表于 2014-12-4 09:03 | 显示全部楼层

大家请看图:

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

iar 数据对齐.jpg

大家请看图,使用变量msg的这2个地方都有警告。
 楼主| bear1 发表于 2014-12-4 09:22 | 显示全部楼层
styleno1 发表于 2014-12-3 20:17
数据结构不评论,从警告来看,取不对齐的地址报警告是正常的

那这个警告可以忽略吗?
kseeker 发表于 2014-12-4 10:11 | 显示全部楼层
查查iar带的帮助手册吧。关于#pragma 的部分也许有关闭警报的功能。
sjnh 发表于 2014-12-4 10:22 | 显示全部楼层
结构体定义采用了字节对齐,这两个数据都不是2字节对齐的;
uint16   screen_id;  //产生消息的画面ID
uint16   control_id;  //产生消息的控件ID

但ARM的uint16访问是2字节对齐的,所以47这条语句访问screen_id不会得到正确的数据;
不按标准对齐,可能接收数据方便,但访问就要费点时间、手段;
wlq_9 发表于 2014-12-4 11:02 | 显示全部楼层
#pragma pack(1)
struct xxxx{
};
#pragma pack()
用不着push,pop,那是MFC里的事情。
对齐以后,访问内部成员用指针要小心了。
比如某uint16成员在某奇地址上,用uint16指针访问,后果可以猜到的。
 楼主| bear1 发表于 2014-12-4 21:40 来自手机 | 显示全部楼层
wlq_9 发表于 2014-12-4 11:02
#pragma pack(1)
struct xxxx{
};

还是不大懂,会有什么样的后果?
 楼主| bear1 发表于 2014-12-8 08:53 来自手机 | 显示全部楼层
学习 ,顶
匿名  发表于 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;
 楼主| bear1 发表于 2014-12-10 09:08 | 显示全部楼层
wlq_9 发表于 2014-12-4 11:02
#pragma pack(1)
struct xxxx{
};

能否具体讲讲?
谢谢。
 楼主| bear1 发表于 2014-12-17 09:29 | 显示全部楼层
大侠们,这个警告可以忽略吗?
暂时没发现什么问题。
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;


//YZC 发表于 2014-12-25 14:42 | 显示全部楼层
因为你是字节对齐,三个8位变量后面直接16位变量,明显这样对不齐,解决方法楼上已给出,或者试试双字节、四字节对齐
gaobc 发表于 2014-12-25 14:54 | 显示全部楼层
同意18楼的,不要还在8位机空间里,现在M3比arm7tdmi好多了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

151

主题

970

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部