51系列小型操作系统精髓 简单实现4

#include <REG52.H>

#define MAX_TASKS 2 //任务槽个数.必须和实际任务数一至

#define MAX_TASK_DEP 12 //最大栈深.最低不得少于2 个,保守值为12.

unsigned char idata task_stack[MAX_TASKS][MAX_TASK_DEP];//任务堆栈.

unsigned char idata task_sp[MAX_TASKS];

unsigned char task_id; //当前活动任务号

//任务切换函数(任务调度器)

void task_switch(){

task_sp[task_id] = SP;

if(++task_id == MAX_TASKS)

task_id = 0;

SP = task_sp[task_id];

}

//任务装入函数.将指定的函数(参数1)装入指定(参数2)的任务槽中.如果该槽中原来就有任

//务,则原任务丢失,但系统本身不会发生错误.

void task_load(unsigned int fn, unsigned char tid){

task_sp[tid] = task_stack[tid] + 1;

task_stack[tid][0] = (unsigned int)fn & 0xff;
//低字节

task_stack[tid][1] = (unsigned int)fn >> 8;
    //高字节

}

//从指定的任务开始运行任务调度.调用该宏后,将永不返回.

#define os_start(tid) {task_id = tid,SP = task_sp[tid];return;}

/*============================以下为测试代码==========================*/

void task1(){

static unsigned char i;

while(1){

i++;

task_switch();//编译后在这里打上断点

}

}

void task2(){

static unsigned char j;

while(1){

j+=2;

task_switch();//编译后在这里打上断点

}

}

void main(){

//这里装载了两个任务,因此在定义MAX_TASKS 时也必须定义为2

task_load(task1, 0);//将task1 函数装入0 号槽

task_load(task2, 1);//将task2 函数装入1 号槽

os_start(0);

}

以上为网摘

以下为本人改进:任务函数切换

#include <REG52.H>

#define MAX_TASKS 2 //任务槽个数.必须和实际任务数一至
#define MAX_TASK_DEP 12 //最大栈深.最低不得少于2 个,保守值为12.
unsigned char idata task_stack[MAX_TASKS][MAX_TASK_DEP];//任务堆栈.
//unsigned char idata task_sp[MAX_TASKS];
unsigned char task_id; //当前活动任务号

//任务切换函数(任务调度器)
void task_switch(){
//	task_sp[task_id] = SP;
	if(++task_id == MAX_TASKS)
		task_id = 0;
	SP = task_stack[task_id] + 1;
}
//任务装入函数.将指定的函数(参数1)装入指定(参数2)的任务槽中.如果该槽中原来就有任
//务,则原任务丢失,但系统本身不会发生错误.
void task_load(unsigned int fn, unsigned char tid){
//	task_sp[tid] = task_stack[tid] + 1;
	task_stack[tid][0] = (unsigned int)fn & 0xff;	 //低字节
	task_stack[tid][1] = (unsigned int)fn >> 8;	     //高字节
}
//从指定的任务开始运行任务调度.调用该宏后,将永不返回.
#define os_start(tid) {task_id = tid,SP = task_stack[tid] + 1;return;}
/*============================以下为测试代码==========================*/
void task1(){
	static unsigned char i;
	while(1){
		i++;
		task_switch();//编译后在这里打上断点
	}
}
void task2(){
	static unsigned char j;
	while(1){
		j+=2;
		task_switch();//编译后在这里打上断点
	}
}
void main(){
	//这里装载了两个任务,因此在定义MAX_TASKS 时也必须定义为2
	task_load(task1, 0);//将task1 函数装入0 号槽
	task_load(task2, 1);//将task2 函数装入1 号槽
	os_start(0);
}

以本人再改进:任务断点切换

//任务切换函数(任务调度器)
void task_switch(){
	//保存当前断点;
	task_stack[task_id][0] =*((unsigned char *)(SP-1));
	task_stack[task_id][1] =*((unsigned char *)(SP-2));
	//设置任务优先级

	//切换到下一任务  ,如果没有下一任务,则回到0任务,切换到哪里?
	if(task_id==0)
		SP=SP-2;  //切换出去,接着执行
	else
	{
			SP = task_stack[task_id] + 1;    //

	}
				
}

全部程序

#include <REG52.H>

#define MAX_TASKS 2 //任务槽个数.必须和实际任务数一至
#define MAX_TASK_DEP 2 //最大栈深.最低不得少于2 个,保守值为12.
unsigned char idata task_stack[MAX_TASKS][MAX_TASK_DEP]={0};//任务堆栈.
//unsigned char idata task_sp[MAX_TASKS];
unsigned char task_id=0; //当前活动任务号

//任务切换函数(任务调度器)
void task_switch(){
	//保存当前断点;
	task_stack[task_id][0] =*((unsigned char *)(SP-1));
	task_stack[task_id][1] =*((unsigned char *)(SP-2));
	//设置任务优先级

	//切换到下一任务  ,如果没有下一任务,则回到0任务,切换到哪里?

	if(task_id==0)
	{
		task_id=1;
		if(task_stack[1][0]==0 && task_stack[1][1]==0 )
		{
			SP=SP-2;  //切换出去,接着执行
		}
		else
		{
			SP = task_stack[task_id] + 1;
		}

	}
	else
	{
		   	task_id=0;
			SP = task_stack[task_id] + 1;    //
	}
	//

}
/*
//任务装入函数.将指定的函数(参数1)装入指定(参数2)的任务槽中.如果该槽中原来就有任
//务,则原任务丢失,但系统本身不会发生错误.
void task_load(unsigned int fn, unsigned char tid){
//	task_sp[tid] = task_stack[tid] + 1;
	task_stack[tid][0] = (unsigned int)fn & 0xff;	 //低字节
	task_stack[tid][1] = (unsigned int)fn >> 8;	     //高字节
}
//从指定的任务开始运行任务调度.调用该宏后,将永不返回.
#define os_start(tid) {task_id = tid,SP = task_stack[tid] + 1;return;}
*/
/*============================以下为测试代码==========================*/
void task1(){
	static unsigned char i;
	while(1){
		i++;
		task_switch();//编译后在这里打上断点
	}
}
void task2(){
	static unsigned char j;
	while(1){
		j+=2;
		task_switch();//编译后在这里打上断点
	}
}
void main(){
	task1();
	task2();
	/*
	//这里装载了两个任务,因此在定义MAX_TASKS 时也必须定义为2
	task_load(task1, 0);//将task1 函数装入0 号槽
	task_load(task2, 1);//将task2 函数装入1 号槽
	os_start(0);*/
}

51系列小型操作系统精髓 简单实现4,布布扣,bubuko.com

时间: 2024-08-12 17:12:14

51系列小型操作系统精髓 简单实现4的相关文章

51系列小型操作系统精髓 简单实现8 C语言版待改进

使用keil4  ,代码Code Optimization:0   运行OK 可运行8个任务 Program Size: data=21.0 xdata=0 code=401  (包括2个示例变量,未优化) 任务从中断处切换,在定时时间到后从定时中断中切换回来. 待改进地方 1.手动优化汇编程序 2. 重入问题 3.参数进函数和时中断的保护问题 #include "STC12C5A.H" #define TIMER_RELOAD()  {TL0=0x00;TH0=0xC4;}//使能T

51系列小型操作系统精髓 简单实现11 C语言版优化后说明(有图)

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

51系列小型操作系统精髓 简单实现7 C语言版待改进

#include "STC12C5A.H" #define TIMER_RELOAD()  {TL0=0x00;TH0=0xC4;}//使能T/C  初始10ms #define MAX_TASKS 2 //任务槽最大个数. unsigned char idata task_stack[MAX_TASKS][2];//任务堆栈.  PC指针为16位,需2个字节task_stack[][0]L  task_stack[][1]H. unsigned char idata task_tim

51系列小型操作系统精髓 简单实现2

在51单片机中,不能直接修改PC,但有一种方法是可以改变PC的.函数调用里会把PC值压入堆栈中,调用结束后,会把PC值弹出到PC中. 能改变PC就可以控制程序流程. 1.在任务中切换出去 #define MAX_TASKS 8 //任务槽最大个数. unsigned char idata task_stack[MAX_TASKS][2];//任务堆栈. //保存当前断点 并把SP=SP-2; task_stack[task_id][0] =*(SP--); task_stack[task_id]

51系列小型操作系统精髓 简单实现3

现在遇到的问题: 1.任务不用预加载,进入一个任务,加载一个任务.没有任务时,定时器怎么处理?当只有一个任务时,怎么处理?多个任务怎么轮转或按优先级切换? 2.关于各任务定时时间,一个一个地减是否麻烦,有没有更好的方法? 3.没有保护寄存,这样切换,是否对?当任务函数有多个层嵌套时,有没有问题? #include "STC12C5A.H" #define TIMER_RELOAD() {TL0=0x00;TH0=0xC4;}//使能T/C 初始10ms #define MAX_TASK

51系列小型操作系统精髓 简单实现10 C语言版优化后发布(有图)

4个任务 /* 使用keil4 可运行8个任务 任务从rtos_wait()处切换,在定时时间到后从定时中断中切换回来. */ #include "STC12C5A.H" #define TIMER_RELOAD() {TL0=0x00;TH0=0xC4;}//使能T/C 初始10ms #define MAX_TASKS 8 //任务槽最大个数. unsigned char idata task_stack[MAX_TASKS][2];//任务堆栈. PC指针为16位,需2个字节tas

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

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

51系列小型操作系统精髓 简单实现6 C语言版待改进

#include "STC12C5A.H" #define TIMER_RELOAD()  {TL0=0x00;TH0=0xC4;}//使能T/C  初始10ms #define MAX_TASKS 8 //任务槽最大个数. unsigned char idata task_stack[MAX_TASKS][2];//任务堆栈.  PC指针为16位,需2个字节. unsigned char idata task_time[MAX_TASKS]; //定时时间 unsigned char

51系列小型操作系统精髓 简单实现

源码地址(专业定制程序:MCU,Windows,Android ,VC串口,Android蓝牙等不限.) 1.切换任务并记录位置,保证在时间到后能切换回来.(在任务中切换出去,在定时器中切换回来.)(时间片轮转) ;******************************************** ;RTOS 用定时器0的多任务处理程序 ;项目增加方式使用. ;程序不影响其它数据,目前程序的前后段不能进行参数传递 . 最多可以同时运行8个任务, ;执行时使用定时器0,定时时间根据初始化时的