第一,当任务运行时,它用来保存一些局部变量;
第二,当任务挂起时,它负责保存任务的运行现场,也就是CPU寄存器的值。

uCOS任务堆栈的深入分析(转)

堆栈作用的就是用来保存局部变量,从本质上讲也就是将CPU寄存器的值保存到RAM中。在uCOS中,每一个任务都有一个独立的任务堆栈。为了深入理解任务堆栈的作用,不妨分析任务从“出生”到“消亡”的整个过程,具体就是分析任务的建立,运行,挂起几种状态中任务堆栈的变化情况。

现在假设系统运行着一个由用户创建的用以完成打印工作的任务TPrint。TPrint最初通过OSTaskCreate()函数创建,在该函数中与任务堆栈有关的第一段代码是大家比较熟悉的函数OSTaskStkInit(),这个函数是在uCOS移植过程中必须实现的,其作用是“初始化堆栈”,其实就是预先在RAM中的一块区域中把任务将来运行开始时CPU寄存器应处的状态(正确值)准备好,之后,任务第一次被内核调度器调度运行时,将这些准备好的数据(寄存器的值)推到CPU的寄存器中,如果数据设计的合理,CPU便会按照我们预先设计好的思路运行。所以,“初始化堆栈”实际上是做了一个“未雨绸缪”的工作。这个过程中有两点是必须慎重考虑的,一是PC该如何定位,二是CPU的其它寄存器(除PC之外)该怎么处理。先说第一点,因为任务是第一次运行,而任务从本质上将就是一段代码,所以PC指针应该定位到这段代码的第一行处,即所谓的入口地址(Entry Point)处,这个地址由任务指针保存着,所以把该指针值赋给PC即可。第二,这段代码还未被执行过,所以代码中的变量与CPU的其它寄存器一点关系也没有,因此R0-R12,R14可随便给值,或者不赋值也可,让这些寄存器保持原来的值,显然后者更为简单。最后再给CPSR赋值,用户可以根据实际需要使系统运行于系统模式或管理模式。经过入栈和出栈,此时SP指向任务堆栈的最底端(就是已经定义好的任务堆栈数组的最后一个元素)。

之后任务代码开始正式运行,因为CPU的寄存器是有限的,所以在运行时不可避免地要把一些临时变量暂时保存到堆栈中。具体应保存到哪个地址呢,不用担心,SP知道(任务第一次运行时,这个地址就是任务堆栈数组的最后一个元素的地址)。任务堆栈的大小和任务代码中临时变量的数目有关,如果这段代码临变量特别多,堆栈就应设计的大一些。

然后,TPrint任务由于某种原因将要被挂起,所以应把任务的运行现场放到堆栈里保护起来,TPrint任务再次运行时再把这个现场还原,任务就能从上次断点处紧接着运行。那么,这个现场是什么呢?从本质上讲,TPrint任务的运行过程就是CPU在执行一段特定的代码,所以这个现场就是CPU的现场,也就是寄存器的值。这些寄存器的值包含了代码执行时的所有信息,包括当前运行到了这段代码的哪个位置处(由PC值指明)。因此,把CPU的寄存器的值推入堆栈,然后记住栈顶指针的位置(SP由OSTCBCur->OSTCBStkPtr保存),当任务再次将要运行前,从SP指向的地址处依次把先前保存的CPU寄存器的值放到CPU的寄存器中,任务就可以从上次中断的地方准确无误地执行。这个过程就像突然把任务冻结了,与任务有关的任何东西都不能动了,一段时间之后又把任务解冻,与它有关的东西又变得可用,于是任务又可以活蹦乱跳地跑起来了。

从以上分析可以看出,任务堆栈至始至终伴随着任务,与之生死与共,它的作用可以概括为两点:第一,当任务运行时,它用来保存一些局部变量;第二,当任务挂起时,它负责保存任务的运行现场,也就是CPU寄存器的值。有些朋友正是忽视了第一点,产生了“任务堆栈大小应是固定值的疑问”。我感觉,这可能与对函数OSTaskStkInit()的理解有关,我们都称之为堆栈初始化函数,但此处的“初始化”与我们理解的初始化不太一样,平时讲的(变量的)初始化似乎指的是将变量的所有成员都一一初始化。而此处的堆栈的初始化仅仅是初始化了很大一个堆栈的一小部分,因为当前只有这部分是有用的,而剩余的大部分用不到,所以不用初始化,就像有些变量不用初始化一样(有默认值或随机值)。更深入一点考虑,当任务挂起时,任务堆栈中保存任务挂起前CPU寄存器的这一连续的区域肯定在整个堆栈的最上面;当任务重新开始运行时,SP弹出寄存器的值,这段区域变成空白的区域。而且,任务每次挂起前用来保存当前CPU寄存器这一连续区域在整个任务堆栈空间中是浮动的

ucosii任务堆栈的作用是什么呢?相关推荐

  1. 深入分析MCU堆栈的作用,以及该如何设置堆栈大小

    置顶/星标公众号,不错过每一条消息 前段时间分享文章<从嵌入式编程中感悟「栈」为何方神圣?>之后,很多朋友问了关于堆栈的问题.今天就写点相关内容,让大家进一步了解堆栈的知识. 1写在前面 ...

  2. 51单片机中断的调用寄存器组(PSW)的作用,以及汇编堆栈的作用,堆栈指针的SP的使用方法,RAM的运行和ROM在单片机具体运行和C语言的优势和中断,定时器基础知识(上)

    一,堆栈在汇编的作用,以及PUSH ACC 和 PUSH PSW 通过最简单的8051单片机RAM的分配可知,单片机从烧程序到达到一定的工作过程.首先明白为什么要引如"烧"写的过程 ...

  3. 出问题 初始化ucosiii_STM32 ucosii 双堆栈初始化问题

    MSP 可以不用初始化.系统硬件自动搞定了. PSP 初始化为0,是用来区别,是不是第一次切换任务, 因为第一次切换任务,无上一次任务来保存.不然,要保存上一个任务到栈. PendSV_Handler ...

  4. 【Android 应用开发】Android 返回堆栈 与 任务

    文章目录 I . 返回堆栈 概念 II . 返回堆栈 运行机制 III . 任务 I . 返回堆栈 概念 返回堆栈概念 : ① 任务 : Android 中的任务就是 Android 应用 与 用户进 ...

  5. uCOS任务堆栈的深入分析(转)

    堆栈作用的就是用来保存局部变量,从本质上讲也就是将CPU寄存器的值保存到RAM中.在uCOS中,每一个任务都有一个独立的任务堆栈.为了深入理解任务堆栈的作用,不妨分析任务从"出生" ...

  6. 数据结构之线性结构之堆栈

    二,堆栈 中缀表达式:运算符位于两数之后: a+b*c-d/e 后缀表达式:运算符位于两数之后: abc*+de/-:计算机表示式求解时的读法:用堆栈实现计算 前缀表达式:运算符位于两数之前: -+a ...

  7. java堆栈类在哪个包里_Java堆栈Stack类的使用

    栈的官方概念 栈是java存放内存的两种结构之一.栈是限定仅在表尾进行插入或删除操作的线形表. 通俗的讲,往栈里面存数据,就是先进后出.最先存入的数据在最底部,取出的时候最后被取出.可以理解为吃饱了就 ...

  8. UCOS III 任务堆栈理解

    UCOS III在创建任务时,调用OSTaskStkInit函数,以初始化正在创建的任务的堆栈框架. 1:堆栈就是一段连续的空间.用于存储数据的,在c计算机中有很多应用,比如发生中断时保存现场,c语言 ...

  9. 堆栈的概念————————ARM微控制器与嵌入式系统(清华大学慕课记录)

    堆栈.堆.栈的概念 堆:堆可以被看成是一棵树.堆是在程序运行时,申请某个大小的存储空间.即动态分配内存,对其访问和对一般内存的访问没有区别. 栈:栈是一种运算受限的线性表.仅允许在栈的一端进行插入和删 ...

最新文章

  1. Variable和Tensor合并后,PyTorch的代码要怎么改?
  2. 计算概论c和文科计算机,计算概论与计算机程序设计基础/C语言【理工学社】
  3. Codeforces987F AND Graph
  4. 阿里云力夺FewCLUE榜首!知识融入预训练+小样本学习的实战解析
  5. 解决android扫描二维码时,用户禁止权限报错问题
  6. elementui常用知识点总结
  7. Linux驱动程序的数据封装
  8. mysql封装执行_解决Mysql封装类执行报错——Mysql::insert() should not be called
  9. QString 字符编码
  10. 新版JupyterLab快捷键+调试技巧(建议收藏)
  11. osea/ 5.0-6.0
  12. 计算机设备问题代码43,双击unknown device由于该设备有问题Windows已将其停止(代码 43)怎么办解决教程...
  13. 手机远程访问HTML5,如何使用手机连接远程桌面?
  14. 揭露狂拽炫酷吊炸天,靠抄袭起家的非主流崇才科技
  15. Typora设置高亮
  16. WPF开发之dll文件创建与调用
  17. 当下社会和经济形势概述
  18. 中国特种腈行业市场供需与战略研究报告
  19. 双系统下卸载Ubuntu方法
  20. 机器学习之随机森林填补缺失值和众数填补缺失值

热门文章

  1. tkinter 类继承的三种方式
  2. Webdriver使用Chrome模拟手机浏览器测试移动版网站
  3. easy js test--方便对js进行测试,不需要刷新
  4. Nginx1.0.9配置虚拟主机
  5. myqsl cluster error code 2310
  6. (转)NSIS使用心得
  7. [转]ReiserFS与ext3的比较
  8. linux deliver分发管理,Erlang/Elixir: 使用 Edeliver 进行自动化的持续部署
  9. python语言有哪些类型的运算符_python(4)-变量 数据类型和运算符
  10. Tomcat启动设置环境变量