- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
4.堆栈检验的原理与源代码
如图3.19所示,以自下向上生长的堆栈为例,说明堆栈检验的原理。这种讨论方法也适合自上向下生长的堆栈。具体说明如下:
(1)因为堆栈自下向上生长,所以OS_STK_GROWTH置0。通过查看堆栈本身的内容,μC/OS-Ⅱ从而决定堆栈的方向。堆栈检验不会自动执行,只有发出堆栈检验命令时,堆栈检验功能才会被执行。
(2)进行堆栈检验时,μC/OS-Ⅱ要求在任务建立时堆栈被清零。图3.19堆栈检验(3)根据OS_TCB中存储的数据,μC/OS-Ⅱ可以得到堆栈栈底的位置。
(4)得到分配给任务的堆栈的尺寸。
(5)堆栈检验OSTaskStkChk()开始沿着栈底计算空闲堆栈空间数量,具体实现方法是统计存储值为0的连续堆栈入口的数量,直到发现存储值不为0的堆栈入口为止。堆栈空间的计算单位是堆栈入口的宽度,而不是字节,其具体数据类型参看OS_CPU.H中的OS_STK。也就是说,如果堆栈入口的宽度是16位,对0的比较也是按16位完成的。已用堆栈空间的数量可以从用户在OSTaskCreateExt()中定义的堆栈尺寸中减去了存储值为0的连续堆栈入口尺寸后得到。(6)计算完毕后,OSTaskStkChk()把空闲堆栈的字节数和已用堆栈的字节数放置在数据结构OS_STK_DATA中(参看μCOS_Ⅱ.H)。
(7)在给定的某个时刻,被检验任务的堆栈指针可能会指向整个堆栈中的任何位置。每次调用OSTaskStkChk()时,用户也可能会因为任务还没触及堆栈的最深处而得到不同的堆栈空闲空间数。因此,为了能得到正确的空闲堆栈数量,用户必须使应用程序运行得足够久,并且确保经历了最坏的堆栈使用情况。用户可以根据最坏情况下的堆栈需求设置堆栈的最终容量。一般建议多分配10%~100%的堆栈空间,以便于升级和扩展。堆栈检验的结果并不是堆栈使用的全部实际情况,只是一个大致的使用结果。
OSTaskStkChk()函数的源代码如程序清单3.28所示。 程序清单3.28堆栈检验函数的源代码
INT8UOSTaskStkChk(INT8Uprio,OS_STK_DATA*pdata){
#ifOS_CRITICAL_METHOD=?=3
OS_CPU_SRcpu_sr;
#endif
OS_TCB *ptcb;
OS_STK *pchk;
INT32U free;
INT32U size;#ifOS_ARG_CHK_EN0
if(prioOS_LOWEST_PRIOprio!=OS_PRIO_SELF){/*确保优先级有效 */
return(OS_PRIO_INVALID);
}
#endif
pdata-OSFree =0;
pdata-OSUsed =0;
OS_ENTER_CRITICAL();if(prio=?=OS_PRIO_SELF){ /*将OS_PRIO_SELF换算为优先级数值 */
prio=OSTCB-OSTCBPrio;
}
ptcb=OSTCBPrio[prio];
if(ptcb=?=(OS_TCB*)0){ /*确保要被删除的任务是存在的 */
OS_EXIT_CRITICAL();
return(OS_TASK_OPT_EXIST);
}/*要执行堆栈检验,必须用OSTaskCreateExt()建立任务,且已经传递了选项OS_TASK_OPT_CHK;*/
/*若任务是OSTaskCreate()函数建立的,因opt参数为0,则将造成检验失败*/
if((ptcb-OSTCBOptOS_TASK_OPT_STK_CHK)=?=0){
OS_EXIT_CRITICAL();
return(OS_TASK_OPT_ERR);
}
free =0; /*从栈底开始计算堆栈的空闲空间,直到发现非0的堆栈入口为止*/ size =ptcb-OSTCBStkSize;
pchk=ptcb-OSTCBStkBottom;
OS_EXIT_CRITICAL();
#ifOS_STK_GROWTH=?=1
while(*pchk++=?=(OS_STK)0){
free++;
}#else
while(*pchk--=?=(OS_S
文档评论(0)