接下来就是编写通用调度代码了,可以支持多个任务。
下面的例子是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; }