(1)时钟超时管理架构
对时钟的管理,主要基于时钟中断的功能。中断功能的实现在上面有简要的介绍,这里不做过多描述。
这里介绍两个重要的时钟管理结构体:
struct TIMERCTL
{
 unsigned int count, next, using;
 struct TIMER *timers[MAX_TIMER];
 struct TIMER timers0[MAX_TIMER];
};
 count 计数器
 next “下一时刻”
 using 当前活动的定时器数量
 timers 定时器结构指针数组 (注意:这是一个有序数组,和sheets[]结构是一样的作用)
 timers0 定时器结构数组
以及单个时钟结构体:
struct TIMER
{
 unsigned int timeout, flags;
 struct FIFO8 *fifo;
 unsigned char data;
};
 timeout 相对于当前时间的预定时刻
 flags 记录定时器状态
 fifo 定时器队列指针
 data 定时器数据
首先在内核中初始化PIT之后,并且打开了IRQ0的时钟中断,设置好了中断函数,在这里时钟中断的频率是每秒执行100次,也就是每秒执行一百次中断函数。
首先时钟管理表中count成员在每次中断执行后都会自加一,而next是记录下一个即将超时的时钟时间。同之前的相关管理表,timers是用来排序的指针数组,而timers0用来分配需要管理的超时时钟,这里最大时钟数量被指定为500个。
而在单个时钟结构结构体中,timeout是在执行超时设置的操作后,加上count的时间,可以理解为超时时刻。
在时钟中断中一旦发现有时钟超时,那么就向时钟指定的FIFO队列里,写入由data指定的数据。
这是时钟架构的简要介绍,下面进行分部解析。
 (2)PIT相关设定
上面介绍的PIT是programmable interval timer-可编程间隔定时器的意思,当然这也是一个外部设备。
 io_out8(PIT_CTRL, 0x34);
 io_out8(PIT_CNT0, 0x9c);
 io_out8(PIT_CNT0, 0x2e);
这里对PIC的指定端口发送一定的命令后,PIT设备即开始工作。
这里数值的设置需要阅读相关硬件手册。
(3)时钟中断处理
时钟中断的处理函数,在中断里面实现。
在注册好IDT后时钟中断的函数跳转到 inthandler20函数中实现。
在接受到中断的时候,首先需要向PIC发送一个信号表示受理完毕:
io_out8(PIC0_OCW2, 0x60);
然后时钟控制结构体的count成员加一。
然后判断下一个超时时刻next是否超过count,如果超过就继续,如果没有超过,就退出函数,等待下一次中断。
超过指定时候再遍历所有在使用中的时钟,找出超时的定时器。
在这里还需要判读这个时钟结构体是否是多任务切换的结构体,如果是则执行切换操作,这部分将在多任务里面进行介绍。
如果不是任务切换时钟结构体,那么会进行向该时钟结构体的fifo缓冲区中写入指定的内容。最后对定时器进行位移操作。最后指定下一个等待的时刻next,如果已经没有活动的定时器则next被指定为0xffff ffff最大等待时间。
(4)定时器分配及设置
定时器的分配就是找出时钟管理表中第一个没有被使用的时钟(由定时器中flag标志指定),找到后返回定时器 的指针地址,否则返回0 。
这里需要说明的是定时器的设定功能,在设置定时器的时候,首先需要保存eflags寄存器的内容,然后关闭中断。
因为在设置定时器的时候,如果发生中断,设定函数还未执行结束,那么可能会发生意想不到的错误。
在时钟的设定时间是,时钟结构体里面存储的内容是当前时间加上超时时间,这个在前面也有提及.
然后在timers的指针数组中按照timeout的大小进行排序。
相关算法是是进行移位算法,因为是指针的移动,所以移动的总量并非很大。