网上有一个C51的多任务系统,但是对其代码的运行流程不太清楚,请各位网友大神们帮忙解释下。谢谢
/*
使用keil4 ,代码Code Optimization:0 运行OK
可运行8个任务
Program Size:
data=21.0 xdata=0 code=401 (包括2个示例变量,未优化)
任务从中断处切换,在定时时间到后从定时中断中切换回来。
待改进地方
1.手动优化汇编程序
2. 重入问题
3.参数进函数和定时中断的保护问题
*/
#include <regx52.H>
#include <INTRINS.H>
typedef unsigned char u8;
typedef unsigned int u16;
sbit LED1 = P2 ^ 0;
sbit LED2 = P2 ^ 1;
#define TIMER_RELOAD() {TL0=0xf0;TH0=0xd8;}//使能T/C 初始10ms
#define MAX_TASKS 2 //任务槽最大个数.
u8 idata task_stack[MAX_TASKS][2];//任务堆栈. PC指针为16位,需2个字节task_stack[][0]L task_stack[][1]H。
u8 idata task_time[MAX_TASKS]; //定时时间
u8 task_id=0; //当前活动任务号
u8 a=0;
u8 b=0;
void rtos_wait(u8 time)
{
static u8 i;
//保存当前任务时间
task_time[task_id]=time;
//保存当前断点 并把SP=SP-2,任务切换到下一任务;
task_stack[task_id][1] =*((u8 data* )(SP));
SP--;
task_stack[task_id][0] =*((u8 data*)(SP));
SP--;
/* //任务号
if(++task_id == MAX_TASKS)
task_id = 0;
*/
//任务号设为最大,越过最大则回到0
for(i=0; i<MAX_TASKS; i++)
{
if(task_time[i]==0)//根据定时时间判断
{
task_id=i;
break;
}
}
// if(i==MAX_TASKS) //任务满 超出则回到0
// {
// task_id=0;
// }
}
void task_test()
{
while(1)
{
a++;
LED2 = ~LED2;
rtos_wait(100); //执行完后,记录下一步地址,返回
a++;
}
}
void task_test2()
{
while(1)
{
b++;
LED1 = ~LED1;
rtos_wait(50); //执行完后,记录下一步地址,返回
b++;
}
}
void Timer0Init() //@18.432MHz
{
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式 16bit timer
TL0 = 0xF0; //设置定时初值
TH0 = 0xD8; //设置定时初值 10ms
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1; //允许定时器0中断
EA = 1; //开启总中断
}
void main()
{
Timer0Init();
task_test();
task_test2();
while(1);
}
void task_sw() //任务时间是否到,任务时间到 实时切换回
{
//从把定时时间减1 ,找看哪个任务到,任务时间到,则实时切换回
static u8 i;
for(i=0; i<MAX_TASKS; i++)
{
if(task_time[i])
{
task_time[i]--;
if(task_time[i]==0)//多个定时时间同时到,任务越靠后,越优先执行。
{
task_id=i; //当前任务号
//保存的PC指针调出来
SP++;
(*((u8 data*)(SP)))=task_stack[i][0];
SP++;
(*((u8 data*)(SP)))=task_stack[i][1] ;
}
}
}
}
void tm0_isr() interrupt 1 //using 1
{
//定时时间重载
TIMER_RELOAD();
//every 10ms to scan
task_sw(); //任务时间是否到,任务时间到 实时切换回
}
任务加载后,是怎么做到任务切换的,main函数中的while(1);不会一直占用cpu吗??
|