2013-07-26 35 views
2

我正在開發一個arm7tdmi目標的應用程序。 我曾經用IAR編譯代碼,但現在我切換到arm-none-eabi-gcc,我有以下問題。 我如何設置默認對齊的變量與arm gcc

typedef struct 
{ 
    uint32 nNumber; 
    uint32 nPara1; 
    uint32 nPara2; 
    uint32 nPara3; 
    uint32 nPara4; 
    uint32 nPara5; 
    uint32 nParax[122]; 
} TTXSpecial_t; 

static uint8 cTelBuf[TTX_TEL_LENGTH]; 

例如當cTelBuf放在@0x4000000A

&(((TTXSpecial_t *)cTelBuf)->nNumber) 

返回相同的地址,到目前爲止,一切都還好。


cTelBuf被填滿,所以 ((TTXSpecial_t *)cTelBuf)->nNumber應該是 0x87654321

內存轉儲顯示:

0x40000000: 00 00 04 00 00 02 0C 00 00 02 21 43 65 87 00 00 
0x40000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 


問題是,每當我讀 (TTXSpecial_t *)cTelBuf)->nNumber值將是 0x2004321。 因此,您可以看到讀取在地址 0x40000008而不是 0x4000000A完成。
我CFLAGS是: -mcpu=arm7tdmi -Os -gdwarf-2 -mthumb-interwork -fomit-frame-pointer -Wall -Wpadded -Wstrict-prototypes -fstrict-aliasing -fverbose-asm -Wa
問題1:如何設置一個默認的數據對齊臂無 - EABI - 海合會
我知道 static uint8 cTelBuf[TTX_TEL_LENGTH] __attribute__((aligned(4)));將修復這種情況下的問題,但我想通常設置對齊。 IAR編譯器如何做到這一點?

問題2:有沒有辦法避免這個問題(一般情況下沒有複製)? 我的意思是:如果我想要TTXSpecial_t結構從cTelBuf+1開始。 一種解決方案可能是將memcpy cTelBuf+1分配給TTXSpecial_t結構,但如何在不分配額外內存的情況下執行此操作?

+0

您可能不會在您的真實代碼中聲明'cTelBuf'。 – auselen

回答

3

你的問題是你有類型,並沒有使用它們。編譯器知道TTXSpecial_t包含需要4個字節對齊的32位值。問題在於你將cTelBuf聲明爲字節數組,其中編譯器只能說該字節訪問不需要對齊。

所以,我建議你聲明你的字節數組爲TTXSpecial_t(並將它轉換爲字節訪問你的uint8),或者將它作爲一個組合數據類型,聲明它爲聯合(即作爲你的TTXSpecial_tunit8數組,覆蓋)。

Afaik在gcc中沒有通用選項來更改變量的默認對齊方式(某些體系結構具有特殊的小型開關,但我沒有提供arm的功能),並且快速瀏覽IAR文檔說, IAR編譯器的行爲方式相同。這意味着他會在4個字節邊界處對齊結構類型的變量,但聲明的字節數組只會對齊1個字節 - 看起來您很幸運,您使用IAR編譯器從未遇到過代碼問題 - 您應該修復儘快它也可能發生。