接下来就是编写通用调度代码了,可以支持多个任务。
下面的例子是3个独立的任务,系统运行如下:
代码下载:funnyos_task_schedule.zip
typedef struct osTask {
void (*ptask)(void);
int stack_SS;
int stack_SP;
int isTaskStart;
} osTask;
int taskCount = 0;
int isTaskAllStart = 0;
osTask task[4];//task1, task2;
void main (void) {
PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK); /* Clear the screen */
PC_DispStr( 0, 0, " Funny OS Demo ", DISP_FGND_WHITE + DISP_BGND_RED + DISP_BLINK);
PC_SetTickRate(18); /* Reprogram tick rate */
PC_TickISR = &TickISR;
PC_VectSet(0x8, PC_TickISR); //asm {int 08h};
task[0].ptask = &testTask1; //创建任务1,任务栈地址0x90100
task[0].stack_SS = 0x9000;
task[0].stack_SP = 0x100;
taskCount++;
task[1].ptask = &testTask2; //创建任务2,任务栈地址0x80100
task[1].stack_SS = 0x8000;
task[1].stack_SP = 0x100;
taskCount++;
task[2].ptask = &testTask3; //创建任务2,任务栈地址0x70100
task[2].stack_SS = 0x7000;
task[2].stack_SP = 0x100;
taskCount++;
for(;;);
}
void TickISR(void) {
static int i = 0;
//static int j = 0;
static int taskid = 0;
static int taskSS, taskSP;
asm {pop di; pop si;}
asm cli;
//outp(0x20, 0x20);
asm {
push ax;
push dx;
mov dx,0x20;
mov al,0x20;
out dx,al;
mov al,0x0;
pop dx;
pop ax;
}
asm sti;
for(i = 0; i < taskCount; i++) {
if(!task[i].isTaskStart) {
task[i].isTaskStart = 1;
//save pre task stack
if(i) {
asm {
push ax; push bx; push cx; push dx; push si; push di; push bp; push ds; push es;
mov taskSP, sp;
mov taskSS, ss;
};
task[i-1].stack_SS = taskSS;
task[i-1].stack_SP = taskSP;
}
taskSS = task[i].stack_SS;
taskSP = task[i].stack_SP;
asm {
mov ss, taskSS;
mov sp, taskSP;
}
(*(task[i].ptask))();
}
}
if(!isTaskAllStart) {
isTaskAllStart = 1;
taskid = taskCount - 1; //taskid starts from 0
}
for(i = 0; i < taskCount; i++) {
if(i == taskid) {
//save task stack
asm {
push ax; push bx; push cx; push dx; push si; push di; push bp; push ds; push es;
mov taskSP, sp;
mov taskSS, ss;
};
task[i].stack_SS = taskSS;
task[i].stack_SP = taskSP;
//restore nextTaskid stack
taskid = ((taskid+1) == taskCount) ? (0) : (taskid + 1); //taskid = next task id
taskSS = task[taskid].stack_SS;
taskSP = task[taskid].stack_SP;
asm {
mov ss, taskSS;
mov sp, taskSP;
pop es; pop ds; pop bp; pop di; pop si; pop dx; pop cx; pop bx; pop ax;
iret;
}
}
}
//asm iret;
}