在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);