欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 焦点 > uC/OSII学习笔记(二)任务的堆栈检验

uC/OSII学习笔记(二)任务的堆栈检验

2025/1/14 10:36:51 来源:https://blog.csdn.net/weixin_45024820/article/details/144238308  浏览:    关键词:uC/OSII学习笔记(二)任务的堆栈检验

加入OSTaskCreateExt()创建拓展任务函数的使用。
加入OSTaskStkChk()堆栈检验函数的使用。

堆栈检验函数可检查任务堆栈的使用字节数量和空闲字节数量。
具体使用方法如下:
1.创建拓展任务OSTaskCreateExt()用于堆栈检验,堆栈检验必须用拓展任务OSTaskCreateExt()。如,

#define task1_PRIO      50				//这个是任务优先级,任务优先级的编号,1-63,且不能重复,它代表了任务的唯一性
#define task1_STK_NUM   40  			//指任务的OS_STK的数量
OS_STK task1_STK[task1_STK_NUM];		//有task1_STK_NUM 个4个字节的空间,40*4
void task1(void* p_arg); 				//任务函数#define task2_PRIO      60
#define task2_STK_NUM   40 
OS_STK task2_STK[task2_STK_NUM];
void task2(void* p_arg);OSTaskCreateExt(task1, NULL, \&task1_STK[task1_STK_NUM - 1], task1_PRIO, task1_PRIO, \task1_STK, task1_STK_NUM, NULL, OS_TASK_OPT_STK_CHK| OS_TASK_OPT_STK_CLR);
OSTaskCreateExt(task2, NULL, \&task2_STK[task2_STK_NUM - 1], task2_PRIO, task2_PRIO, \task2_STK, task2_STK_NUM, NULL, OS_TASK_OPT_STK_CHK| OS_TASK_OPT_STK_CLR);void task1 (void *p_arg)
{INT8U err1 = OSTaskStkChk(task1_PRIO,&StackBytes1);GUI_Printf(0,40,GUI_WHITE,GUI_BLACK|GUI_FONT_16,"Task1 FreeStack:%d",StackBytes1.OSFree);GUI_Printf(0,60,GUI_WHITE,GUI_BLACK|GUI_FONT_16,"Task1 UsedStack:%d",StackBytes1.OSUsed);GUI_Printf(0,80,GUI_WHITE,GUI_BLACK|GUI_FONT_16,"Task1 err:%d",err1);while(1){GUI_Printf(0,20,GUI_WHITE,GUI_BLACK|GUI_FONT_16,"任务1");
//		GUI_Printf(0,40,GUI_WHITE,GUI_BLACK|GUI_FONT_16,"Task1 FreeStack:%d",StackBytes1.OSFree);
//		GUI_Printf(0,60,GUI_WHITE,GUI_BLACK|GUI_FONT_16,"Task1 UsedStack:%d",StackBytes1.OSUsed);
//		GUI_Printf(0,80,GUI_WHITE,GUI_BLACK|GUI_FONT_16,"Task1 err:%d",err1);
//		OSTimeDlyHMSM(0, 0, 1, 0);OSTimeDly(50);}
}void task2(void *p_arg) 
{INT8U err2 = OSTaskStkChk(task2_PRIO,&StackBytes2);GUI_Printf(0,140,GUI_WHITE,GUI_BLACK|GUI_FONT_16,"Task2 UsedStack:%d",StackBytes2.OSUsed);GUI_Printf(0,120,GUI_WHITE,GUI_BLACK|GUI_FONT_16,"Task2 FreeStack:%d",StackBytes2.OSFree);GUI_Printf(0,160,GUI_WHITE,GUI_BLACK|GUI_FONT_16,"Task2 err:%d",err2);while(1){GUI_Printf(0,100,GUI_WHITE,GUI_BLACK|GUI_FONT_16,"任务2");
//		GUI_Printf(0,120,GUI_WHITE,GUI_BLACK|GUI_FONT_16,"Task2 FreeStack:%d",StackBytes2.OSFree);
//		GUI_Printf(0,140,GUI_WHITE,GUI_BLACK|GUI_FONT_16,"Task2 UsedStack:%d",StackBytes2.OSUsed);
//		GUI_Printf(0,160,GUI_WHITE,GUI_BLACK|GUI_FONT_16,"Task2 err:%d",err2);
//		OSTimeDlyHMSM(0, 0, 1, 0);OSTimeDly(50);// 其他任务...}
}

OSTaskCreateExt()创建拓展函数与OSTaskCreate()创建任务函数相比多了五个入口参数,它们的前四个参数task,pdata,ptos和prio(分别为:task是任务代码的指针,pdata是任务开始执行时传递给任务的参数的指针,ptos是分配给任务的堆栈的栈顶指针,prio是分配给任务的优先级)完全相同,先后顺序都一模一样,方便用户将OSTaskCreate()移植到OSTaskCreateExt()。后五个参数分别为:
id参数,为要建立的任务创建一个特殊的标识符,但是只要简单的将id设置的和人物的优先级一样就行。
pbos,是指向任务的堆栈的栈底指针,用于堆栈的检验。
stk_size,用于指定堆栈成员的数目,用于堆栈的检验。
pext,指向用户附加的数据域的指针,用来拓展任务的OS_TCB。
opt,用于设定OSTaskCreateExt()的选项,指定是否允许堆栈检验,是否将堆栈区域清零,任务是否要进行浮点操作等等。ucosii.h文件有一个所有选项的常数表,用户在使用时只需将选项常数进行位或操作即可。在堆栈检验时OSTaskCreateExt()的最后一个参数必须为OS_TASK_OPT_STK_CHK| OS_TASK_OPT_STK_CLR,用于开启堆栈检验。
2.定义结构体OS_STK_DATA XXX用于堆栈检验。如

OS_STK_DATA  StackBytes1;						/*定义结构体,用于堆栈检验*/
OS_STK_DATA  StackBytes2;						/*定义结构体,用于堆栈检验*/

结构体XXX中包含XXX.OSFree和XXX.OSUsed, 分别代表任务堆栈的使用字节数量和空闲字节数量。如

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;

3.调用堆栈检验函数OSTaskStkChk(),两个输入参数分别为待检验任务的优先级和结构体XXX的地址。

void task1 (void *p_arg)
{INT8U err1 = OSTaskStkChk(task1_PRIO,&StackBytes1);GUI_Printf(0,40,GUI_WHITE,GUI_BLACK|GUI_FONT_16,"Task1 FreeStack:%d",StackBytes1.OSFree);GUI_Printf(0,60,GUI_WHITE,GUI_BLACK|GUI_FONT_16,"Task1 UsedStack:%d",StackBytes1.OSUsed);GUI_Printf(0,80,GUI_WHITE,GUI_BLACK|GUI_FONT_16,"Task1 err:%d",err1);while(1){GUI_Printf(0,20,GUI_WHITE,GUI_BLACK|GUI_FONT_16,"任务1");
//		GUI_Printf(0,40,GUI_WHITE,GUI_BLACK|GUI_FONT_16,"Task1 FreeStack:%d",StackBytes1.OSFree);
//		GUI_Printf(0,60,GUI_WHITE,GUI_BLACK|GUI_FONT_16,"Task1 UsedStack:%d",StackBytes1.OSUsed);
//		GUI_Printf(0,80,GUI_WHITE,GUI_BLACK|GUI_FONT_16,"Task1 err:%d",err1);
//		OSTimeDlyHMSM(0, 0, 1, 0);OSTimeDly(50);}
}

正常运行的堆栈检验函数OSTaskStkChk()的返回值是0,这里用
INT8U err1 = OSTaskStkChk(task1_PRIO,&StackBytes1);
也是为了观察返回值判断是否运行成功。运行结果如图
运行结果
任务1和2均设置了40个OS_STK,使用了34,空闲6。用户应该使自己的应用程序运行足够长的时间,并且经历最坏的堆栈情况,这样才能得到正确的数,为了适应程序的多升级和拓展,应该多分配10%到100%的堆栈空间。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com