搜索
bottom↓
回复: 18

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

[复制链接]

出0入0汤圆

发表于 2011-11-14 11:08:22 | 显示全部楼层 |阅读模式
看了论坛里那个简易OS,对任务切换有些不理解,自己写了一个类似的,但不保存SP,这样三个任务会不停循环执行,任务函数也不用死循环了。
首先,如果哪位能解释这个任务切换是怎样实现的,请直接给我解释一下,谢谢了。

这是我写的代码
#include<reg52.h>
unsigned int task_sp[3];
unsigned char task_stack[3][12];
unsigned char task_id=0,i=0;
void task_switch()
{
// task_sp[task_id]=SP;
  if(task_id==2)task_id=0;
  else task_id++;
  SP=task_sp[task_id];         
}
void task1()
{
  i++;
  task_switch();
}
void task2()
{
  i++;
  task_switch();
}
void task3()
{
  i++;
  task_switch();
}
void task_init()
{
  task_stack[0][0]=(unsigned int)task1 & 0xff;
  task_stack[0][1]=(unsigned int)task1 >> 8;
  task_sp[0]=task_stack[0]+1;
  task_stack[1][0]=(unsigned int)task2 & 0xff;
  task_stack[1][1]=(unsigned int)task2 >> 8;
  task_sp[1]=task_stack[1]+1;
  task_stack[2][0]=(unsigned int)task3 & 0xff;
  task_stack[2][1]=(unsigned int)task3 >> 8;
  task_sp[2]=task_stack[2]+1;          
}
void os_start(tid) {task_id = tid,SP = task_sp[tid];return;}
void main()
{
  task_init();
  os_start(0);
}
对于  task_sp[1]=task_stack[1]+1;这一句,根据书上说的,就是把task_stack[1][1]里的值赋给task_sp[1],但实际上仿真时的结果是这样的

(原文件名:未命名.jpg)

里面的0x14是什么??地址?

(原文件名:QQ截图未命名.jpg)

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

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2011-11-14 11:26:32 | 显示全部楼层
简单的说就是OS欺骗了MCU。
OS将需要运行的任务地址压栈,然后中断返回的时候正好返回到需要运行的任务所在的地方开始执行程序!

出0入0汤圆

发表于 2011-11-14 12:06:06 | 显示全部楼层
mark

出0入0汤圆

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

出0入9汤圆

发表于 2011-11-25 19:15:45 | 显示全部楼层
留个脚印

出0入0汤圆

发表于 2011-11-25 23:32:37 | 显示全部楼层
MARK

出0入0汤圆

发表于 2011-11-26 01:34:47 | 显示全部楼层
就像是结构体做链表一样

出0入0汤圆

发表于 2011-11-26 16:10:35 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-11-26 17:25:17 | 显示全部楼层
mark

出0入0汤圆

发表于 2012-2-22 17:34:07 | 显示全部楼层
看过

出0入0汤圆

发表于 2012-2-22 19:58:26 | 显示全部楼层
看过

出0入0汤圆

发表于 2012-2-26 12:10:37 | 显示全部楼层
状态机

出0入8汤圆

发表于 2012-2-27 13:25:22 | 显示全部楼层
Lz,不能以上面的代码来理解OS多任务是切换.你的代码太另类了。
上下文切换现场保护怎么处理??

出0入8汤圆

发表于 2012-2-27 13:29:35 | 显示全部楼层
LZ的OS多任务没有意义。
代码展开就是
void main()
{
  while(1)
{
   fun1();
   fun2();
   fun3();
}
}

出0入0汤圆

发表于 2012-2-27 22:16:53 | 显示全部楼层
回复【13楼】skype
lz的os多任务没有意义。
代码展开就是
void main()
{
  while(1)
{
   fun1();
   fun2();
   fun3();
}
}
-----------------------------------------------------------------------

赞同

出0入0汤圆

 楼主| 发表于 2012-3-8 21:52:41 | 显示全部楼层
但是这个可以让人明白多任务切换的原理啊、

出0入0汤圆

发表于 2012-3-9 13:27:13 | 显示全部楼层
回复【14楼】donglaile
-----------------------------------------------------------------------

这个叫做协作式多任务。

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

出0入0汤圆

发表于 2012-3-9 14:17:25 | 显示全部楼层
去看看small rtos for 51.

出0入30汤圆

发表于 2012-3-9 14:55:44 | 显示全部楼层
中断的精髓。没有中断,神马任务都切换不了。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-6-8 21:50

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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