⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 task_switch.c

📁 基于51的圈圈操作系统(51_00_OS)出来拉…… 来这里下载整个程序包: http://blog.21ic.com/more.asp?name=computer00&id=9501
💻 C
字号:
/*******************************************************
*************基于51内核的圈圈操作系统*****************
本程序只供学习使用,未经作者许可,不得用于其它任何用途

Task_Switch.c file

Created by Computer-lov
Date: 2005.10.27

Edit date:2006.2.24

Version V1.1
Copyright(C) Computer-lov 2005-2015
All rigths reserved

******************************************************/

#include "AT89X52.h"
#include "task_switch.h"
#include "MAIN.H"
#include "OS_core.h"

///////////////////////////////////////////任务切换函数/////////////////////////////////
void OS_Task_Switch(void)
{
 static unsigned char i;    //使用static申明局部变量,避免临时变量使用相同地址
 static unsigned char temp;

 EA=0;                //关中断
 __asm PUSH ACC       //保护当前任务寄存器
 __asm PUSH B
 __asm PUSH PSW
 __asm PUSH DPL
 __asm PUSH DPH
 __asm PUSH 0         //0-7为工作寄存器
 __asm PUSH 1
 __asm PUSH 2
 __asm PUSH 3
 __asm PUSH 4
 __asm PUSH 5
 __asm PUSH 6
 __asm PUSH 7

 OS_pcb[OS_Current_ID].Task_SP=SP;   //保存当前堆栈指针

 OS_Current_ID=0;     //设置为空闲任务的ID号,优先级最低
 
 temp=0x01;
 for(i=0;i<MAX_TASK;i++)   //查找优先级最高的任务
  {
   if(OS_Task_List&temp)   //判断是否有该任务
    {
     if(OS_pcb[i].Suspend==0)   //查找未挂起任务
      {
       if(OS_pcb[i].Priority<OS_pcb[OS_Current_ID].Priority)   //如果优先级高,则切换之
        {
         OS_Current_ID=i;
        }
      }
    }
   temp<<=1;    //调整temp的值,以检查下一个任务
  }

 SP=OS_pcb[OS_Current_ID].Task_SP;     //任务堆栈指针切换

 __asm POP 7         //恢复任务寄存器
 __asm POP 6
 __asm POP 5
 __asm POP 4
 __asm POP 3
 __asm POP 2
 __asm POP 1
 __asm POP 0
 __asm POP DPH
 __asm POP DPL
 __asm POP PSW
 __asm POP B
 __asm POP ACC

 EA=1;      //开中断
}
/////////////////////////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////定时器中断服务函数//////////////////////////////////
void Timer2ISR(void) interrupt 5 using 1
{
 unsigned char i;
 unsigned char temp;

 EA=0;            //关中断

 __asm PUSH DPL    //保护当前任务寄存器,其中ACC,PSW,B寄存器编译器自动压栈
 __asm PUSH DPH
 __asm PUSH 0
 __asm PUSH 1
 __asm PUSH 2
 __asm PUSH 3
 __asm PUSH 4
 __asm PUSH 5
 __asm PUSH 6
 __asm PUSH 7

 TF2=0;        //清中断标志TF2


 if(!OS_Running)  //如果是第一次进入,则调整好堆栈指针位置,使其不返回主函数
  {
   SP-=2;         //将堆栈指针下移2,因为从主函数中断时压栈的两个返回地址是无用的
   for(i=1;i<Num_PUSH_bytes+1;i++)   //同时将刚被压栈的那几个往下平移2个字节
    {
     ((unsigned char idata *)(SP-Num_PUSH_bytes))[i]=((unsigned char idata *)(SP-Num_PUSH_bytes+2))[i];
    }
   OS_Running=1;     //开始运行
   OS_Run_Time=0;   //运行总时间清0
  }

 OS_Run_Time++;    //每一个时钟节拍,运行总时间加1

 OS_pcb[OS_Current_ID].Task_SP=SP;      //保存当前任务堆栈指针

 OS_Current_ID=0;                    //设置为空闲任务的ID号,优先级最低

 temp=0x01;
 for(i=0;i<MAX_TASK;i++)          //查找优先级最高的任务
  {
   if(OS_Task_List&temp)          //如果此任务存在
    {
     if(OS_pcb[i].Delay!=0)            //如果任务需要延时
      {
       OS_pcb[i].Delay--;              //延时时间减1
       if(OS_pcb[i].Delay==0)          //如果延时时间到
        {
         OS_pcb[i].Suspend=0;          //任务解挂起
        }
      }
     if(OS_pcb[i].Suspend==0)          //查找未挂起任务
      {
       if(OS_pcb[i].Priority<OS_pcb[OS_Current_ID].Priority)   //如果优先级高,则切换之 
        {
         OS_Current_ID=i;
        }
      }
    }
   temp<<=1;    //调整temp的值,以检查下一个任务 
  }

 SP=OS_pcb[OS_Current_ID].Task_SP;    //任务堆栈指针切换

 __asm POP 7
 __asm POP 6
 __asm POP 5
 __asm POP 4
 __asm POP 3
 __asm POP 2
 __asm POP 1
 __asm POP 0
 __asm POP DPH
 __asm POP DPL         //恢复任务寄存器

 EA=1;              //开中断
}
////////////////////////////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -