hacker9 发表于 2011-11-14 11:08:22

简易OS多任务是怎样切换的?

看了论坛里那个简易OS,对任务切换有些不理解,自己写了一个类似的,但不保存SP,这样三个任务会不停循环执行,任务函数也不用死循环了。
首先,如果哪位能解释这个任务切换是怎样实现的,请直接给我解释一下,谢谢了。

这是我写的代码
#include<reg52.h>
unsigned int task_sp;
unsigned char task_stack;
unsigned char task_id=0,i=0;
void task_switch()
{
// task_sp=SP;
if(task_id==2)task_id=0;
else task_id++;
SP=task_sp;       
}
void task1()
{
i++;
task_switch();
}
void task2()
{
i++;
task_switch();
}
void task3()
{
i++;
task_switch();
}
void task_init()
{
task_stack=(unsigned int)task1 & 0xff;
task_stack=(unsigned int)task1 >> 8;
task_sp=task_stack+1;
task_stack=(unsigned int)task2 & 0xff;
task_stack=(unsigned int)task2 >> 8;
task_sp=task_stack+1;
task_stack=(unsigned int)task3 & 0xff;
task_stack=(unsigned int)task3 >> 8;
task_sp=task_stack+1;          
}
void os_start(tid) {task_id = tid,SP = task_sp;return;}
void main()
{
task_init();
os_start(0);
}
对于task_sp=task_stack+1;这一句,根据书上说的,就是把task_stack里的值赋给task_sp,但实际上仿真时的结果是这样的
http://cache.amobbs.com/bbs_upload782111/files_47/ourdev_694996QKXH5N.jpg
(原文件名:未命名.jpg)

里面的0x14是什么??地址?
http://cache.amobbs.com/bbs_upload782111/files_47/ourdev_694997XX5W67.jpg
(原文件名:QQ截图未命名.jpg)

这里并没有储存task_stack的任何东西呀。我就想知道,task_sp到底得到了一个什么东西。小弟很菜,拜托不要说去看什么什么书之类的话,如果并非打击我,推荐几本好书让我补些基础也行。

changhui0222 发表于 2011-11-14 11:26:32

简单的说就是OS欺骗了MCU。
OS将需要运行的任务地址压栈,然后中断返回的时候正好返回到需要运行的任务所在的地方开始执行程序!

liu116feng 发表于 2011-11-14 12:06:06

mark

hacker9 发表于 2011-11-14 15:57:34

我的理解是程序在进入函数时就会引发压栈操作,第一件事就是先保存当前的程序地址,所以,这就是为什么task_stack[]task_stack[]里存放的是函数的地址;还有在压栈时,MOV SP,#0x60;PUSH PC;就是把PC的值存在0x61里面,所以,在恢复任务时,要执行的就是SP=task_stack[]+1;在函数返回时,ret指令,大概就是执行了POP指令,从而才能转向另一个任务。不知道是不是这样

Semiconductor 发表于 2011-11-25 19:15:45

留个脚印

Helloeveryon 发表于 2011-11-25 23:32:37

MARK

52171314 发表于 2011-11-26 01:34:47

就像是结构体做链表一样

lwcumt 发表于 2011-11-26 16:10:35

mark

moonhtc 发表于 2011-11-26 17:25:17

mark

to_xyr 发表于 2012-2-22 17:34:07

看过

yhy630 发表于 2012-2-22 19:58:26

看过

to_xyr 发表于 2012-2-26 12:10:37

状态机

skype 发表于 2012-2-27 13:25:22

Lz,不能以上面的代码来理解OS多任务是切换.你的代码太另类了。
上下文切换现场保护怎么处理??

skype 发表于 2012-2-27 13:29:35

LZ的OS多任务没有意义。
代码展开就是
void main()
{
while(1)
{
   fun1();
   fun2();
   fun3();
}
}

donglaile 发表于 2012-2-27 22:16:53

回复【13楼】skype
lz的os多任务没有意义。
代码展开就是
void main()
{
while(1)
{
   fun1();
   fun2();
   fun3();
}
}
-----------------------------------------------------------------------

赞同

hacker9 发表于 2012-3-8 21:52:41

但是这个可以让人明白多任务切换的原理啊、

Pony279 发表于 2012-3-9 13:27:13

回复【14楼】donglaile
-----------------------------------------------------------------------

这个叫做协作式多任务。

想在51上玩抢占?算了吧,麻烦,低效。

welcome_cool 发表于 2012-3-9 14:17:25

去看看small rtos for 51.

lovelywwei 发表于 2012-3-9 14:55:44

中断的精髓。没有中断,神马任务都切换不了。
页: [1]
查看完整版本: 简易OS多任务是怎样切换的?