📄 ——uc-os-ii任务栈处理的一种改进方法.htm
字号:
style="TEXT-INDENT: 30px">假定任务1首次运行时任务栈为空。运行一段时间后任务2运行,堆栈空间继续往上生长。这次任务切换不需要修改CPU的SP数值,但需要记下任务1的栈顶位置SP1(图3中)。</P>
<P
style="TEXT-INDENT: 30px">在任务2运行一段时间后,RTOS又切换到任务1运行。在切换时,不能简单地将SP指针修改回SP1的数值,因为这样堆栈向上生长时会破坏任务2堆栈中的数据。办法是将原来任1务堆栈保存的数据移动到靠栈顶的位置,而将任务2堆栈数据下移到靠栈底的位置,堆栈指针SP实际上不需要修改(图3右)。</P>
<P
style="TEXT-INDENT: 30px">考虑到更为一般的情况,有N个任务,当前运行的任务为k,下一个运行的任务为j,在共用任务堆栈时必须做的工作有:</P>
<P style="TEXT-INDENT: 30px">*为每个任务定义栈顶和栈底2个堆栈指针;</P>
<P
style="TEXT-INDENT: 30px">*在任务切换时,将待运行任务j的堆栈内容移动到靠栈顶位置,同时将其堆栈上方的任务堆栈下移,修改被移动推栈的任务堆栈指针。</P>
<P style="TEXT-INDENT: 30px">假设我们定义的任务栈空间和任务的栈指针变量为:</P>
<P style="TEXT-INDENT: 30px">void
TaskSTK[MAX_STK_LEN];/*任务堆栈空间*/</P>
<P style="TEXT-INDENT: 30px">typedef struct TaskSTKPoint{</P>
<P style="TEXT-INDENT: 30px">int TaskID;</P>
<P style="TEXT-INDENT: 30px">int pTopSTK;</P>
<P style="TEXT-INDENT: 30px">int pBottomSTK;</P>
<P style="TEXT-INDENT: 30px">}TASK_STK_POINT;</P>
<P style="TEXT-INDENT: 30px">TASK_STK_POINT pTaskSTK[MAX_TASK_NUM];
/*存放每个任务的栈顶和栈底指针*/</P>
<P
style="TEXT-INDENT: 30px">任务栈指针数组pTaskSTK的元素个数同任务个数。为了堆栈交换,需要另外一块临时存储空间,其大小可按单个任务栈最大长度定义,用于中转堆栈交换的内容。堆栈内容交换的伪C算法可写为:</P>
<P style="TEXT-INDENT: 30px">StkEechange(int CurTaskID,int
RunTaskID)</P>
<P style="TEXT-INDENT: 30px">{ /*2个参数为当前运行任务号和下一运行任务号*/</P>
<P style="TEXT-INDENT: 30px">void TempSTK[MAX_PER_STK_LEN];
/*注意该变量长度可小于TaskSTK*/</P>
<P style="TEXT-INDENT: 30px">L=任务RunTaskTD的堆栈长度;</P>
<P style="TEXT-INDENT: 30px">①将TaskSTK顶部的L字节移动到TempSTK中;</P>
<P style="TEXT-INDENT: 30px">②将RunTaskID任务的堆栈内容移动到TaskSTK顶部;</P>
<P style="TEXT-INDENT: 30px">③将RunTaskID堆栈上方(移动前位置)所有内容下移L个字节;</P>
<P
style="TEXT-INDENT: 30px">④修改RunTask堆栈上方(移动前位置)所有任务栈顶和栈底指针(pTaskSTK变量);</P>
<P style="TEXT-INDENT: 30px">};<IMG height=268 hspace=1
src="——uC-OS-II任务栈处理的一种改进方法.files/5c.gif" width=377 align=right
vspace=1 border=0></P>
<P style="TEXT-INDENT: 30px">该算法的平均时间复杂度可计算如下:</P>
<P style="TEXT-INDENT: 30px">O(T)=SL/2+SL/2+SL×N/2</P>
<P
style="TEXT-INDENT: 30px">式中,第一、二项为步骤①和步骤②时间,第三项为步骤③时间;SL表示每个任堆栈的最大长度(即MAX_PER_STK_LEN),N表示任务数。</P>
<P
style="TEXT-INDENT: 30px">取SL为64字节,任务数为16个,则数据项平均移动次数为576。假设每次移动指令时间为2μs,则一次任务栈移动时间长达约1ms。所以在使用该方法时,为了执行时间尽量短,编码时应仔细推敲。</P>
<P
style="TEXT-INDENT: 30px">从空间上说,共用任务栈比独立任务栈优越。假设独立任务栈方法中每个堆栈空间为K,任务数为N,则独立任务栈方式的堆栈总空间为N×K。在共用任务栈时,考虑各任务互补的情况,TaskSTK变量不需要定义为N×K长度,可能定义为二分之一或者更小就可以了。</P>
<P style="TEXT-INDENT: 30px">另外,这种方法不需要在任务切换时修改CPU的SP指针。</P>
<P style="TEXT-INDENT: 30px">(2)工作栈和任务堆栈</P>
<P
style="TEXT-INDENT: 30px">上节共用任务栈算法的缺点是:任务切换时的堆栈内容交换算法复杂,占用时间长。另外一个折中的方法是设计一个工作堆栈,用于给当前运行的任务使用;在任务切换时,将工作栈内容换出得另外的存储空间,该空间可以动态申请,其大小按实际需要即可。</P>
<P
style="TEXT-INDENT: 30px">这种方法看起来和独立任务栈的方法类似,需要N+1块存储空间,其中一块用于工作栈空间。和独立任务堆栈相比,其区别有2点:</P>
<P style="TEXT-INDENT: 30px">①SP指针所指向的空间始终是同一块存储空间,即工作栈;</P>
<P
style="TEXT-INDENT: 30px">②每个任务栈的大小不需要按最大空间定义,可以动态按实际大小从内存中分配空间。</P>
<P
style="TEXT-INDENT: 30px">对于8031这种处理器结构,由于堆栈指针只能指向其内部存储器,大小十分有限。采取这种方法,可将工作栈设在内部RAM,将任务栈设在外部RAM,扩展了堆栈空间。</P>
<P
style="TEXT-INDENT: 30px">和上一种共用堆栈方法相比,这种方法的交换时间要短,其时间复杂度约为1.5倍最大任务栈长度。</P>
<P style="TEXT-INDENT: 0px"><B>5 总结</B></P>
<P
style="TEXT-INDENT: 30px">独立任务栈的方法适合于存储器充足、任务切换频繁、对任务切换时间要求较高的场合,一般主要用在16位或者32位微处理器平台环境。值得注意的是,在某些微处理器中,虽然可使用的数据存储器可以设计得较大,但堆栈所能使用的存储器却是有限的。比如8031系列存储器,堆栈只能使用内部的128字节数据存储器,即使系统中有64K字节的外部数据存储器,任务栈的总空间也不能超过128字节。这种处理器使用共用任务栈结构的RTOS就更好一些。</P>
<P
style="TEXT-INDENT: 30px">由于共用任务栈系统需要较长的任务切换时间,不适于任务切换频繁的场合,在很多嵌入式系统中,长时间只有几个任务会处于运行状态,其它任务在特定的条件下才会运行。对于RTOS的使用者,也可以适当地划分任务,来减小任务切换的时间。</P>
<P
style="TEXT-INDENT: 30px">无论使用哪种方法,在存储空间有限时,任务栈的长度应仔细计算。计算的根据是任务中的函数嵌套数、函数局部变量长度。对于共用任务栈,还要考虑同时运行态和挂起态的最大任务数。一些编译器可以生成堆栈溢出检查代码,在调试时可将该编译开关打开,以测试需要的实际堆栈长度。
</SPAN></P>
<P></P></DIV></TD></TR>
<TR>
<TD align=middle height=15>
<TABLE cellSpacing=0 cellPadding=0 align=center border=0>
<TBODY>
<TR>
<TD>
<DIV></DIV></TD></TR></TBODY></TABLE></TD></TR>
<TR>
<TD align=right height=2>
<TABLE cellSpacing=0 cellPadding=0 width="80%" border=0>
<TBODY>
<TR>
<TD width=75>【<A href="javascript:doPrint();">打印本稿</A>】</TD>
<TD width=8></TD>
<TD width=75>
<P>【<A
href="http://www.21ic.com/new_info/news/review.asp?title=uC/OS-II任务栈处理的一种改进方法target="
_blank?>发表评论</A>】</P></TD>
<TD width=10></TD>
<TD width=79>【<A
href="http://www.21ic.com/new_info/news/sendmail.asp?num=uC/OS-II任务栈处理的一种改进方法">推荐</A>】</TD></TR></TBODY></TABLE></TD></TR>
<TR>
<TD align=right height=2></TD></TR>
<TR>
<TD align=right height=2><A href="javascript:window.close();"><IMG
height=20 src="——uC-OS-II任务栈处理的一种改进方法.files/close_c.gif" width=77
border=0 name=Image161></A><FONT
color=#ffffff>----</FONT></TD></TR></TBODY></TABLE><BR><BR>
<TABLE cellSpacing=0 cellPadding=0 width=520 align=center border=0>
<TBODY>
<TR>
<TD vAlign=bottom align=middle width=114 bgColor=#999a76
height=1><IMG height=1 src="——uC-OS-II任务栈处理的一种改进方法.files/blank.gif"
width=1></TD>
<TD width=466 height=1></TD></TR>
<TR>
<TD align=middle width=114 bgColor=#ece8db height=19>相关新闻</TD>
<TD width=466 height=19></TD></TR>
<TR bgColor=#999a76>
<TD colSpan=2 height=1><IMG height=1
src="——uC-OS-II任务栈处理的一种改进方法.files/blank.gif" width=1></TD></TR>
<TR>
<TD colSpan=2 height=1></TD></TR></TBODY></TABLE>
<TABLE borderColor=#000000 cellSpacing=0 cellPadding=0 width=520
align=center border=0>
<TBODY>
<TR>
<TD vAlign=top>
<TABLE class=RelatedTable width="100%" border=0>
<TBODY>
<TR class=RelatedTr>
<TD class=RelatedTd>
<SCRIPT language=javascript
src="——uC-OS-II任务栈处理的一种改进方法.files/about.htm"></SCRIPT>
</TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR></TD>
<TD vAlign=top align=middle width=150 bgColor=#ece8db height=2>
<TABLE cellSpacing=0 cellPadding=1 width="100%" border=0>
<TBODY>
<TR>
<TD bgColor=#000000>
<TABLE cellSpacing=0 cellPadding=2 width=150 bgColor=#ece8db
border=0>
<TBODY>
<TR>
<TD>
<META content="Microsoft FrontPage 5.0" name=GENERATOR>
<META content=FrontPage.Editor.Document name=ProgId><BR><A
href="http://www.hhcn.com/chinese/cnindex.html"
target=blank>华恒<BR>(ARM,PowerPC,冷火,龙珠)</A><BR><A
href="http://www.embedon.com/" target=blank>远峰</A> <BR><A
href="http://www.21ic.com/custom/jhb/index.htm"
target=blank>复旦金海博</A><BR><A
href="http://www.emdoor.com/index.asp"
target=blank>亿道</A><BR><BR>单片机 <BR><BR><A
href="http://www.hk.renesas.com/"
target=blank>Renesas</A><BR><A
href="http://www.zlgmcu.com/tools/kaifaban.asp"
target=blank>周立功 Philips</A> <BR><A
href="http://www.strong-ic.com/" target=blank>胜创特</A> <BR><A
href="http://www.holtek.com.tw/" target=blank>盛群 Holtek</A>
<BR><A href="http://www.xhl.com.cn/"
target=blank>Cygnal单片机</A><BR><A href="http://www.lierda.com/"
target=blank>利尔达MSP430</A> <BR><BR>接口电路:<BR><BR><A
href="http://www.whjmw.com/" target=blank>金迈威</A> <BR><A
href="http://www.21ic.com/custom/maiwei/mw.htm"
target=blank>迈威</A> <BR><A href="http://www.rs232.net.cn/"
target=blank>瑞赛特</A><BR><BR><BR>存储器<BR><A
href="http://www.huazhoucn.com/"
target=blank>铁电存储器免费样品</A><BR><BR><BR>模拟器件<BR><A
href="http://www.unique-ap.com.cn/"
target=blank>Linear</A><BR><BR><BR>编程器<BR><A
href="http://www.xeltek.com.cn/"
target=blank>西尔特编程器</A><BR></TD></TR>
<TR>
<TD
height=5></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width=766 align=center border=0>
<TBODY>
<TR>
<TD vAlign=top colSpan=6></TD></TR>
<TR>
<TD vAlign=top colSpan=6 height=10></TD></TR>
<TR>
<TD vAlign=top bgColor=#999999 colSpan=6 height=2></TD></TR>
<TR>
<TD class=stxt vAlign=center align=middle colSpan=6
height=6></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width=766 align=center border=0>
<TBODY>
<TR>
<TD class=s width=973 height=12></TD></TR>
<TR>
<TD class=s width=973 height=20>
<DIV align=center><FONT face="Arial, Helvetica, sans-serif"><!--start copyright-->
<DIV align=center><FONT color=black>
<TABLE cellSpacing=0 cellPadding=0 width=600 align=center border=0>
<TBODY>
<TR>
<TD align=middle width="100%" colSpan=2><BR>Better View:800*600 Best
View:1024x768 为了本系统能够更好的为您服务,请使用IE4.0或以上版本浏览器
<BR><BR>版权所有(C)21IC中国电子网 电话:010-82357510, 82357511 传真: 010-82357512
</TD></TR></TBODY></TABLE><!--start copyright--></FONT></DIV></FONT></DIV></TD></TR></TBODY></TABLE><BR></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -