本帖最后由 冷漠 于 2010-7-22 09:19 编辑
……中断可能引发任务切换。当一个进程被中断时,该进程的进程表项中将建立一个堆栈,再次启动该进程所需的全部信息都放在这个新堆栈上。通过以下操作可以再次启动任何一个进程:将栈指针指向其进程表项,然后执行一个指令序列来恢复CPU寄存器值,最后以一条iretd指令结束。调度程序决定堆栈指向哪个进程表项。
内核本身在运行时也可能发生中断。CPU检测到中断后将使用内核栈,而不是进程表中的堆栈。这样便允许中断嵌套。当后来的中断服务例程结束后,在它之前执行的中断服务例程就可以运行直到结束。在所有中断都被处理之后则可以重启动一个进程。
——摘自William Stallings《操作系统——内核与设计原理》(第四版)
51操作系统正是这样运行的。
看看一个51多任务操作系统中有几个(私有)堆栈?以及它们如何运行操作的:
51多任务操作系统中,每个任务都可以享有一个公有堆栈和一个私有堆栈,当该任务处于运行态时,它使用的是公用(动态)堆栈 SP 。就是人们习惯认为的那个51内部只有的唯一的堆栈; 呵,只有SP所指向的堆栈才是公有堆栈区。
当一个运行态任务被迫进入阻塞态或者转换进入就绪态时,它都带有一个(退出活动态时)系统为自己建立的那个静态新堆栈(私有);——它存放着该任务被再次启动(进入运行态)所需要的全部信息。
呵,静态堆栈是非SP指向,所以称它为私有以和公有对应。
例如一个没有外部XDATA配置的 8031,其128字节的DATA空间内可以建立15个任务,每任务具有一个私有堆栈!见图1:
显然,系统任务越多,私有堆栈占用DATA 越多,留下的公有堆栈深度越小。
杨屹老师曾经写了一个uC/OS到51的移植程序,见任哲编著的《 嵌入式实时操作系统uC/OS II 原理及应用 》P186:
由于51系列单片机的片内RAM 极其有限,所以就只能把应用程序中各个任务堆栈的内容放在片外RAM中,而只在片内RAM中设置一个公有的堆栈。
如果把片外RAM中用来存放任务堆栈内容的区域叫做任务堆栈映像,而片内RAM中的公用堆栈叫做系统堆栈,那么……
老师的方法是把中止运行态的当前任务堆栈全部换出到XDATA段,使得尽可能多的内部RAM做公有系统堆栈,这就叫做以时间换空间吧。
呵呵,系统,公有,私有,映像,各自叫法不同而已。没有硬性规定。还有静态、动态,这些操作系统概念,中文怎么翻译才算标准,还没出炉;读者自己明白就行了。
|