📄 task_switch.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 + -