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

2020-02-04 09:28发布

看了论坛里那个简易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]到底得到了一个什么东西。小弟很菜,拜托不要说去看什么什么书之类的话,如果并非打击我,推荐几本好书让我补些基础也行。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
18条回答
changhui0222
1楼-- · 2020-02-04 14:24
简单的说就是OS欺骗了MCU。
OS将需要运行的任务地址压栈,然后中断返回的时候正好返回到需要运行的任务所在的地方开始执行程序!
liu116feng
2楼-- · 2020-02-04 16:27
mark
hacker9
3楼-- · 2020-02-04 21:41
我的理解是程序在进入函数时就会引发压栈操作,第一件事就是先保存当前的程序地址,所以,这就是为什么task_stack[][0]task_stack[][1]里存放的是函数的地址;还有在压栈时,MOV SP,#0x60;PUSH PC;就是把PC的值存在0x61里面,所以,在恢复任务时,要执行的就是SP=task_stack[]+1;在函数返回时,ret指令,大概就是执行了POP指令,从而才能转向另一个任务。不知道是不是这样
Semiconductor
4楼-- · 2020-02-05 00:56
 精彩回答 2  元偷偷看……
Helloeveryon
5楼-- · 2020-02-05 01:09
MARK
52171314
6楼-- · 2020-02-05 02:46
就像是结构体做链表一样

一周热门 更多>