本文重點介紹如果使用函數OSTaskStkChk()函數來檢查UCOSII系統下各任務堆棧的使用情況。
1、簡單介紹一下OSTaskStkChk()函數參數和返回值:
INT8U OSTaskStkChk(INT8U prio, OS_STK_DATA *p_stk_data)
參數prio : 被檢測任務的優先級,也就是唯一標識被檢任務的ID。
參數*p_stk_data:指向OS_STK_DATA 結構體的一個變量指針。
OS_STK_DATA 結構體如下:
typedef struct os_stk_data {
INT32U OSFree; /* Number of free entries on the stack */
INT32U OSUsed; /* Number of entries used on the stack */
} OS_STK_DATA;
返回值:0,表示函數返回成功,即:OS_ERR_NONE
異常返回值如下:
OS_ERR_PRIO_INVALID :被檢測任務的優先級優先級設置錯誤,可能比最高優先級都高了。要小於最高優先級並大於最低優先級,同時不要和自己檢測任務的優先級相同
OS_ERR_TASK_NOT_EXIST :你要檢測的任務沒有被建立或者被分配到一個互斥PIP
OS_ERR_TASK_OPT:被檢任務在建立的時候OSTaskCreateExt函數最後一個參數沒有設置爲OS_TASK_OPT_STK_CHK
OS_ERR_PDATA_NULL:指針'p_stk_data可能爲空了(if 'p_stk_data' is a NULL pointer)
2、查看任務堆棧使用情況步驟:
(1)創建一個靜態函數CheckStackTask,用於任務調用。
這個數的作用有兩方面:
一方面,它調用OSTaskStkChk()函數用於檢測UCOSII系統中任務堆棧使用情況。
另一方面,在檢測任務堆棧時這個函數它本身做爲一個任務線程,在系統中運行。(下一步將說到它被任務創建函數OSTaskCreateExt()調用。)
示例:
static void CheckStackTask(void* pArg)
{
u8 err1 =0,err2=0,err3=0,err4=0,err5=0;
while(1)
{
err1=OSTaskStkChk(TASK_PRI_1,&OSTKDataSize1);
OSTimeDly(100);
err2=OSTaskStkChk(TASK_PRI_2,&OSTKDataSize2);
OSTimeDly(100);
err3=OSTaskStkChk(TASK_PRI_3,&OSTKDataSize3);
OSTimeDly(100);
{
printf("Task1 FreeStack:%d ,UsedStack:%d ,err:%d\n",OSTKDataSize1.OSFree,OSTKDataSize1.OSUsed,err1);
printf("Task2 FreeStack:%d ,UsedStack:%d ,err:%d\n",OSTKDataSize2.OSFree,OSTKDataSize2.OSUsed,err2);
printf("Task3 FreeStack:%d ,UsedStack:%d ,err:%d\n",OSTKDataSize3.OSFree,OSTKDataSize3.OSUsed,err3);
printf("*******\n\n");
}
}
}
(2)要用創建任務函數OSTaskCreateExt()創建一個任務,用於調用上一步的CheckStackTask()函數。
示例:
#define TASK_STK_SIZE_CHKTASK 64 //(定義任務堆棧,任務堆棧64就夠大了)
#define TASK_PRI_CHKTASK 51 //(定義任務優先級,檢測任務的優先級,要小於其他被檢任務)
OSTaskCreateExt(CheckStackTask, NULL, \
&gaTaskCheckTask[TASK_STK_SIZE_CHKTASK-1], TASK_PRI_CHKTASK, TASK_PRI_CHKTASK, \
gaTaskCheckTask, TASK_STK_SIZE_CHKTASK, NULL, OS_TASK_OPT_STK_CLR);
(3)檢查被檢測任務在創建時的最後一項參數,是不是添加了OS_TASK_OPT_STK_CHK項。
示例:
OSTaskCreateExt(TaskTmp1, NULL, \
&gaTaskStkTmp[TASK_STK_SIZE-1], TASK_PRI_1, TASK_PRI_1, \
gaTaskStkTmp, TASK_STK_SIZE_1, NULL, OS_TASK_OPT_STK_CLR|OS_TASK_OPT_STK_CHK);
(4)檢查宏OS_TASK_STAT_STK_CHK_EN是否爲1,如果不是修改爲1。
示例:
#define OS_TASK_STAT_STK_CHK_EN 1u /* Check task stacks from statistic task
(5)最後一點建議:
1、將被測任務經歷最壞的堆棧使用狀態,測出來的使用率纔可靠
2、堆棧使用率最好在%50~%80之間,太小浪費空間,太大不安全
3、最好在工程中單獨建立一個優先級較低延時較長的任務來測試其它任務的堆棧使用情況,不用時可以掛起該任務