Keil MDK5 環境下 GD32F303 在 FreeRTOS 任務中使用浮點運算報 HardFault 異常的問題

2022-01-06 14:00:03

1. 問題描述

1. 1 環境

類別版本
系統WIN10
KeilKeil MDK 5.15.0
開發板星空派GD32F303開發板
GD32F30x 韌體庫V2.1.2
GD32F30x Keil 5 支援包V2.1.0
FreeRTOSV10.4.3-LTS-Patch-2

1. 2 問題

繼上一篇博文《GD32F303 移植 FreeRTOS》之後,以為可以愉快的玩 FreeRTOS 了,沒想到接下來遇到了一個大坑。

博主在任務中使用了浮點型運算,測試任務如下:

static void test_task(void *para)
{
    float f = 0.3f;
    while(1)
    {
        LOGD("task: %s, freestack: %d, proi: %d\n", OS_TaskGetName(NULL), OS_TaskGetFreeStackSpace(NULL), OS_TaskGetPriority(NULL));

        f *= 3.0f;

        OS_MsDelay(1000);
    }
}

編譯下載執行串列埠輸出如下資訊:
在這裡插入圖片描述
只要執行了浮點型運算,就進入了 HardFault 異常中斷。

2. 探索過程

2.1 HardFault 異常方向排查問題,分析出現的問題

出現 HardFault 硬體錯誤的原因主要有兩個方面:

  • 記憶體溢位或者存取越界
  • 堆疊溢位

但是從設定角度而言,任務棧空間是足夠的,就算加了浮點運算,需要的空間大,我建立任務直接加大棧空間到 2048 問題依舊存在,根據 JLINK 模擬偵錯也是一頭霧水,無果。

修改啟動檔案 startup_gd32f30x_hd.s 的堆疊空間,增加堆疊空間問題依舊。

參考博文《STM32硬體錯誤HardFault_Handler的處理方法》

2.2 浮點運算方向排查問題,檢查是否啟用了 FPU 功能

在這裡插入圖片描述
如上圖增加了 __FPU_PRESENT 宏定義,啟用 FPU 後,編譯執行仍舊如此,並同時嘗試了裸機使用浮點型運算是沒有問題的,證明問題還是出在 FreeRTOS 核心相關上。

2.3 位元組對齊問題

參考博文

但其實檢視過 startup_gd32f30x_hd.s 啟動檔案,已經設定的是 8 直接對齊
在這裡插入圖片描述
其實參考博文的參考意義不大,博主的情況與參考博文的情況不一致,但也不失為一種解決思路。

3. 解決方法

探索了幾天,嘗試了多種辦法,奈何博主的知識貯備不夠,無法更深層次去探索問題的根源。

無意之間瀏覽到博文《STM32 Printf 列印浮點數亂碼的問題》
該博主提到修改編譯優先順序設定成預設的解決思路,即:
將Options -> C/C++ -> Optimization 設定為 default。
在這裡插入圖片描述
修改成預設後,執行程式,問題便解決了。但其實不知根本。
其實只要不是 Level 0 等級都是可以的。
檢視了編譯優化相關博文,還是未果。相關博文如下:

4. 總結

問題困擾幾天,雖然解決,但不知根本。後續有時間再來一探究竟!