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

news2024/11/27 0:23:19

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.coloradmin.cn/o/615723.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用Graalvm+Swing搓了个原生桌面应用的轮子:文件差异对比工具,附轮子源码

文章目录 1、DFDiff介绍2、软件架构3、安装教程3.1、编译为jar包运行3.2、编译为原生应用运行 4、运行效果图5、项目源码地址 1、DFDiff介绍 当前已实现的功能比较两个文件夹内的文件差异,已支持文件差异对比。 2、软件架构 软件架构说明 开发环境是在OpenJDK17&…

docker 安装gitlab jenkins git maven

jenkins 配置git提示 问题1、Error performing git command: /usr/local/git ls-remote -h 问题2、stdout: stderr: Host key verification failed. fatal: Could not read from remote repository. Please make sure you have the correct access rights and the repositor…

【数据结构】一文带你掌握二叉树的构造与应用

文章目录 1. 构造二叉树2. 前序遍历2.1 前序遍历递归2.2 前序遍历非递归 3. 中序遍历3.1 中序遍历递归3.2 中序遍历非递归 4. 后序遍历4.1 后序遍历递归4.2 后序遍历非递归 5. 层序遍历6. 节点个数6.1 所有节点个数6.2 获得叶子节点个数 7. 检测值为value的元素是否存在8.总结 …

数据库SQL2000最基本的安装和操作教程

Chengg0769 2012年 转载请保留以下版权来源 www.mis2erp.com http://blog.csdn.net/chengg0769 http://www.haojiaocheng.cc 题外话: 之前写了一个项目,因为是国企,各种文档都要给到他们。当时就写了一个简单的维护管理SQL2000的文档。这…

【2352. 相等行列对】

来源:力扣(LeetCode) 描述: 给你一个下标从 0 开始、大小为 n x n 的整数矩阵 grid ,返回满足 Ri 行和 Cj 列相等的行列对 (Ri, Cj) 的数目。 如果行和列以相同的顺序包含相同的元素(即相等的数组&#…

DMBOK知识梳理for CDGA/CDGP——第四章 数据架构(附常考知识点)

关 注ghz“大数据食铁兽”,回复“知识点”获取《DMBOK知识梳理for CDGA/CDGP》常考知识点(第四章 数据架构) 第四章 数据架构 第四章是CDGA|CDGP考试的重点考核章节之一,分值占比高,知识点比较密集,重点…

CAN message 属性DLC和DataLength,极易混淆

🍅 我是蚂蚁小兵,专注于车载诊断领域,尤其擅长于对CANoe工具的使用🍅 寻找组织 ,答疑解惑,摸鱼聊天,博客源码,点击加入👉【相亲相爱一家人】🍅 玩转CANoe&…

STM32开发(CubeMX+HAL)——点灯(轮询、中断)

目录 1.CubeMX生成工程文件 2.点灯1——轮询 3.点灯2——中断 3.1CubeMX配置时钟 3.2中断和事件简介 3.3配置GPIO口 3.4使能中断 3.5配置工程 3.6中断函数编写 1.CubeMX生成工程文件 1.1新建工程 1.2输入STM32C8T6选择芯片 1.3双击芯片 1.4 选择System Core—SYS——…

DAY09_JQueryBootStrap实现省略号效果

目录 1 JQuery简介2 引入JQuery方式3 JS与JQ之间的转换4 选择器4.1 基本选择器4.2 层级选择器4.2.1 层级选择器相关方法 4.3 过滤选择器4.4 内容选择器4.5 可见选择器4.6 隐藏显示的相关方法4.7 属性选择器4.8 子元素选择器4.9 表单选择器 5 JQ中新增的遍历方式6 JQ中相关方法7…

vue解决浏览器中跳转新页面缓存上一页表单等内容方法

在工作中,有可能会遇到需要缓存页面或组件的功能。 情况1:比如在h5中有个一个50个表单,在填到第40个表单时,需要你去另一个新页面去选择列表项,然后把数据带回来。需要我们不仅把数据带回来还要保留前面已经填好的40个…

GIS地图:解读未知的地理空间之谜

在这个信息爆炸的时代,如何有效地理解和利用地理空间数据成为各行各业追求的目标。而GIS地图作为一种强大的工具,能够帮助我们连接世界的空间智慧。 GIS地图的魅力在于它能够将庞大的地理数据转化为直观、可视化的地图表达。通过GIS地图,我们…

管理平台|智慧工地将成为施工界的“扛把子”!

大家都知道,建筑业是一个安全事故频发的高危行业,特别在施工环节,由于施工现场人员复杂、环境混乱、地点分散、多工序交叉等现象,如何进行现场施工管理就显得格外重要。 但是,依赖于现场管理的施工模式总是存在着很多…

数据结构-图结构

图是最为复杂的数据结构。如果数据元素之间存在一对多或者多对多的关系,那么这种数据的组织结构就叫作图结构。 图的基本概念 图的定义 图Graph是由顶点(图中的节点被称为图的顶点)的非空有限集合V与边的集合E(顶点之间的关系&a…

什么AC+AP组网?什么是mesh组网?

一、什么是ACAP组网? ACAP组网是一种基于集中式管理的无线局域网(WLAN)组网架构,主要由AC(Access Controller)和多个AP(Access Point)组成。AC作为网络管理中心,负责控制…

别乱分层,PO、VO、DAO、BO、DTO、POJO 到底应该用在哪里,你知道吗

一、PO :(persistant object),持久对象 二、VO :(value object),值对象 三、DAO :(Data Access Objects),数据访问对象接口 四、BO :(Business Object&…

30天从入门到精通TensorFlow1.x 第六天,可视化工具 TensorBoard

文章目录 一、接前一天二、TensorBoard(1). 什么是TensorBoard(2). TensorBoard有什么用(3). TensorBoard怎么安装 三、tf.summary模块(1).如何使用tensorboard(2&#x…

数据结构之二叉树(Binary Tree)详解

目录 1、什么是二叉树? 2、二叉树的遍历:深度优先和广度优先 (1)深度优先搜索(DFS)算法 (2)广度优先搜索(BFS)算法 3、二叉树的性质详解 4、二叉树的类型 (1)满二叉树 &…

IT服务台追踪的关键故障指标

指标是 IT 服务管理的核心,可提供运营见解并帮助确定持续改进的领域。通常的服务台指标有助于展示内部运营效率。为 例如,衡量在指定时间内解决的工单数量的 SLA 是展示服务台效率的关键因素。另一方面,故障指标可帮助团队识别 IT 基础架构中…

Linux基本指令学习(入门)

Linux基本指令学习 0.在xshell中登录自己的虚拟机1. ls指令2. pwd命令3. cd 指令4. touch指令5.mkdir指令6.rmdir指令 && rm 指令7.man指令:8.cp指令9.mv指令:10.cat11.more指令12.less指令13.head指令14.tail指令15.时间相关的指令16.Cal指令17…

【Linux】Tomcat 部署及优化

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 Tomcat 部署及优化 一、Tomcat 概述1.Tomcat 介绍2.Tomcat 核心组件3.Tomcat 组件结构4.Tomcat 处理请求过程 二、Tomcat 部署步骤1.关闭防火墙2.安装JDK3.设置JDK环境变量4.…