请选择 进入手机版 | 继续访问电脑版

EDABOSS电子论坛

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 654|回复: 0

[转帖] uC/OS-II学习笔记—任务堆栈

[复制链接]

9

主题

0

回帖

51

E币

技术员

Rank: 2

积分
18
发表于 2019-9-17 08:31:53 | 显示全部楼层 |阅读模式
所谓堆栈,就是在存储器中按数据“后进先出(Last In First Out, LIFO)”的原则组织的连续存储空间。因此,堆栈这种数据结构最大的特点就是最后进去的最先出来。这就像我们向箱子中放书,箱子的底面积刚好和书相同,那么先放进箱子中的书很明显只能最后出来。为了满足任务切换或响应中断时保存CPU寄存器中的内容,以及存储任务私有数据的需要,每个任务都有自己的堆栈。当任务进行切换的时候,将CPU寄存器的内容压入堆栈,恢复的时候再弹出来给CPU寄存器。任务堆栈是任务的重要组成部分,关于任务堆栈在操作系统代码中的定义如下所示:

004517ozieiedf0tjecfkb.jpg
004517dshivahqjastyqgk.jpg
004518bb84t1n8e4631it8.jpg

TASK_STK_SIZE是每个任务堆栈的大小,这里设置为512,根据具体情况做移植时,可修改这个值。OS_MAX_TASKS是用户任务的数量。OS_STK是堆栈的数据类型,使用typedef来定义,等同于无符号的整数,在32位的PC系统中,为32位的无符号整数。如果需要移植到其他系统,就要根据需要进行更改。很明显,这里我们定义了最多用户任务数个堆栈,而统计任务和空闲任务的堆栈是单独定义的,分别是OSTaskStatStk和OSTaskIdleStk,如下所示:

004518r6jccxu75ek25m2x.jpg
004519kabztx58b5jxsej5.jpg

OS_STK是32位的,所以执行一次压栈操作,就要压进去4个字节;执行一次退栈操作,就弹出4个字节。而堆栈的大小就是TASK_STK_SIZE个OS_STK,而非TASK_STK_SIZE。这里TASK_STK_SIZE是512,那么就是512*sizeof(OS_STK),为2048个字节。
TaskStk就是我们定义的堆栈,这里是以数组的形式定义的,每个堆栈的尺寸是512个字节,而一共定义了OS_MAX_TASKS个这样的堆栈。需要注意的是用户堆栈可以由用户自己定义,并非一定要采用二维数组的形式。
任务堆栈有四种:满递减堆栈,空递减堆栈,满递增堆栈,空递增堆栈。作为一个嵌入式操作系统应该可以移植到不同的平台,因此必须兼容这四种模式。

004521n8m8ugmucr28m0uh.png

如上所示是STM32F407的编程手册中的一段,从中可以很清楚的看到,STM32F407采用的是满递减堆栈。

004515gbafz9dtcdd9fasi.png

假如堆栈的初始状态如上图所示,那么向堆栈中压入一个数据后的堆栈如下图所示:

004516r3ea97m866me9aum.png

如果一个任务的任务堆栈如上图所示,那么它的定义大概就应该如下所示:
OS_STK Task1Stk[10];
这样,这个堆栈就有Task1Stk[0]~Task1Stk[9]这样十个堆栈空间。那么初始状态SP应该指向&Task1Stk[9]+1,然后向堆栈中压入第一个数据,首先,SP向下移动一个堆栈空间,然后将数据存入这个堆栈空间。也就是说存储到Task1Stk[9]中。如果再存储一个数据,那么,同样的,再执行一次上面的动作,将数据存入到Task1Stk[8]中。Task1Stk[9]为栈顶,Task1Stk[0]为栈底。
OSTCBStkPtr就是指向堆栈栈顶的指针,OSTCBStkBottom是指向堆栈栈底的指针,OSTCBStkSize是堆栈的大小。如果OSTCBStkPtr与OSTCBStkBottom相等了,那么说明堆栈已经满了。OSTCBStkSize是用于做堆栈检查的。
积分规则
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|EDABOSS电子论坛

GMT+8, 2024-4-18 11:12 , Processed in 0.042758 second(s), 23 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表