1. 程式人生 > 實用技巧 >關於微控制器位元組對齊的所導致的硬體錯誤

關於微控制器位元組對齊的所導致的硬體錯誤

今天在除錯程式時,對一個結構體指標的成員進行讀取時,莫名其妙的產生了一個硬體錯誤,該指標由一個數組指標強制轉換的,問題很隱晦,開發平臺使用的是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個位元組對齊,問題就解決了。