发布于 

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 ...... 显示位置的坐标
c ...... 字符颜色(color)
b ...... 背景颜色(back color)
s ...... 字符串(string)
l ...... 字符串长度(length)

2.重新调整FIFO缓冲区(1)

  • 将定时器用的多个FIFO缓冲区都集中成一个,往FIFO写入不同的数据,就能够正常地分辨出是哪个寄存器超时了。

3.测试性能

  • 我们专注于定时器地改良,是因为在今后地开发中会经常使用定时器。
  • 测试性能地方法:先对HariMain略加修改,恢复变量count,然后完全不显示计数,全力执行“count++;”语句。当到了10秒后超时的时候,再显示这个count值。

4.重新调整FIFO缓冲区(2)

  • 把3个定时器全部归纳到一个FIFO缓冲区中,就可以把键盘和鼠标归纳起来,只用1个FIFO缓冲区。
0~ 1…………………光标闪烁用定时器
3…………………3秒定时器
10…………………10秒定时器
256~ 511…………………键盘输入(从键盘控制器读入的值再加上256)
512~ 767……鼠标输入(从键盘控制器读入的值再加上512)
  • 此次我们改写最多的是HariMain。在HariMain里,执行“count++;”语句和查询FIFO缓冲区中是否有数据这两个操作,是多次交互进行的。这次修改以后,程序只需要看1个FIFO缓冲区就行了,而以前要看3个。也就是说,FIFO缓冲区的查询能够更快完成,从而使得“count++;”语句执行的次数更多。

5.加快中断处理(4)

  • 在FIFO里有一个取代移位处理的方法:读取一个数据以后不是让后面的数据向前靠齐,而是
    改变下一次的数据读取地址。这是一个很巧妙的方法,但不适用于定时器。因为从timers[ ]中去除超时的中断时,这个方法虽然不错,但问题在于,用timer_settime登录中断时,后面的中断必须后移,在这一点上,以上方法不太好。
  • 更好的方法:我们在结构体struct TIMER中加入next变量。这是个地址变量,用来存放下一个即将超时的定时器的地址。
    13.1

  • 判断一下顺序,如果我们知道了插入的位置(即知道了在s和t中间插入的话),就可以像下图那样把数据重新连接起来。也就是仅仅改变s->next和timer->next的值就可以了。

13.2

6.使用“哨兵”简化程序

  • 我们来看看具体的做法。在进行初始化的时候,将时刻0xffffffff的定时器连到最后一个定时器上。虽然我们偷了点懒没有设定fifo等,但不必担心。反正无论如何都不可能到达这个时刻(在到达之前会修改时刻),所以不可能发生超时问题。它一直处于后面,只是个附带物,是个留下来看家的留守者。这个留守者正是“哨兵“。