FreeRTOS操作系統例程:任務棧溢出檢測

安富萊電子 www.armfly.com?

安富萊_STM32-V5開發板_FreeRTOS教程(V1.0)


實驗目的:

*? ? ? ? ? ? ? ? 1. 學習FreeRTOS的任務棧溢出檢測方法一(模擬棧溢出)。

*? ? ? ? ? ? ? ? 2. FreeRTOS的任務棧溢出檢測方法一說明:

*? ? ? ? ? ? ? ? ? a. FreeRTOSConfig.h文件中配置宏定義:

*? ? ? ? ? ? ? ? ? ? ? #define? configCHECK_FOR_STACK_OVERFLOW? 1

*? ? ? ? ? ? ? ? ? b. 在任務切換時檢測任務棧指針是否過界了,如果過界了,在任務切換的時候會觸發棧溢出鉤子函數。

*? ? ? ? ? ? ? ? ? ? ? void vApplicationStackOverflowHook( TaskHandle_t xTask,

*? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? signed char *pcTaskName );

*? ? ? ? ? ? ? ? ? ? ? 用戶可以在鉤子函數里面做一些處理。本實驗是在鉤子函數中打印出現棧溢出的任務。

*? ? ? ? ? ? ? ? ? c. 這種方法不能保證所有的棧溢出都能檢測到。比如任務在執行的過程中發送過棧溢出。任務切換前

*? ? ? ? ? ? ? ? ? ? ? 棧指針又恢復到了正常水平,這種情況在任務切換的時候是檢測不到的。又比如任務棧溢出后,把

*? ? ? ? ? ? ? ? ? ? ? 這部分棧區的數據修改了,這部分棧區的數據不重要或者暫時沒有用到還好,如果是重要數據被修

*? ? ? ? ? ? ? ? ? ? ? 改將直接導致系統進入硬件異常。這種情況下,棧溢出檢測功能也是檢測不到的。

*? ? ? ? ? ? ? ? ? d. 本實驗就是簡單的在任務vTaskUserIF中申請過大的??臻g,模擬出一種棧溢出的情況,溢出后觸

*? ? ? ? ? ? ? ? ? ? ? 發鉤子函數,因為我們將溢出部分的數據修改了,進而造成進入硬件異常。

?#define? configCHECK_FOR_STACK_OVERFLOW? 1

/*

*********************************************************************************************************

* 函 數 名: StackOverflowTest

* 功能說明: 任務棧溢出測試

* 形? ? 參: 無

* 返 回 值: 無

*********************************************************************************************************

*/

static void StackOverflowTest(void)

{

int16_t i;

uint8_t buf[2048];

(void)buf; /* 防止警告 */

/*

? 1. 為了能夠模擬任務棧溢出,并觸發任務棧溢出函數,這里強烈建議使用數組的時候逆著賦值。

? ? 因為對于M3和M4內核的MCU,堆棧生長方向是向下生長的滿棧。即高地址是buf[2047], 低地址

? ? 是buf[0]。如果任務棧溢出了,也是從高地址buf[2047]到buf[0]的某個地址開始溢出。

? ? ? ? 因此,如果用戶直接修改的是buf[0]開始的數據且這些溢出部分的數據比較重要,會直接導致

? ? 進入到硬件異常。

? 2. 棧溢出檢測是在任務切換的時候執行的,我們這里加個延遲函數,防止修改了重要的數據導致直接

? ? 進入硬件異常。

? 3. 任務vTaskTaskUserIF的??臻g大小是2048字節,在此任務的入口已經申請了棧空間大小

------uint8_t ucKeyCode;

? ? ------uint8_t pcWriteBuffer[500];

? ? 這里再申請如下這么大的棧空間

? ? -------int16_t i;

-------uint8_t buf[2048];

? ? 必定溢出。

*/

for(i = 2047; i >= 0; i--)

{

buf[i] = 0x55;

vTaskDelay(1);

}

}


/*

*********************************************************************************************************

* 函 數 名: vApplicationStackOverflowHook

* 功能說明: 棧溢出的鉤子函數

* 形? ? 參: xTask? ? ? ? 任務句柄

*? ? ? ? ? ? pcTaskName? 任務名

* 返 回 值: 無

*********************************************************************************************************

*/

void vApplicationStackOverflowHook( TaskHandle_t xTask, signed char *pcTaskName )

{

printf("任務:%s 發現棧溢出\r\n", pcTaskName);

}

實驗目的:

*? ? ? ? ? ? ? ? 1. 學習FreeRTOS的任務棧溢出檢測方法二(模擬棧溢出)。

*? ? ? ? ? ? ? ? 2. FreeRTOS的任務棧溢出檢測方法二說明:

*? ? ? ? ? ? ? ? ? a. FreeRTOSConfig.h文件中配置宏定義:

*? ? ? ? ? ? ? ? ? ? ? #define? configCHECK_FOR_STACK_OVERFLOW? 2

*? ? ? ? ? ? ? ? ? b. 在任務切換時檢測任務棧指針是否過界了,如果過界了,在任務切換的時候會觸發棧溢出鉤子函數。

*? ? ? ? ? ? ? ? ? ? ? void vApplicationStackOverflowHook( TaskHandle_t xTask,

*? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? signed char *pcTaskName );

*? ? ? ? ? ? ? ? ? ? ? 用戶可以在鉤子函數里面做一些處理。本實驗是在鉤子函數中打印出現棧溢出的任務。

*? ? ? ? ? ? ? ? ? c. 任務創建的時候將任務棧所有數據初始化為0xa5,任務切換時進行任務棧檢測的時候檢測末尾

*? ? ? ? ? ? ? ? ? ? ? 的16個字節是否都是0xa5,通過這種方式來檢測任務棧是否溢出了。相比方法一,這種方法的速度

*? ? ? ? ? ? ? ? ? ? ? 稍慢些,但是這樣就有效的避免了方法一里面的部分情況。不過依然不能保證所有的棧溢出都能檢測

*? ? ? ? ? ? ? ? ? ? ? 到,比如任務棧末尾的16個字節沒有用到,即沒有被修改,但是任務棧已經溢出了,這種情況是檢

*? ? ? ? ? ? ? ? ? ? ? 測不到的。另外任務棧溢出后,任務棧末尾的16個字節沒有修改,但是溢出部分的棧區的數據修改

*? ? ? ? ? ? ? ? ? ? ? 了,這部分棧區的數據不重要或者暫時沒有用到還好,如果是重要數據被修改將直接導致系統進入硬

*? ? ? ? ? ? ? ? ? ? ? 件異常。這種情況下,棧溢出檢測功能也是檢測不到的。

*? ? ? ? ? ? ? ? ? d. 本實驗就是簡單的在任務vTaskUserIF中申請過大的棧空間,模擬出一種棧溢出的情況,溢出后觸

*? ? ? ? ? ? ? ? ? ? ? 發鉤子函數,因為我們將溢出部分的數據修改了,進而造成進入硬件異常。

#define? configCHECK_FOR_STACK_OVERFLOW? 2

函數內容和上面一樣:

static void StackOverflowTest(void)

void vApplicationStackOverflowHook( TaskHandle_t xTask, signed char *pcTaskName )

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容