上一节写了个单任务系统,下面当然就是多任务了,这里就先用2个任务吧。
任务多了,就需要调度,前面说了,需求就是写个支持多任务,分时调度的操作系统。
怎样实现分时调度呢?PC机有颗8254计时器芯片,设置好计数后,可实现每秒(18-1193180)次的中断。
可以在每次定时器中断中轮流调度任务,这样就能让多任务运行起来。是不是有点小激动。。。。。
想法是美好的,还需要一步步实现,先能够实现周期性的定时器中断再说。
先上图吧,在每次定时器中断中输出显示字符’a’:
代码下载: funnyos_time_interrupt.7z
定时器中断实现代码如下,
#include "pc.h"
void testtest();
void TickISR(void);
void (*PC_TickISR)(void);
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);
testtest();
for(;;);
}
void testtest() {
static int i = 97;
i++;
PC_DispChar( 0, i-95, i, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);
}
void TickISR(void) {
static int i = 0;
static int j = 0;
PC_DispChar( (i++)%78, (j++)/78 + 1, 'a'+(j/78), DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);
asm cli;
outp(0x20, 0x20);
asm sti;
//asm iret;
}
基础知识:
定时器芯片8254的控制寄存器IO 地址为0x43,寄存器操作方式如下图:这里设置每秒18次中断,PC_SetTickRate(18)。 还有定时器中断向量号为0x8,即内存地址0x20-0x23处的值为中断处理函数TickISR()的地址。 在TickISR()函数中除了暑促字符'a',还设置了outp(0x20, 0x20); 这句汇编代码,是使能中断控制芯片(PIC)——8259A的定时器的掩码,即重新使能定时器中断,因为每次 产生定时器中断是,掩码都是自动置0,去使能的。