记录#pragma pack()的问题

在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()的问题)