2016-05-25 50 views
2

長篇小說我使用IAR EWARM編譯器在C中使用了這個。IAR編譯器中的指針

uint8_t packet[2048]; 
uint32_t* src = (uint32_t*)&packet[9]; 
uint32_t var = *src++; 

最後一行導致總線故障。

uint8_t packet[2048]; 
uint32_t* src = (uint32_t*)&packet[9]; 
uint32_t var = 0xFE; 
*src++; 

現在沒有總線故障。我可以在調試器的src中看到我希望它指向的數據。按預期增加它的工作,但嘗試讀取它會導致總線故障。

任何幫助?

+0

這是一個隨機的信息塊。不僅不足以回答,甚至不理解問題。 –

+0

對我來說似乎很清楚。你有我的函數的原型,你可以看到我在傳入指針時如何引用指針。你有實際的函數調用。而且你在函數中有錯誤發生的實際行以及實際錯誤。 – lusher00

+0

只是供參考 - 有3個近距離投票目前不清楚。 –

回答

4

這可能是您的MCU需要讀取32位整數以對齊到32位。

&packet[9]肯定不是32位對齊,這就是爲什麼你會得到一個錯誤。

+0

是的,就是這樣。我忘了這一切。謝謝。 – lusher00

4

&packet[9]可能未正確對齊uint32_t。看到ARM CPU上的「總線錯誤」通常是對齊錯誤的標誌。 See here有關對齊的解釋。

在第二個示例中,它可能會通過優化*操作來避免總線故障,因爲您從不使用結果。

請注意,即使您修復此問題,代碼仍會通過違反嚴格的別名規則而導致未定義的行爲。 (uint8_t可能不會被別名爲uint32_t)。一些編譯器現在看起來可以「正常工作」,但代碼將來可能會隨時中斷。

代碼的安全等效是:

uint8_t *src = &packet[9]; 
uint32_t var; 
memcpy(&var, src, sizeof var); 
src += sizeof var; 

注意,如果源數據被指定爲具有整數特定字節順序(例如,你從網絡流得到它,而不是數據你那麼你會希望使用一種方法來讀取獨立於uint32_t表示的數據。 (換句話說,「排序」)。