www.pudn.com > 51_00_OS.rar > task_switch.C, change:2006-02-24,size:4059b
/******************************************************* *************基于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; //开中断 } ////////////////////////////////////////////////////////////////////////////////////////////