Implement another pseudo operating system (scheduler) using goto and C macro definitions(2)
Implement another pseudo operating system (scheduler) using goto and C macro definitions, this is not a real embedded operating system, it is a pseudo operating system, or a scheduler for MCU, it costs a few ram and rom, but can do a lot works for you and save your time and easy your software.
Compared to the previous implementation, In this implement, switch case can be used in source.
the whole source are listed:
#include <stc89c51.h>
#define MAXTASKS 3
//-------------pseudo operating system (scheduler) use goto----begin---------------------------------------
//switch case can be used in this implement
#define _SS(N) static unsigned char STATE=0; switch(STATE){ STATES##N;}
#define _EE ; STATE=0; return 255;
#define WaitX(A,tickets) do {STATE=A; return tickets ;} while(0); ST(A):
#define RunTask(TaskName,TaskID) do { if (timers[TaskID]==0) timers[TaskID]=TaskName(); } while(0);
#define RunTaskA(TaskName,TaskID) { if (timers[TaskID]==0) {timers[TaskID]=TaskName(); continue;} } //?°??μ?è???ó??è±£?¤?′DD
#define CallSubX(A,SubTaskName) do {unsigned char currdt; STATE=A; return 0; ST(A): currdt=SubTaskName(); if(currdt!=255) return currdt;} while(0);
#define InitTasks() {unsigned char i; for(i=MAXTASKS;i>0 ;i--) timers[i-1]=0; }
#define UpdateTimers() {unsigned char i; for(i=MAXTASKS;i>0 ;i--){if((timers[i-1]!=0)&&(timers[i-1]!=255)) timers[i-1]--;}}
#define EXIT do {STATE=0; return 255;} while(0);
#define RESTART do {STATE=0; return 0;} while(0);
volatile unsigned char timers[MAXTASKS];
#define ST(A) ST##_##A
#define GO(A) case A: goto ST(A);
#define STATES1 GO(1);
#define STATES2 GO(1);GO(2);
#define STATES3 GO(1);GO(2);GO(3);
#define STATES4 GO(1);GO(2);GO(3);GO(4);
#define STATES5 GO(1);GO(2);GO(3);GO(4);GO(5);
#define STATES6 GO(1);GO(2);GO(3);GO(4);GO(5);GO(6);
#define STATES7 GO(1);GO(2);GO(3);GO(4);GO(5);GO(6);GO(7);
#define STATES8 GO(1);GO(2);GO(3);GO(4);GO(5);GO(6);GO(7);GO(8);
#define STATES9 GO(1);GO(2);GO(3);GO(4);GO(5);GO(6);GO(7);GO(8);GO(9);
#define STATES10 GO(1);GO(2);GO(3);GO(4);GO(5);GO(6);GO(7);GO(8);GO(9);GO(10);
#define STATES11 GO(1);GO(2);GO(3);GO(4);GO(5);GO(6);GO(7);GO(8);GO(9);GO(10);GO(11);
#define STATES12 GO(1);GO(2);GO(3);GO(4);GO(5);GO(6);GO(7);GO(8);GO(9);GO(10);GO(11);GO(12);
#define STATES13 GO(1);GO(2);GO(3);GO(4);GO(5);GO(6);GO(7);GO(8);GO(9);GO(10);GO(11);GO(12);GO(13);
#define STATES14 GO(1);GO(2);GO(3);GO(4);GO(5);GO(6);GO(7);GO(8);GO(9);GO(10);GO(11);GO(12);GO(13);GO(14);
#define STATES15 GO(1);GO(2);GO(3);GO(4);GO(5);GO(6);GO(7);GO(8);GO(9);GO(10);GO(11);GO(12);GO(13);GO(14);GO(15);
#define STATES16 GO(1);GO(2);GO(3);GO(4);GO(5);GO(6);GO(7);GO(8);GO(9);GO(10);GO(11);GO(12);GO(13);GO(14);GO(15);GO(16);
//#define STATESXX ....you can define more
#define SEM unsigned int
#define InitSem(sem) sem=0;
#define WaitSem(A,sem) do{ sem=1; WaitX(A,0); if (sem>0) return 1;} while(0);
#define WaitSemX(A,sem,tickets) do { sem=tickets+1; WaitX(A,0); if(sem>1){ sem--; return 1;} } while(0);
#define SendSem(sem) do {sem=0;} while(0);
//------------pseudo operating system (scheduler) use goto end------------------------------------------
sbit LED1 = P2^1;
sbit LED2 = P2^2;
sbit LED0 = P2^5;
unsigned char task0(){
_SS(1) //1 wait used in this task _SS(1)
while(1){
WaitX(1,50);
LED0=!LED0;
}
_EE
}
unsigned char task1(){
_SS(1) //1 wait used in this task _SS(1)
while(1){
WaitX(1,100);
LED1=!LED1;
}
_EE
}
unsigned char task2(){
_SS(3) //3 wait used in this task _SS(3)
while(1){
WaitX(1,100);
LED2=!LED2;
WaitX(2,100);
LED2=!LED2;
WaitX(3,100);
LED2=!LED2;
}
_EE
}
void InitT0()
{
TMOD = 0x21;
IE |= 0x82; // 12t
TL0=0Xff;
TH0=0XDB;
TR0 = 1;
}
void INTT0(void) interrupt 1 using 1
{
TL0=0Xff; //10ms ??
TH0=0XDB;//b7;
UpdateTimers();
RunTask(task0,0);//High-level tasks, executed in interrupts, can deprive low-level tasks。
}
void main()
{
InitT0();
InitTasks(); //?????,?????timers??
while(1){
// RunTask(task0,0);
RunTaskA(task1,1);//??1?????2??????
RunTaskA(task2,2);//??2????????
}
}
Comment disabled