[uCOS/RTOS]uC/OS-II中的任务堆栈大小检测

article/2025/11/8 1:40:41

 在uC/OS-II系统中,创建任务的时候除了需要配置任务的优先级以外,还需要对任务堆栈大小进行分配。而对于单片机这种RAM并不是非常大的微控制器来说,RAM显得格外珍贵,如果任务堆栈分配大了,会导致RAM不够用,分配小了任务运行又会受到影响,甚至系统的崩溃,所以在创建任务的时候合适的堆栈大小分配很重要。

  uC/OS-II中任务堆栈的作用主要有两个,一是在任务运行的时候保存任务的一些局部变量,二是当任务挂起时,保存任务现场,也就是CPU寄存器的值。uC/OS-II系统是在OSTaskCreate();中的OSTaskStkInit();来确定堆栈地址的。虽然任务堆栈大小也可以通过设计者认为去测算出来,但是要考虑的东西太多,而且也不能十分精确。

  实际上uC/OS-II在OS_TASK.C中提供了很多有关任务管理的功能函数,包括:

建立任务OSTaskCreate()、建立扩展任务OSTaskCreateExt()、删除任务OSTaskDel()等,其中还有一个关于堆栈的函数就是堆栈检验OSTaskStkChk(),这个函数的检测原理就是顺着堆栈的栈底开始计算空闲的堆栈空间大小,实现方法是统计存储值为0的连续堆栈入口的数量,直到发现存储值不为0的堆栈入口,这样就可以知道实际占用的堆栈大小了。

  该函数的调用和运行需要将OS_TASK_STAT_STK_CHK_EN和OS_TASK_CREATE_EXT_EN进行使能,而检测的任务对象是通过任务的优先级来获取的,即:INT8U  prio,并且需要定义一个OS_STK_DATA的结构体变量来存放堆栈情况的值,

其中的:

INT32U  OSFree    就是剩余的堆栈大小

INT32U  OSUsed    是已经使用的堆栈大小。

OSTaskStkChk()源码:

INT8U  OSTaskStkChk (INT8U         prio,OS_STK_DATA  *p_stk_data){OS_TCB    *ptcb;OS_STK    *pchk;INT32U     nfree;INT32U     size;#if OS_CRITICAL_METHOD == 3u                           /* Allocate storage for CPU status register     */OS_CPU_SR  cpu_sr = 0u;#endif#if OS_ARG_CHK_EN > 0uif (prio > OS_LOWEST_PRIO) {                       /* Make sure task priority is valid             */if (prio != OS_PRIO_SELF) {return (OS_ERR_PRIO_INVALID);}}if (p_stk_data == (OS_STK_DATA *)0) {              /* Validate 'p_stk_data'                        */return (OS_ERR_PDATA_NULL);}#endifp_stk_data->OSFree = 0u;                           /* Assume failure, set to 0 size                */p_stk_data->OSUsed = 0u;OS_ENTER_CRITICAL();if (prio == OS_PRIO_SELF) {                        /* See if check for SELF                        */prio = OSTCBCur->OSTCBPrio;}ptcb = OSTCBPrioTbl[prio];if (ptcb == (OS_TCB *)0) {                         /* Make sure task exist                         */OS_EXIT_CRITICAL();return (OS_ERR_TASK_NOT_EXIST);}if (ptcb == OS_TCB_RESERVED) {OS_EXIT_CRITICAL();return (OS_ERR_TASK_NOT_EXIST);}if ((ptcb->OSTCBOpt & OS_TASK_OPT_STK_CHK) == 0u) { /* Make sure stack checking option is set      */OS_EXIT_CRITICAL();return (OS_ERR_TASK_OPT);}nfree = 0u;size  = ptcb->OSTCBStkSize;pchk  = ptcb->OSTCBStkBottom;OS_EXIT_CRITICAL();#if OS_STK_GROWTH == 1uwhile (*pchk++ == (OS_STK)0) {                    /* Compute the number of zero entries on the stk */nfree++;}#elsewhile (*pchk-- == (OS_STK)0) {nfree++;}#endifp_stk_data->OSFree = nfree * sizeof(OS_STK);          /* Compute number of free bytes on the stack */p_stk_data->OSUsed = (size - nfree) * sizeof(OS_STK); /* Compute number of bytes used on the stack */return (OS_ERR_NONE);}

  对于需要检测的目标任务来说,需要采用OSTaskCreateExt()扩展任务来创建的,区别与普通的OSTaskCreate();函数,创建扩展任务不仅需要指定堆栈的底指针,还指定了堆栈的容量,这个容量值就是用来检验使用的,而该函数的最后一个参数opt 填入OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR即可。
OSTaskCreateExt ()源码:
INT8U  OSTaskCreateExt (void   (*task)(void *p_arg),void    *p_arg,OS_STK  *ptos,INT8U    prio,INT16U   id,OS_STK  *pbos,INT32U   stk_size,void    *pext,INT16U   opt){OS_STK    *psp;INT8U      err;#if OS_CRITICAL_METHOD == 3u                 /* Allocate storage for CPU status register               */OS_CPU_SR  cpu_sr = 0u;#endif#ifdef OS_SAFETY_CRITICAL_IEC61508if (OSSafetyCriticalStartFlag == OS_TRUE) {OS_SAFETY_CRITICAL_EXCEPTION();}#endif#if OS_ARG_CHK_EN > 0uif (prio > OS_LOWEST_PRIO) {             /* Make sure priority is within allowable range           */return (OS_ERR_PRIO_INVALID);}#endifOS_ENTER_CRITICAL();if (OSIntNesting > 0u) {                 /* Make sure we don't create the task from within an ISR  */OS_EXIT_CRITICAL();return (OS_ERR_TASK_CREATE_ISR);}if (OSTCBPrioTbl[prio] == (OS_TCB *)0) { /* Make sure task doesn't already exist at this priority  */OSTCBPrioTbl[prio] = OS_TCB_RESERVED;/* Reserve the priority to prevent others from doing ...  *//* ... the same thing until task is created.              */OS_EXIT_CRITICAL();#if (OS_TASK_STAT_STK_CHK_EN > 0u)OS_TaskStkClr(pbos, stk_size, opt);                    /* Clear the task stack (if needed)     */#endifpsp = OSTaskStkInit(task, p_arg, ptos, opt);           /* Initialize the task's stack          */err = OS_TCBInit(prio, psp, pbos, id, stk_size, pext, opt);if (err == OS_ERR_NONE) {if (OSRunning == OS_TRUE) {                        /* Find HPT if multitasking has started */OS_Sched();}} else {OS_ENTER_CRITICAL();OSTCBPrioTbl[prio] = (OS_TCB *)0;                  /* Make this priority avail. to others  */OS_EXIT_CRITICAL();}return (err);}OS_EXIT_CRITICAL();return (OS_ERR_PRIO_EXIST);}
  这就是uC/OS-II自带检验任务堆栈大小的方法,但是由于任务运行受实际产品使用状态等很多方面的影响,必须在任务最大运行负载的情况下所测出来的使用率才是最可靠的,一般为了防止堆栈过小,在RAM空间够用的时候,建议最后可以将实际测出来的大小*2进行堆栈分配。
---------------------
作者:forgot
链接:https://bbs.21ic.com/icview-3285474-1-1.html
来源:21ic.com
此文章已获得原创/原创奖标签,著作权归21ic所有,任何人未经允许禁止转载。


http://chatgpt.dhexx.cn/article/q3A1327U.shtml

相关文章

FreeRTOS-Task

Task FreeRTOS中Task为调度单位,是独立的运行实例,具有自己的堆栈空 间。Task通常是无限循环执行,不允许以任何方式退出实现函数(return 语句或者运行结束)。如果Task真的不需要了,需要显式的调用delete 函…

AUTOSAR OS Introduction -- Part 2(Task Property)

Event Event 主要用于为Extended Task 提供多个同步点,每个Event 可以关联多个Task Event Trigger condition 显示调用SetEvent通过Alarm TriggerCallback & OS API WaitEvent 只要表达式中任意一个EVENT 被收到,Task state则切换至Ready, 等待调度表按照优先级进行…

UCOS-Ⅲ查看任务堆栈空间:OSTaskStkChk()函数

UCOS-Ⅲ查看任务堆栈空间:OSTaskStkChk()函数 文章目录 前言一、准备工作二、使用步骤1.创建堆栈检测任务2.在头文件os_cfg.h开启宏OS_CFG_STAT_TASK_STK_CHK_EN3.在堆栈检测任务使用OSTaskStkChk()函数 三、结果 前言 硬件的RAM资源有限,UCOSⅢ提供了一…

【UCOSIII操作系统】任务篇(1)创建任务

UCOSIII操作系统 UCOSIII操作系统——任务篇(1)创建任务一、UCOSIII——任务 简介二、创建任务流程1、定义任务栈2、定义任务控制块TCB3、定义任务主体函数4、创建任务 三、任务的状态 UCOSIII其他内容导航不迷路 UCOSIII操作系统-简介 【UCOSIII操作系统…

FreeRTOS中taskENTER_CRITICAL()和taskEXIT_CRITICAL()函数运用

以下转载自安富莱电子: http://forum.armfly.com/forum.php 临界段 代码的临界段也称为临界区,一旦这部分代码开始执行,则不允许任何中断打断。为确保临界段代码 的执行不被中断,在进入临界段之前须关中断,而临界段代…

OSTaskCreateExt()建立任务

ucosII创建任务的硬性要求: 1.任务必须被创建在多任务启动前或运行的任务中 2.任务不能在ISR(中断)中创建 3.任务必须在死循环中,且不能有返回 OSTaskCreateExt()建立任务 NT8U OSTaskCreateExt (void (*task)(void *pd), …

赢在微点答案专区英语_英语u校园读写2答案unit3,u校园新标准大学英语视听说3单元测试答案搜题公众号...

英语u校园读写2答案unit3,u校园新标准大学英语视听说3单元测试答案搜题公众号,u校园大学英语读写4第一单元答案查题APP更多相关问题A.婴儿期 B.幼儿期 C.学龄前期 D.学龄期 E.青春期关于自我,正确的说法是(…

新视野大学英语视听说第三版答案

Unit 1 Unit 2 Unit 3 Unit 4 Unit 5 Unit 6 Unit 7 Unit 8

视听说教程(第三版)4 quiz 1

视听说教程(第三版)4 quiz 1 Reading Comprehension Section A Passage One Questions 1 to 5 are based on the following passage. We all want to raise kids who are happy and successful, but we often mistakenly think that money is the key …

welearn 视听说1-4

词汇题(55道) 1. You should carefully think over_____ the manager said at the meeting. A. that B. which C. what D. whose 1.选C,考察宾语从句连接词,主句谓语动词think over后面缺宾语,后面的宾语从句谓语动…

使用RemObjects Pascal Script

摘自RemObjects Wiki 本文提供RemObjects Pascal Script的整体概要并演示如何创建一些简单的脚本. Pascal Script包括两个不同部分: 编译器 (uPSCompiler.pas)运行时 (uPSRuntime.pas) 两部分彼此独立.可以分开使用,或通过TPSScript 控件使用他们,这个控件定义在uPSComponent.p…

搭建一个简单的Pascal脚本开发环境

使用innosetup进行打包,涉及到需要编写一些Pascal脚本,所以了解了下Pascal的相关语法。 这里主要介绍如何搭建一个简单的Pascal开发环境。 一、Free Pascal Free Pascal(全称 FPK Pascal)是一个32位和64位专业Pascal编译器。它…

pascal编程语言介绍

Pascal是一种过程式编程语言,由Niklaus Wirth于1968年设计并于1970年发布,并以法国数学家和哲学家Blaise Pascal的名字命名。Pascal可以运行在多种平台上,例如Windows、Mac OS和各种版本的UNIX/Linux。[3] 软件名称 Pascal 软件平台 Windows、…

Free Pascal IDE安装

1. Free Pascal IDE 安装 首先,去 https://www.freepascal.org/download.var 下载Free Pascal IDE。我选择的sourceforge镜像 fpc-3.0.2.i386-win32.exe,下载比较慢,请耐心等待。下载完成后,双击exe文件进行安装&#xf…

[pascal入门]数组

一、本节目标 本节我们将要讲述数组。本节目标: 一维数组二维数组字符数组 二、一维数组 我们通过一个案例来简单的理解数组。班主任要计算班级里面50个同学数学成绩的平均成绩,道理上讲这是一个比较简单的问题,只需要把每个人的成绩加起来除…

linux的pascal语言,pascal语言视频教程 Linux GCC常用命令详解

GCC 的意思也只是 GNU C Compiler 而已。经过了这么多年的发展,GCC 已经不仅仅能支持 C 语言;它现在还支持 Ada 语言、C 语言、Java 语言、Objective C 语言、Pascal 语言、COBOL语言,以及支持函数式编程和逻辑编程的 Mercury 语言&#xff0…

vscode 配置 pascal环境

vscode 配置 pascal环境 网上关于配置pascal的教程不太多,我试验了好几个,都没搞对,其中有很多原因吧,最后从较多、较熟悉的c环境开始配置理解,才算是慢慢懂得了这个配置过程,前前后后大概花一个星期&…

信息学竞赛 c语言 pascal,pascal信息学竞赛教程

第一讲: 信息学竞赛讲座:预备知识 计算机语言是计算机软件中非常独特的一部份,它属于系统软件,但又和应用软件息息相关。它的作用是:使人类能够用某些命令、指令去让计算机为人类进行数值、逻辑运算。计算机语言中,只有一种语言是…

Pascal基础教程

第一课 初识Pascal语言 信息学奥林匹克竞赛是一项益智性的竞赛活动,核心是考查选手的智力和使用计算机解题的能力。选手首先应针对竞赛中题目的要求构建数学模型,进而构造出计算机可以接受的算法,之后要写出高级语言程序,上机调试…

【通用学术英语视听说答案】

通用学术英语视听说答案–主编郎曼、侯霞