30天自制操作系统(13)
DAY13_定时器(2)
1. 简化字符串显示
- 将“涂背景色、写字符、完成刷新”写进一个函数,更方便使用
void putfonts8_asc_sht(struct SHEET *sht, int x, int y, int c, int b, char *s, int l)
{
boxfill8(sht->buf, sht->bxsize, b, x, y, x + l * 8 - 1, y + 15);
putfonts8_asc(sht->buf, sht->bxsize, x, y, c, s);
sheet_refresh(sht, x, y, x + l * 8, y + 16);
return;
}
x, y ...... 显示位置的坐标 |
2.重新调整FIFO缓冲区(1)
- 将定时器用的多个FIFO缓冲区都集中成一个,往FIFO写入不同的数据,就能够正常地分辨出是哪个寄存器超时了。
3.测试性能
- 我们专注于定时器地改良,是因为在今后地开发中会经常使用定时器。
- 测试性能地方法:先对HariMain略加修改,恢复变量count,然后完全不显示计数,全力执行“count++;”语句。当到了10秒后超时的时候,再显示这个count值。
4.重新调整FIFO缓冲区(2)
- 把3个定时器全部归纳到一个FIFO缓冲区中,就可以把键盘和鼠标归纳起来,只用1个FIFO缓冲区。
0~ 1…………………光标闪烁用定时器 |
- 此次我们改写最多的是HariMain。在HariMain里,执行“count++;”语句和查询FIFO缓冲区中是否有数据这两个操作,是多次交互进行的。这次修改以后,程序只需要看1个FIFO缓冲区就行了,而以前要看3个。也就是说,FIFO缓冲区的查询能够更快完成,从而使得“count++;”语句执行的次数更多。
5.加快中断处理(4)
- 在FIFO里有一个取代移位处理的方法:读取一个数据以后不是让后面的数据向前靠齐,而是
改变下一次的数据读取地址。这是一个很巧妙的方法,但不适用于定时器。因为从timers[ ]中去除超时的中断时,这个方法虽然不错,但问题在于,用timer_settime登录中断时,后面的中断必须后移,在这一点上,以上方法不太好。 更好的方法:我们在结构体struct TIMER中加入next变量。这是个地址变量,用来存放下一个即将超时的定时器的地址。
判断一下顺序,如果我们知道了插入的位置(即知道了在s和t中间插入的话),就可以像下图那样把数据重新连接起来。也就是仅仅改变s->next和timer->next的值就可以了。
6.使用“哨兵”简化程序
- 我们来看看具体的做法。在进行初始化的时候,将时刻0xffffffff的定时器连到最后一个定时器上。虽然我们偷了点懒没有设定fifo等,但不必担心。反正无论如何都不可能到达这个时刻(在到达之前会修改时刻),所以不可能发生超时问题。它一直处于后面,只是个附带物,是个留下来看家的留守者。这个留守者正是“哨兵“。