吃虧在四位元組對齊
我在寫程式的時候遇到一個問題,費了我半天的時間才找到答案,記錄如下:
我原來一個程式有如下結構:
UCHAR Rx_buf[MAX_BUF];
typedef struct //本結構體保證四位元組對齊
{
UCHAR _station;
UCHAR _command;
…
UINT32 _offset;
} Protocol;
//程式片斷
Protocol *proto;
…
For(i=0; i<sizeof(Protocol); i++)
Tx_buf[i] = Rx_buf[i];
*proto = (Protocol *)Tx_buf;
Make_ack(proto, Rx_buf, Tx_buf);
…
// Make_ack函數實現
Make_ack(proto, Rx_buf, Tx_buf)
{
…
If(proto…)
{
F_open(…);
F_lseek(&file, proto->offset); //此處出錯
F_read(…);
F_close(…);
}
…
}
就這麼一段程式,從邏輯上看任何問題沒有,但是就是讀取不到檔案,把我氣得呀!還以為是檔案系統出錯了,就開始找檔案系統的代碼,結果發現沒有問題。還作了測試。
然後我就懷疑是輸入參數錯了,掛wpe截獲發送的資料,發現發送的資料完全正確,寫測試代碼發現接受的資料完全正確。
於是乎,掛模擬器,並用串口輸出調試資訊。
代碼修改如下:
// Make_ack函數實現
Make_ack(proto, Rx_buf, Tx_buf)
{
…
If(proto…)
{
f_open(…);
f_lseek(&file, proto->offset); //此處出錯
f_read(…);
f_close(…);
}
#ifdef OUTPUT_DEBUG_STRING
SerialPrintf(“proto->offset:%d”, proto->offset);
#endif
…
}
結果調試運行結果:在調試到proto->offset時顯示的資料為0,是我預期的結果,但是串口列印的資料確是:12636928。我一看傻眼了,還有這麼邪門。然後我就調試到f_lseek函數內部,發現參數傳進來就給我改了地址了。呵呵,終於找到原因了,可是他娘的是怎麼回事呢?然後我就琢磨著可能是四位元組沒有對齊,於是乎就開啟了memory,發現果然Tx_buf的起始位置是四位元組的中間,找編譯器的設定也沒找到,只要做了如下修改*proto = (Protocol *)Tx_buf;修改為*proto = (Protocol *)Rx_buf;反正資料一樣。
問題解決,搞定。但是還是很不爽。