文章目錄
- 前言
- 問題描述
- 原因分析
- 問題解決
- 總結
前言
在構建編譯工程時,會有一些對應的編譯配置選項,不同的編譯器,會有對應的配置項。本文介紹GHS工程中編譯選項配置不對應導致的異常。
問題描述
在S32K3集成工程中,核1的INP_SWC中使用E2E_P01Protect會導致核1 shutdown
排查原因是在調用Crc_CalculateCRC8函數時掛掉了
屏蔽里面的for循環后,可以跑起來
uint8 Crc_CalculateCRC8(const uint8* Crc_DataPtr, uint32 Crc_Length, uint8 Crc_StartValue8, boolean Crc_IsFirstCall)
{uint32 index;uint8 result = Crc_StartValue8;uint8 crcTemp;if(Crc_DataPtr != NULL_PTR){crcTemp = (Crc_IsFirstCall != FALSE) ? ((uint8)CRC_INITIAL_VALUE8) : (Crc_StartValue8^ CRC_XOR_VALUE8);for (index = 0U; index < Crc_Length; ++index){/* Impact of temporary rest on next crc rest */crcTemp ^= ((uint8)Crc_DataPtr[index]) ;/* Next temporary crc rest */ crcTemp = CRC_8_Tbl[crcTemp]; }result = crcTemp ^ CRC_XOR_VALUE8;}return (result);
}
原因分析
查看輸入的參數,發現length異常
往前找,發現傳入的config參數就不對
實際定義時的參數如下
傳入E2E_P01Protect函數中的參數變成了
可以看到,DataLenth的地址在傳遞前為0x0046D0B4,而在傳遞后變成了0x0046D0B2
導致傳遞的參數亂了
為什么會出現這種情況呢?
有一點可以注意一下,出問題的地方在DataIDMode后面,他不是一個變量定義,而是一個枚舉enum類型
為什么同一個枚舉類型會有兩種數據長度呢?
最終排查發現,由于兩個源文件在不同的gpj配置文件中被編譯,出現異常的文件中的配置文件中定義了–short_enum,開啟了編譯優化
導致參數在傳遞后,DataIDMode只占2個byte,而在未優化的文件中,占4個byte.所以導致了問題
查看ghs bulid手冊:
–short_enum對枚舉使用最小類型
控制枚舉的分配。此選項允許的設置為:
?On(–short_enum) -以盡可能小的類型存儲枚舉。
?Off(–no_short_enum) -[默認]將枚舉存儲為整數
其實在手冊中就已經明確指出了,需要確保所有文件配置一致!
問題解決
搞清楚問題出現的緣由,將兩個文件中的配置統一之后,問題就解決了。
總結
編譯器對應的編譯選項,還是需要花時間好好學習下,不然出問題可能很難排查。