您的位置:首页 > 编程语言 > C语言/C++

51系列小型操作系统精髓 简单实现12 C语言版未加保护参数

2014-05-26 14:33 337 查看
/*
CRTOS 实时可剥夺型内核
1.任务不用预加载,不用预定义。任务调用时加载,可删除(退出死循环即可)
2.单位轮转查询时间由晶振和定时器初始化决定。在这里为10ms
3.定时时间为【 time*单位轮转查询时间 】 ,其中time为 rtos_wait(time)中time.
4.可运行多个任务【自定义】
5.任务从rtos_wait()处切换,在定时时间到后从定时中断中切换回来,任务执行后,回到中断,再从中断回到主程序。
*/
#include "STC12C5A.H"

#define TIMER_RELOAD()  {TL0=0x00;TH0=0xC4;}//使能T/C	  初始10ms
#define MAX_TASKS 3 //任务槽最大个数.
unsigned char data task_stack[MAX_TASKS][2];//任务堆栈.  PC指针为16位,需2个字节task_stack[][0]L  task_stack[][1]H。
unsigned char data task_time[MAX_TASKS];	//定时时间
unsigned char data task_id=0; //当前活动任务号
void Timer0Init()		//@18.432MHz
{
AUXR &= 0x7F;		//定时器时钟12T模式
TMOD &= 0xF0;		//设置定时器模式
TMOD |= 0x01;		//设置定时器模式
TL0 = 0x00;		//设置定时初值
TH0 =0xC4;		//设置定时初值 10ms
TF0 = 0;		//清除TF0标志
TR0 = 1;		//定时器0开始计时

ET0=1;
EA=1;
}
void rtos_wait(unsigned char time)
{
if(task_id==MAX_TASKS)		 //忽略不处理,直接跳出
{
SP-=2;
}
else
{
task_time[task_id]=time;   	//保存当前任务时间
task_stack[task_id][1] =*((unsigned char data* )(SP));	  	//保存当前断点 并把SP=SP-2,任务切换到下一任务;
SP--;
task_stack[task_id][0] =*((unsigned char data*)(SP));
SP--;
for(task_id=0;task_id<MAX_TASKS && task_time[task_id];task_id++)	 //任务号设为最大,越过最大则回到0	 //根据定时时间判断
{

}
}
}
void rwcl2()
{
//保存的PC指针调出来
SP++;
(*((unsigned char data*)(SP)))=task_stack[task_id][0];
SP++;
(*((unsigned char data*)(SP)))=task_stack[task_id][1] ;
}
void rwcl()		 //任务时间是否到,任务时间到 实时切换回
{
//从把定时时间减1 ,找看哪个任务到	,任务时间到 实时切换回
unsigned char data i;
for(i=0;i<MAX_TASKS && task_time[i];i++)
{
if(--task_time[i]==0)		//多个定时时间同时到,任务越靠后,越优先执行。
{
task_id=i;			//当前任务号
//堆栈保护
rwcl2();
//堆栈弹出
}
}
}
void tm0_isr() interrupt 1 //using 1
{
TIMER_RELOAD();	 //定时时间重载
rwcl();			 //任务时间是否到,任务时间到 实时切换回
}

//****************************************************************示例
unsigned char a=0;
unsigned char bb=0;
void task_test()
{
static unsigned char i;
while(1)
{
a=~a;
for(i=0;i<10;i++)
rtos_wait(10);		 //执行完后,记录下一步地址,返回
a=~a;
for(i=0;i<10;i++)
rtos_wait(10);		 //执行完后,记录下一步地址,返回
}
}
void task_test2()
{
static unsigned char i;
while(1)
{
bb=~bb;
for(i=0;i<10;i++)
rtos_wait(10);		 //执行完后,记录下一步地址,返回
bb=~bb;
for(i=0;i<10;i++)
rtos_wait(10);		 //执行完后,记录下一步地址,返回
}
}
void tsy()
{
static unsigned char c=0;
rtos_wait(10);
c=5;
}
void main()
{
Timer0Init();
task_test();
task_test2();
while(1)
{
tsy();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: