DAY13:定时器(2)
简化字符串显示
首先简化之前程序(即完成涂上背景色,再在上面写字符,然后刷新的功能),封装成一个函数(putfonts8_asc_sht()):
/*变量说明:
x,y ------显示位置的坐标
c ------字符的颜色
b ------背景的颜色
s ------字符串
l ------字符串长度
*/
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);
piutfonts8_asc(sht->buf,sht->bxsize,x,y,c,s);
sheet_refresh(sht,x,y,x+l*8,y+16);
return
}
重新调整FIFO缓冲区
原来的程序对每个定时器都划分了一块FIFO,即100个定时器给了100个FIFO缓冲区。
然而,我们可以通过不同的定时器在定时结束后往FIFO写入不同的数据来区分定时器,从而将100个FIFO集成到1个上。
void timer_settime(struct TIMER *timer,unsigned int timeout)
{
int e,i,j;
timer->timeout = timeout + timerctl.count;
timer->flag = TIMER_FLAGS_USING;
e = io_load_eflags();
io_cli();
/*搜索注册的位置*/
for(i=0;i<timerctl.using;i++){
if(timerctl.timers[i]->timeout>=timer->timeout){
break;
}
}
/* i号之后全部后移一位*/
for(j=timerctl.using;j>i;j--){
timerctl.timers[j] = timerctl.timers[j-i];
}
timerctl.using++;
/*插入到空位上*/
timerctl.timers[i] =timer;
timerctl.next = timerctl.timers[0]->timeout;
io_store_eflags(e);
return;
}
现在重新调整FIFO缓冲区
struct FIFO32{
int *buf;
int p,q,size,free,flags;
}
void fifo32_init(struct FIFO32 *fifo, int size, int *buf)
/* FIFO缓冲区的初始化*/
{
fifo->size = size;
fifo->buf = buf;
fifo->free = size; /*空*/
fifo->flags = 0;
fifo->p = 0; /*写入位置*/
fifo->q = 0; /*读取位置*/
return;
}
int fifo32_put(struct FIFO32 *fifo, int data)
/*给FIFO发送数据并储存在FIFO中*/
{
if (fifo->free == 0) {
/*没有空余空间,溢出*/
fifo->flags |= FLAGS_OVERRUN;
return -1;
}
fifo->buf[fifo->p] = data;
fifo->p++;
if (fifo->p == fifo->size) {
fifo->p = 0;
}
fifo->free--;
return 0;
}
int fifo32_get(struct FIFO32 *fifo)
/*从FIFO取得一个数据*/
{
int data;
if (fifo->free == fifo->size) {
/*当缓冲区为空的情况下返回-1*/
return -1;
}
data = fifo->buf[fifo->q];
fifo->q++;
if (fifo->q == fifo->size) {
fifo->q = 0;
}
fifo->free++;
return data;
}
int fifo32_status(struct FIFO32 *fifo)
/*报告已经存储了多少数据*/
{
return fifo->size - fifo->free;
}
加快中断处理
FIFO里面有一个取代移位处理的方法:读取一个数据以后不让后面的数据向前靠齐,而是改变下一次的数据读取地址。(类似链表的数据结构
)
struct TIMER {
struct TIMER *next;
unsigned int timeout, flags;
struct FIFO32 *fifo;
int data;
};
通过指针,可以减少后移操作,大大加快中断处理速度。
使用“哨兵”简化程序
加入哨兵
void init_pit(void)
{
int i;
struct TIMER *t;
io_out8(PIT_CTRL, 0x34);
io_out8(PIT_CNT0, 0x9c);
io_out8(PIT_CNT0, 0x2e);
timerctl.count = 0;
for (i = 0; i < MAX_TIMER; i++) {
timerctl.timers0[i].flags = 0; /* 没有使用 */
}
t = timer_alloc(); /* 取得一个 */
t->timeout = 0xffffffff;
t->flags = TIMER_FLAGS_USING;
t->next = 0; /* 末尾 */
timerctl.t0 = t; /* 因为现在只有哨兵,所以他就在最前面*/
timerctl.next = 0xffffffff; /* 因为只有哨兵,所以下一个超时时刻就是哨兵的时刻 */
timerctl.using = 1;
return;
}
原来采用线性表优化定时器会产生四个情况
1.运行中的定时器
2.插入到最前面
3.插入到s和t之间
4.插入到最后面
加入哨兵后只有1和4俩种情况。