📄 roaderosv0.2.c
字号:
/*******************************************************************
File: RoaderOS.c
Description: MCS-51 RTOS
Autor: roader
Version: 1.0
Date: 2004-07
Compiler: Keil
Emial: larkguo@gmail.com
*********************************************************************/
#include <reg51.h>
/*------------------------------------------------------------------*/
#define uChar unsigned char
#define uShort unsigned short
#define uLong unsigned long
#define sChar signed char
#define sShort signed short
#define sLong signed long
/*------------------------------------------------------------------*/
#define TASKS_SIZE 5
#define FRAME_SIZE 20 //frame size
#define REGS_SIZE 16 //register size
#define IDLE_TASK TASKS_SIZE -1
#define disable() EA=0 //close interrupt
#define enable() EA=1 //open interrupt
/*------------------------------------------------------------------*/
enum task_state{READY = 1 ,RUNNING, BLOCKED, SLEEPING, SUSPENDED, DEAD};
uChar data cur_task = IDLE_TASK;
char data task_id = 0;
struct _tasks
{
enum task_state status;
uChar data *sp;
uChar frame[FRAME_SIZE];
} tasks[TASKS_SIZE];
/*------------------------------------------------------------------*/
sbit P1_0 = P1^0;
/*------------------------------------------------------------------*/
void Init_Timer();
void Create_Task(void *task, uChar id);
void Kill_Task(uChar id);
void Idle_Task();
void Start_Task();
void task1();
void task2();
/*------------------------------------------------------------------*/
void ContextSwitch() interrupt 3 using 0
{
/* auto push IE */
*(uChar data *)(++SP) = IE;
disable();
#pragma asm
PUSH DPL
PUSH DPH
PUSH 0x00
PUSH 0x01
PUSH 0x02
PUSH 0x03
PUSH 0x04
PUSH 0x05
PUSH 0x06
PUSH 0x07
#pragma endasm
tasks[cur_task].sp = (uChar data *)SP;
//find ready task
for(task_id = 0; task_id < TASKS_SIZE; task_id++)
{
cur_task=(uChar)(cur_task+1)%TASKS_SIZE;
if(tasks[cur_task].status != READY)
continue;
else
break;
}
//if not find,execute idle task
if (tasks[cur_task].status != READY )
cur_task = TASKS_SIZE-1;
SP = tasks[cur_task].sp;
#pragma asm
POP 0x07
POP 0x06
POP 0x05
POP 0x04
POP 0x03
POP 0x02
POP 0x01
POP 0x00
POP DPH
POP DPL
#pragma endasm
// pop IE
IE = *(uChar data *)(SP--);
}
/*------------------------------------------------------------------*/
void Init_Timer()
{
TMOD = (TMOD & 0x0F) | 0x20;
TH1 = 256;
TL1 = TH1;
TR1 = 1;
ET1 = 1;
EA = 1;
}
/*------------------------------------------------------------------*/
void Create_Task(void *task, uChar id)
{
*(uChar data *)(++SP)=IE;
disable();
tasks[id].frame[0] = (uChar)(((uShort)task)&0xff);
tasks[id].frame[1] = (uChar)(((uShort)task)>>8);
tasks[id].frame[4] = 0;
tasks[id].sp = tasks[id].frame - 1 + REGS_SIZE;
tasks[id].status = READY;
IE = *(uChar data *)(SP--);
}
/*------------------------------------------------------------------*/
void Kill_Task(uChar id)
{
*(uChar data *)(++SP) = IE;
disable();
tasks[id].status = DEAD;
tasks[id].frame[0] = 0;
tasks[id].frame[1] = 0;
IE = *(uChar data *)(SP--);
}
/*------------------------------------------------------------------*/
void Idle_Task()
{
while(1)
{
PCON |= 0x01;
}
}
/*------------------------------------------------------------------*/
void Start_Task()
{
Idle_Task();
}
/*------------------------------------------------------------------*/
void task1()
{
while(1)
{
P1_0 = 0;
}
}
void task2()
{
while(1)
{
P1_0 = 0;
}
}
/*------------------------------------------------------------------*/
void main(void)
{
Create_Task(task1, 0);
Create_Task(task2, 1);
Create_Task(Idle_Task, IDLE_TASK);
Init_Timer();
Start_Task();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -