ucos-ii移植之任务堆栈的分析

在讨论任务堆栈之前,要先说说在程序中栈的用途。栈在程序运行过程中起着很重要的作用。
它有如下的几个作用:
1.保存函数的执行路径信息。
2.保存函数执行时的CPU上下文。
3.传递参数。
4.为临时变量分配空间。
在ucos-ii中任务堆栈的作用也是以上这几个。由此可见要想成功将ucos移植到51单片机上。就要使得任务堆栈的功能不受到影响。
ucos-ii的任务堆栈是在程序编写时显式的通过数组定义来开辟的空间。在ram不紧张的处理器重,只要改变sp的值就可以在不同的任务堆栈中进行相应的切换。但是在8051这个平台这却不是一件很容易的事情。keil为了充分利用空间,采用了局部变量覆盖的技术。造成了函数不可重入的问题。为了解决这个问题,keil又采用了模拟堆栈的方式来补救。
     模拟堆栈其实很简单,就是在程序中声明一个全局变量,作为模拟堆栈的栈顶指针。这个模拟堆栈可以用来进行参数的传递以及临时变量空间的分配。由此可见模拟栈满足了一般栈的第3和第4个功能。第1和第2个功能还是由硬件堆栈承担的。因此在移植ucos的时候在处理任务堆栈的时候还是需要用到硬件堆栈。我们使用硬件堆栈来保存函数的执行路径信息。所谓执行路径就是函数调用的历史,在使用了模拟堆栈的情况下,栈中保存的都是函数的返回地址。
     使用硬件堆栈,我们能够满足普通栈的第1个功能。由于在ucos中存在着许多个共享硬件堆栈的任务,因此在任务切换的过程中,前一个任务使用的硬件堆栈的内容应该保存起来,然后再用将一个任务的任务堆栈中保存着的硬件堆栈的信息填充到硬件堆栈中。这样就能够实现任务上下文的切换。采用了这样的处理方式,就引出了另外一个问题,怎么知道硬件堆栈中有多少内容呢。对于硬件堆栈。在程序的开始就要指定sp的内容。在将硬件堆栈的内容移出时,当SP的值等于sp的初始值的时候就停止。在移出的过程中对压栈的次数进行计数,最后压入模拟堆栈之中。这样就能实现堆栈内容的完全复制。这个过程是不能被打断的。
     以上的讨论我们还有第2个功能没有满足,保存函数执行时CPU的上下文。CPU的执行上下文,就是各个寄存器的值。在任务进行切换的过程中,可以将所有寄存器的值都压入模拟堆栈,再将硬件堆栈的内容压入,最后压入对硬件堆栈内容保存时压栈的次数。
    至此,普通堆栈的所有功能都满足了,我们对在ucos移植过程中任务堆栈的处理这一问题也有了初步的解决方案。这个方案可能会延长中断响应时间,广大网友可以提出更好的思路,我们集思广益。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值