zjsxwc 发表于 2013-3-20 18:24:42

基于时间片的52操作系统

本帖最后由 zjsxwc 于 2013-3-21 16:53 编辑

今天在看了rainyss大神的帖子后,在我的52上写了个调度器。#include <reg52.h>


#define MAX_TASKS 3      
#define MAX_TASK_DEP 24
unsigned char idata task_stack={0};
unsigned char idata * task_sp;


unsigned char idatatask_old={0};
unsigned char task_id;

unsigned char idata task_die={0};


unsigned char task_time_slice={
        {0xC0,0xFF},//ʱ¼äƬ
        {0xC2,0xFF},               
        {0xC1,0xFF},       
};



void Task_clear_REG(){
        ACC=0;
        B=0;
        PSW=0;

}

void Start_Timer2(){
        EXEN2=0;
        C_T2=0;
        RCLK=0;
        TCLK=0;
        CP_RL2=0;
       
        RCAP2L=task_time_slice;
        RCAP2H=task_time_slice;
        TL2=task_time_slice;
        TH2=task_time_slice;
       
        PT2=1;
        TR2=1;
        ET2=1;
        EA=1;

}



void Init_OS(){
        Start_Timer2();
}

void Kill_task(unsigned char tid){
        task_die=1;
}
void Revive_task(unsigned char tid){
        task_die=0;
}


void task_load(unsigned int fn, unsigned char tid){
        task_sp = task_stack + 1;
        task_stack = (unsigned int)fn & 0xff;
        task_stack = (unsigned int)fn >> 8;
}





#define os_start(tid) {task_id = tid,SP = task_sp;return;}



void task1()
{
static unsigned char i;

       
        while(1){
                i++;
        }
}

void task2()
{
static unsigned char j;

       
        while(1){
                j+=1;
                j+=2;
                j+=3;
                j+=4;
                j+=5;
                j+=6;
                j+=7;
                j*=8;
                j+=9;
                j+=10;
                j+=55;
                j+=767;
                j+=2;
                j+=2;
                j+=44;
                j*=3;
                j+=1;
                j+=66;
                j*=43;
                j+=7;
                j+=98;
                j*=7;
                j+=332;
                j+=44;
                j+=33;
                j+=324;
                Kill_task(1);//finish task2,and suicide
        }
}

void task3(){
static unsigned char k;

       
        while(1){
                k+=3;
        }
}

void main(){

        task_load(task1, 0);
        task_load(task2, 1);
        task_load(task3, 2);
        Init_OS();
        os_start(0);

}




void task_switch() interrupt 5
{


        unsigned charR={0};//let keil C51 know that R0--R7/B/acc/psw/dptr must be push\pop in the stack!
        TR2=0;


        task_old=1;
        task_sp=SP;
       
                               
        while(1){
                if(++task_id == MAX_TASKS)
                task_id = 0;
                if         (task_die!=1) break;                                                               
        }       
                               
        if (task_old)
                SP=task_sp;
        else{       
                *(task_sp+1)=0;//acc
                *(task_sp+2)=0;//B
                *(task_sp+3)=0;//dpoh
                *(task_sp+4)=0;//dpol
                *(task_sp+5)=0;//psw
                *(task_sp+6)=0;//r0
                *(task_sp+7)=0;//r1
                *(task_sp+8)=0;//r2
                *(task_sp+9)=0;//r3
                *(task_sp+10)=0;//r4
                *(task_sp+11)=0;//r5
                *(task_sp+12)=0;//r6
                *(task_sp+13)=0;//r7
               
                task_sp=task_sp+13;
                SP = task_sp;
        }

       
        TF2=0;       
        TL2=task_time_slice;
        TH2=task_time_slice;
        TR2=1;
        return;
}已改,由于使用中断服务函数时C51会自动保持ACC\PSW\B\R0--R7\dptr到相应任务堆栈所以省下了开辟空间保证这些寄存器的事情.

沙漏 发表于 2013-3-20 18:26:39

移植了操作系统吗

zjsxwc 发表于 2013-3-20 18:27:16

本帖最后由 zjsxwc 于 2013-3-20 21:39 编辑

占用了52的T2计时器 以及 level 1特权的中断。

zjsxwc 发表于 2013-3-20 18:42:40

沙漏 发表于 2013-3-20 18:26 static/image/common/back.gif
移植了操作系统吗

只是由原来手动切任务,变成按时间片自动切任务,利用了52多出来的T2计数器。

barryliu 发表于 2013-3-21 09:42:46

R0~R7、PSW、ACC等重要寄存器没保存,任务切换会死人的。
你的测试程序例子太简单,所以你没看出来问题。

zjsxwc 发表于 2013-3-21 12:21:11

本帖最后由 zjsxwc 于 2013-3-21 16:30 编辑

barryliu 发表于 2013-3-21 09:42 static/image/common/back.gif
R0~R7、PSW、ACC等重要寄存器没保存,任务切换会死人的。
你的测试程序例子太简单,所以你没看出来问题。 ...

多谢提醒,
已修改源程序

zjsxwc 发表于 2013-3-21 14:38:59

本帖最后由 zjsxwc 于 2013-3-21 16:48 编辑

实现了寄存器组的保存,防止了寄存器不同任务间的重用。


剩下的问题就是函数重入问题,对于函数重入问题也只能以宏代替或者使用那个重用函数关键字reentrant

zjsxwc 发表于 2013-3-21 16:50:05

在我的52上测试,基本没有问题了,不过每个task中的变量都要是static的,否则keil生成汇编时可能会为不同变量分配相同地址。
页: [1]
查看完整版本: 基于时间片的52操作系统