/*检查优先级为prio的任务的堆栈使用情况,并把结果存入OS_STK_DATA类型的单元中*/
INT8U OSTaskStkChk(INT8U prio,OS_STK_DATA *pdata)
{
OS_TCB *ptcb; /*用于执行所要堆栈检测任务的TCB*/
OS_STK *pchk; /*用于指向所要堆栈检测的任务的堆栈*/
INT32U free; /*存放未使用的堆栈容量*/
INT32U size; /*存放堆栈总容量*/
pdata->OSFree=0;/*将用于存放堆栈检测结果的单元进行清零*/
pdata->OSUsed=0;
if(prio>OS_LOWEST_PRIO &&prio != OS_PRIO_SELF)/*查看优先级是否在有效范围内*/
{
return(OS_PRIO_INVALID);
}
OS_ENTER_CRITICAL();/*在对任务的TCB内容读取的过程中需要关中断,即TCB是临界资源,不可多个进程同时访问*/
if (prio==OS_PRIO_SELF) /*如果prio的值为OS_PRIO_SELF 即prio==0xFF,系统规定优先级为当前正在执行的任务*/
{
prio=OSTCBCur->OSTCBPrio;/*需要将prio的值更改为当前正在执行任务的优先级*/
}
ptcb=OSTCBPrioTbl[prio];/*根据任务的优先级和TCB优先级表,找到所要进程堆栈检测任务的TCB*/
if(ptcb==(OS_TCB *)0) /*判断任务是否存在,这个是针对,如果所要检查的任务并不是正在执行的任务*/
{
OS_EXIT_CRITICAL(); /*任务不存在的话,要先开中断,然后再返回*/
return (OS_TASK_NOT_EXIST);
}
if((ptcb->OSTCBopt&OS_TASK_OPT_STK_CHK)==0) /*在任务存在的前提下,再查看该任务是否允许堆栈检测*/
{ /*OSTCBopt中的内容为0的话OS_TACK_OPT_STK_CHK一定为零*/
OS_EXIT_CRITICAL(); /*而OS_TACK_OPT_STK_CHK为零的话,OSTCBopt不一定为零*/
return (OS_TASK_OPT_ERR);
}
/*通过上面的操作顺利找到了TCB,下面的操作就是读取TCB中相关的信息*/
free = 0; /*将需要存放空闲堆栈大小的单元清零*/
size = ptcb->OSTCBStkSize; /*读取任务的堆栈的大小*/
pchk = ptcb->OSTCBStkBottom; /*读取栈底堆栈的值*/
OS_EXIT_CRITICAL(); /*TCB中需要的信息已经读取完毕了,此时不需要再霸占TCB了,所以开中断*/
#if OS_STK_GROWTH == 1 /*根据系统硬件的情况,进行空闲堆栈的计算*/
while(*pchk++ == 0)
{
free++;
}
#else
while(*pchk-- == 0)
{
free++;
}
#endif
/*堆栈使用情况计算完毕,填写到所要存储的单元中,并返回堆栈查询没有出错*/
pdata->OSFree = free *sizeof(OS_STK);
pdata->OSUsed = (size-free) * sizeof(OS_STK);
return (OS_NO_ERR);
}
小结:
1.堆栈检查做了哪些事情:主要就是对所要堆栈检查的任务进行堆栈检查,并把检查结果存储在一个单元中*/
①堆栈检查需要的一些临时变量:指向TCB的指针,执行堆栈的指针,堆栈的大小的单元,空闲堆栈大小的单元
②操作:查找到TCB,通过TCB查找到任务的堆栈,对任务堆栈的情况进行计算。
2.堆栈检查具体执行的顺序:
①根据优先级以及TCB优先级表找到TCB,要判断:优先级是否有效;任务是否存在;任务是否允许进行堆栈检测;
②读取TCB中关于堆栈的信息:栈底的位置;堆栈的大小;
③计算空闲的堆栈,和以及使用的堆栈,并写入到给定的存储单元中。
μC/OS之OSTaskStkChk()
最新推荐文章于 2023-11-01 15:00:55 发布