安富萊電子 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 )