關於微控制器位元組對齊的所導致的硬體錯誤
阿新 • • 發佈:2020-11-06
今天在除錯程式時,對一個結構體指標的成員進行讀取時,莫名其妙的產生了一個硬體錯誤,該指標由一個數組指標強制轉換的,問題很隱晦,開發平臺使用的是MDK5.31,微控制器使用的是 HK32F030相容STM32F030,程式碼相互相容,接下來對問題進行詳細描述,
我的結構體如下:
typedef struct { uint32_t reserve : 8; /*保留*/ uint32_t mode : 2; /*執行模式*/ uint32_t level : 2; /*檔位*/ uint32_t Onoff :2; /*開關*/ uint32_t speed_mode : 2; /*風速模式 不使用,手動和自動*/ uint32_t set_temp : 8; /*設定溫度*/ uint32_t cur_temp : 8; /*當前溫度*/ }AIR_CTL_S;
該結構體佔用四個位元組,沒強制位元組對齊時,預設使用的是4個位元組。
使用方法類似如下:
unsigned char data[4] = {0}; AIR_CTL_S* air_ctl_t = (AIR_CTL_S*)data; //強制指標型別轉換
air_ctl_t->set_temp= 255; //執行這句話 莫名其妙的出現hardfault錯誤
究其原因:
1、因為AIR_CTL_S 結構體是四個位元組對齊,所以AIR_CTL_S 的指標地址必定能被4 整除,如果是編譯器自動分配的,如果是用AIR_CTL_S 定義的變數,不管是全域性的還是全部,編譯器都會分配在被4整除的地址上,所以不必擔心硬體錯誤
2、因為我這裡用的是強制型別指標轉換,存在一定的概率性,也就是說如果陣列data的首地址為4的倍數,那什麼問題都沒有,但除錯發現,data的地址是0x200000BA,不能被4整除,導致在訪問air_ctl_t->set_temp,就莫名其妙的進入硬體錯誤。
解決辦法:
使用#pragma pack(1)
結構體定義
#pragma pack()
強制1個位元組對齊,問題就解決了。