uCOSii_任务栈检测和任务栈清除

news/2024/11/29 2:29:11/

1、任务栈检测和任务栈清除

在创建任务时,也需要设置OSTaskCreateExt()传入opt参数。

opt= (INT16U)(OS_TASK_OPT_STK_CLR | OS_TASK_OPT_STK_CHK),可以使用OSTaskStkChk()检查的任务栈的剩余空间,也可以使用OS_TaskStkClr()清除任务栈。

2、创建任务举例

#define LED0_TASK_PRIORITY   5     //设置LED0_TASK任务优先级为5

#define LED0_TASK_STACK_SIZE             88

//设置LED0_TASK任务堆栈大小为88, 8的倍数

//如果任务中使用printf来打印浮点数据的话一点要8字节对齐

OS_STK LED0_TASK_STACK[LED0_TASK_STACK_SIZE];//LED0_TASK任务栈

//LED0_TASK任务

void LED0_TASK(void *pdata)

{

         (void)pdata;

         while(1)

         {

                   OSTimeDlyHMSM(0,0,0,500);//延时500ms

         }

}

OSTaskCreateExt(

LED0_TASK,/*任务函数指针*/

(void *)0,/*建立任务时,传递的参数*/                                                                                   

(OS_STK*)&LED0_TASK_STACK[LED0_TASK_STACK_SIZE-1],/*指向任务栈顶的指针*/

LED0_TASK_PRIORITY, /*任务优先级*/

LED0_TASK_PRIORITY,/*任务ID用优先级代替,2.52版本,无实际作用,保留作为扩展用*/

(OS_STK*)&LED0_TASK_STACK[0],/*指向栈底部的指针,用于OSTaskStkChk()函数*/

LED0_TASK_STACK_SIZE, /*指定任务堆栈的大小,OS_STK类型决定*/

(void *)0, /*定义数据结构的指针,作为TCB的扩展*/

(INT16U)(OS_TASK_OPT_STK_CLR | OS_TASK_OPT_STK_CHK)/*允许任务栈检查*/

);

3OSTaskStkChk()函数

1)、在使用OSTaskStkChk()之前,要先声明OS_STK_DATA结构变量,如下:

OS_STK_DATA  TaskStackData;

2)、OSTaskStkChk()应用举例

OSTaskStkChk( LED0_TASK_PRIORITY, &TaskStackData);

3)、分析解析OSTaskStkChk()函数

函数功能:结构指针p_stk_data返回的数据就是该任务栈的使用情况

//prio表示任务优先级

INT8U  OSTaskStkChk (INT8U prio, OS_STK_DATA  *p_stk_data)

{

    OS_TCB    *ptcb; //任务控制块的指针

    OS_STK    *pchk;//任务栈的指针

    INT32U     nfree;//该任务栈的剩余空间大小,单位为OS_STK

INT32U     size;//该任务栈的总空间大小,单位为OS_STK

//unsigned int重命名为OS_STK

#if OS_CRITICAL_METHOD == 3u

    OS_CPU_SR  cpu_sr = 0u;

#endif

参数检查开始//

#if OS_ARG_CHK_EN > 0u

if (prio > OS_LOWEST_PRIO)

{/*若任务优先级prio比最低优先级(空闲任务优先级),则表示任务优先级错误*/

        if (prio != OS_PRIO_SELF)

        {//自身优先级OS_PRIO_SELF255

            return (OS_ERR_PRIO_INVALID);//优先级无效

        }

    }

if (p_stk_data == (OS_STK_DATA *)0)

{/*p_stk_data结构指针为0*/

        return (OS_ERR_PDATA_NULL);

    }

#endif

    p_stk_data->OSFree = 0u; /*假定任务栈的可用空间0*/

    p_stk_data->OSUsed = 0u; /*假定任务栈的已用空间0*/

    OS_ENTER_CRITICAL();//进入临界区(无法被中断打断),需要定义cpu_sr变量

if (prio == OS_PRIO_SELF)

{/*若任务优先级prio为自身优先级,需要读取当前任务的优先级*/

        prio = OSTCBCur->OSTCBPrio;

        //读取当前任务的优先级

        // OSTCBCur指向“当前任务控制块”的指针

}

ptcb = OSTCBPrioTbl[prio];

//根据所给的任务优先级prio,读取任务控制块的指针

//*OSTCBPrioTbl[]为所有的任务控制块的指针

//OSTCBTbl[]任务控制块数组,所有的任务控制块都保存在这个数组中

if (ptcb == (OS_TCB *)0)

{/*任务控制块的指针ptcb0 */

        OS_EXIT_CRITICAL();//退出临界区(可以被中断打断)

        return (OS_ERR_TASK_NOT_EXIST);

}

if (ptcb == OS_TCB_RESERVED)

{/*任务控制块的指针ptcbOS_TCB_RESERVED,OS_TCB_RESERVED =1 */

        OS_EXIT_CRITICAL();//退出临界区(可以被中断打断)

        return (OS_ERR_TASK_NOT_EXIST);

}

if ((ptcb->OSTCBOpt & OS_TASK_OPT_STK_CHK) == 0u)

{

 //调用OSTaskCreateExt()时会传入opt

 //opt= (INT16U)(OS_TASK_OPT_STK_CLR | OS_TASK_OPT_STK_CHK)

 //OS_TASK_OPT_STK_CHK允许任务栈检查

        OS_EXIT_CRITICAL();//退出临界区(可以被中断打断)

        return (OS_ERR_TASK_OPT);

}

参数检查结束//

    nfree = 0u; //假定该任务栈的剩余空间大小为0,单位为OS_STK

size  = ptcb->OSTCBStkSize;//读取该任务栈的总空间大小,单位为OS_STK

    pchk  = ptcb->OSTCBStkBottom;//读取该任务栈的栈底指针

    OS_EXIT_CRITICAL();//退出临界区(可以被中断打断)

#if OS_STK_GROWTH == 1u

// OS_STK_GROWTH为栈的增长方向,1表示栈是向下增长

//CM3,栈是由高地址向低地址增长的,所以OS_STK_GROWTH设置为1

while (*pchk++ == (OS_STK)0)

{

        nfree++;

        //计算任务栈的剩余空间大小”,单位为OS_STK

        //栈是由高地址向低地址增长的,所以栈底的地址较小,使用pchk++

    }

#else

while (*pchk-- == (OS_STK)0)

{

        nfree++;

        //计算任务栈的剩余空间大小”,单位为OS_STK

        //栈是由低地址向高地址增长的,所以栈底的地址较大,使用pchk--

    }

#endif

p_stk_data->OSFree = nfree * sizeof(OS_STK);

/* unsigned int重命名为OS_STK,计算该任务栈的可用空间大小,单位为字节数*/

p_stk_data->OSUsed = (size - nfree) * sizeof(OS_STK);

/*Compute number of bytes used on the stack*/

    return (OS_ERR_NONE);

}

4OS_TaskStkClr()函数

1)、警慎调用OS_TaskStkClr()函数,否则可能会导致系统崩溃。

注意:这个函数是给OSTaskCreateExt()调用的,在创建任务时,需要将任务栈初始化为0。在任务中不要随便调用

2)、分析解析OS_TaskStkClr()函数

函数功能:清除任务栈

//pbos为指向栈底部的指针

//size为任务堆栈的大小

//opt= (INT16U)(OS_TASK_OPT_STK_CLR | OS_TASK_OPT_STK_CHK),该函数才会执行

void OS_TaskStkClr (OS_STK *pbos, INT32U size, INT16U opt)

{

if ((opt & OS_TASK_OPT_STK_CHK) != 0x0000u)

{ //调用OSTaskCreateExt()时会传入opt

 //opt= (INT16U)(OS_TASK_OPT_STK_CLR | OS_TASK_OPT_STK_CHK)

 //OS_TASK_OPT_STK_CHK允许任务栈检查

        if ((opt & OS_TASK_OPT_STK_CLR) != 0x0000u)

        {/*See if stack needs to be cleared*/

#if OS_STK_GROWTH == 1u

// OS_STK_GROWTH为栈的增长方向,1表示栈是向下增长

//CM3,栈是由高地址向低地址增长的,所以OS_STK_GROWTH设置为1

            while (size > 0u) //循环将任务栈清除

            {/*Stack grows from HIGH to LOW memory*/

                size--;

                *pbos++ = (OS_STK)0;

                //从栈底向上清除

                //栈是由高地址向低地址增长的,所以栈底的地址较小,使用pchk++

            }

#else

            while (size > 0u)

            {/*Stack grows from LOW to HIGH memory*/

                size--;

                *pbos-- = (OS_STK)0; /*Clear from bottom of stack and down*/

                //从栈底向下清除

                //栈是由低地址向高地址增长的,所以栈底的地址较大,使用pchk--

            }

#endif

        }

    }

}

3)、OS_TaskStkClr()应用举例

这是给好奇心很强的人看的。再次强调,不要随便调用

OS_TaskStkClr(

(OS_STK*)&LED0_TASK_STACK[0],/*指向栈底部的指针,用于OSTaskStkChk()函数*/

LED0_TASK_STACK_SIZE, /*指定任务堆栈的大小,OS_STK类型决定*/

(INT16U)(OS_TASK_OPT_STK_CLR | OS_TASK_OPT_STK_CHK)/*允许任务栈清除*/

);

5、实际应用

const char CHECK_TASK_rn_REG[]="\r\n";

const char CHECK_TASK_Initialise_REG[]="CHECK_TASK Initialise";

const char LED0_TASK_used_Or_free_REG[]="LED0_TASK used/free:";

const char LED1_TASK_used_Or_free_REG[]="LED1_TASK used/free:";

const char KEY_TASK_used_Or_free_REG[]="KEY_TASK used/free:";

const char CHECK_TASK_used_Or_free_REG[]="CHECK_TASK used/free:";

const char Used_REG[]="  used%";

const char Err_REG[]="  err:";

void CHECK_TASK(void *pdata)

{

         OS_STK_DATA  pTaskStackData;

         u8 err1 =0;//1079062528

         (void)pdata;

         printf("%s",CHECK_TASK_rn_REG);

         printf("%s",CHECK_TASK_Initialise_REG);

         while(1)

         {

                   err1 = OSTaskStkChk( LED0_TASK_PRIORITY, &pTaskStackData);

                   printf("%s",CHECK_TASK_rn_REG);

                   printf("%s",LED0_TASK_used_Or_free_REG);

        printf("%d/",pTaskStackData.OSUsed);

        printf("%d",pTaskStackData.OSFree);

                   printf("%s",Used_REG);

printf( "%0.2f",(float)(pTaskStackData.OSUsed*100)/(float)(pTaskStackData.OSUsed+pTaskStackData.OSFree) );

                   printf("%s",Err_REG);printf("%d",err1);

                   printf("%s",CHECK_TASK_rn_REG);

                   err1 = OSTaskStkChk( LED1_TASK_PRIORITY, &pTaskStackData);

                   printf("%s",LED1_TASK_used_Or_free_REG);

        printf("%d/",pTaskStackData.OSUsed);

        printf("%d",pTaskStackData.OSFree);

                   printf("%s",Used_REG);

printf( "%0.2f",(float)(pTaskStackData.OSUsed*100)/(float)(pTaskStackData.OSUsed+pTaskStackData.OSFree) );

                   printf("%s",Err_REG);printf("%d",err1);

                   printf("%s",CHECK_TASK_rn_REG);

                   err1 = OSTaskStkChk( KEY_TASK_PRIORITY, &pTaskStackData);

                   printf("%s",KEY_TASK_used_Or_free_REG);

        printf("%d/",pTaskStackData.OSUsed);

        printf("%d",pTaskStackData.OSFree);

                   printf("%s",Used_REG);

printf( "%0.2f",(float)(pTaskStackData.OSUsed*100)/(float)(pTaskStackData.OSUsed+pTaskStackData.OSFree) );

                   printf("%s",Err_REG);printf("%d",err1);

                   printf("%s",CHECK_TASK_rn_REG);

                   err1 = OSTaskStkChk( CHECK_TASK_PRIORITY, &pTaskStackData);

             printf("%s",CHECK_TASK_used_Or_free_REG);

        printf("%d/",pTaskStackData.OSUsed);

        printf("%d",pTaskStackData.OSFree);

                   printf("%s",Used_REG);

printf( "%0.2f",(float)(pTaskStackData.OSUsed*100)/(float)(pTaskStackData.OSUsed+pTaskStackData.OSFree) );

                   printf("%s",Err_REG);printf("%d",err1);

                   printf("%s",CHECK_TASK_rn_REG);

                   OSTimeDlyHMSM(0,0,5,0);//延时5s

         }

}

输出结果:

LED0_TASK used/free:184/168  used%52.27  err:0

LED1_TASK used/free:212/172  used%55.21  err:0

KEY_TASK used/free:184/168  used%52.27  err:0

CHECK_TASK used/free:444/68  used%86.72  err:0

 

 


http://www.ppmy.cn/news/243793.html

相关文章

Keil5新建工程

STM32新建工程 1、基于寄存器、基于库函数、基于HAL2、基于标准库的工程3、工程架构4、基于库函数点灯实验 1、基于寄存器、基于库函数、基于HAL 1、基于寄存器:与51单片机开发案方式一样,是用程序直接配置寄存器,来达到我们想要的功能&…

长虹 Watch FLY 智能手表 评测

该手表采用了传统手表外观设计,尺寸为 48mm,配有 1.45 英寸 412*412px 60Hz IPS 圆屏,可更换多种表盘;配有 260mAh 电池,续航达 14 天;支持蓝牙 5.2、IP68 防尘防水。 长虹 Watch FLY 智能手表搭载 240MHz …

pacewear android wear,Pacewear智能手表怎么样?Pacewear智能手表评测(2)

手表的表带用的是20mm宽度设计,氟橡胶材质,戴在手腕上很柔软,戴着手表跑步也不会觉得割手。不过有利有弊吧,这种柔软表带的感觉和表盘略显硬朗的设计看似有些不搭。 配置与连接 手表和手机不同,由于定位差异&#xff0…

android系统智能手表 开箱,完全安卓体验 Omate智能腕表实机开箱

Omate TureSmart智能腕表行货上市时间已经临近,智能穿戴频道也在第一时间收到了来自Omate的工程样机产品,据介绍目前产品已经最终定型,所以我们拿到的产品与最终上市产品之间差别不大,将在本月底以1888元在京东商城开始预售。 Omate TureSmart智能腕表是一款运行在安卓4.2操…

这才是智能手表该有的样子 HUAWEI WATCH 2评测

近来,智能穿戴产品市场大热,不少品牌纷纷推出了自己的全新产品,就在今年的巴塞罗那2017MWC上,华为正式公布了自己的智能手表的第二代产品HUAWEI WATCH 2。笔者最近也拿到了这款HUAWEI WATCH 2。没错!这才是智能手表该有…

儿童智能手表行业安全问题报告

路人甲 2015/09/23 22:18 Wooyun & NumenTeam 联合出品 0x00 引子 这是来自美剧《网络犯罪调查》的一张截图,讲述的是黑客通过入侵了数万家庭婴儿监控摄像头,分析家庭的作息时间,在合适的时机偷出需要的婴儿,并实时进行全球在…

数码类测评:dido G28S Pro心电血压智能手表

米粉双哥智能好物开箱:年轻人的第一款健康智能手表! Hi~今天米粉双哥为大家测评dido G28S Pro心电血压智能手表。随着科技的不断发展,智能手表已经成为了很多用户除手机外的第二件随身携带的智能设备。智能手表的功能绝不仅仅是看时间&#x…

Android指针手表,既有屏幕又有指针的智能手表,这设计有一套

【不满格评测原创】说到爱国者,这可是实打实的老牌子,我们身边有太多爱国者的东西了,比如音频播放器、电脑外设、数码周边、办公数码、教育数码,等等等等~可以说,爱国者已经把产品覆盖到了我们生活的方方面面。 不过&a…