记录#pragma pack()的问题

原创 2014年01月28日 17:56:59
在Cortex M0平台上做开发的时候,遇到一个纠结了两三天的问题。
代码添加了PWM马达控制后,继续做USB复合设备。在做好USB复合设备,发现原来的PWM马达控制不起作用了,首先对比了模块的寄存器设置,完全一致,然后对比代码,除了USB部分,
没有任何差别,接着尝试对比了bin档和map文件,发现二者最大的区别在于
一个调用了uread.o中的__eabi_uread4函数和uwrite4.o的__eabi_uwrite4函数;
而另外一个没有调用这两个函数。
最后通过仔细对比,将问题锁定在如下定义:
#pragma pack(1)
#pragma pack()
有这个定义,代码正常;而没有这个定义,代码就出现问题。
经过自己查看发现,在FileSystem.h头文件中有#pragma pack(1)的定义,然后就出问题了。
在ARM官网上查到#pragma pack(n)的说明如下:
#pragma pack(n)
This pragma aligns members of a structure to the minimum of n and their natural alignment. Packed objects are read and written using unaligned accesses.
Show/hideSyntax
#pragma pack(n)
Where:
n
is the alignment in bytes, valid alignment values being 1, 2, 4 and 8.
Show/hideDefault
The default is #pragma pack(8).
Show/hideExample
This example demonstrates how pack(2) aligns integer variable b to a 2-byte boundary.
typedef struct

    char a;
    int b;
} S;


#pragma pack(2)


typedef struct

    char a;
    int b;
} SP;


S var = { 0x11, 0x44444444 };
SP pvar = { 0x11, 0x44444444 };
The layout of S is as shown in Figure 1, while the layout of SP is as shown in Figure 2. In Figure 2, x denotes one byte of padding.
Figure 1. Nonpacked structure S


Figure 2. Packed structure SP





由此可以看出packet的压缩方式,和对字节对齐的影响。


而在另外一份ARM的文档上查到下面的信息:
These functions read and write 4-byte and 8-byte values at arbitrarily aligned addresses. An unaligned 2-byte 
value can always be read or written more efficiently using inline code. 
int __aeabi_uread4(void *address); 
int __aeabi_uwrite4(int value, void *address); 


推测是在FileSystem.h中的#pragma pack(1)之后,对齐出现问题,导致数据访问出错。
去掉该定义,就以4字节或者8字节对齐,就恢复正常了。

相关文章推荐

pragma pack(非常有用的字节对齐用法说明)

http://hi.baidu.com/zhanghuikl/blog/item/124ea7998108a9006e068c19.html 强调一点:#pragma pack(4)typedef s...

#pragma pack(push,1)与#pragma pack(1)的区别

这是给编译器用的参数设置,有关结构体字节对齐方式设置, #pragma pack是指定数据在内存中的对齐方式。 #pragma pack (n)             作用:C编译器将按照n个...

#pragma pack()用法详解

1.什么是对齐?为什么要对齐? 现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定变量的时候经常在特定的内存地址访问,这就需要各...

#pragma pack(1) 的意义是什么

设置结构体的边界对齐为1个字节,也就是所有数据在内存中是连续存储的。 比如你在C语言中定义下面这样的结构体: struct s { char ch; int i; }; 然后在主函数中写一句:p...

#pragma pack(push,1)与#pragma pack(1)的区别

这是给编译器用的参数设置,有关结构体字节对齐方式设置, #pragma pack是指定数据在内存中的对齐方式。 #pragma pack (n)             作用:C编译器将按照n个字节...

#pragma pack(push,1)与#pragma pack(1)的区别

这是给编译器用的参数设置,有关结构体字节对齐方式设置, #pragma pack是指定数据在内存中的对齐方式。 #pragma pack (n)             作用:C编译器将按照n个字节...

结构对齐--__packed与#pragma pack

Arm结构体gcc内存边界对齐问题  这段时间移植公司的linux i386程序到Arm linux平台,本以为是件工作量很小的事情,以为只要改几个驱动程序就OK了,没想到在应用程序这一块卡了很...

#pragma pack(1) and #pragma pack(push,1)是什么意思

(1) #pragma pack(1)     作用:调整结构体的边界对齐,让其以一个字节对齐;#pragma pack(1) 使结构体按1字节方式对齐例如:struct sample{char a;...
  • sptoor
  • sptoor
  • 2010年06月17日 16:10
  • 1917

#pragma pack(push,1) & #pragma pack(pop)

1 引子      在程序中,有的时候我们定义结构体的时候,要用#pragma pack(push,1) & #pragma pack(pop)类似代码将结构体包起来。一般形式如下:#pragma p...

#Pragma Pack(n)与内存分配

#pragma pack(n) 解释一: 每个特定平台上的编译器都有自己的默认“对齐系数”(也叫对齐模数)。程序员可以通过预编译命令#pragma pack(n),n=1,2,4,8,16来改变这...
  • mylinx
  • mylinx
  • 2011年11月24日 11:50
  • 24888
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:记录#pragma pack()的问题
举报原因:
原因补充:

(最多只允许输入30个字)