标签:des style blog http color io os 使用 java
1、第一版:数组方式[09d]
>_<" 在bootpack.h里面的timer.c的声明和结构体:
1 /* timer.c */ 2 #define MAX_TIMER 500 //最多500个定时器 3 struct TIMER{ 4 unsigned int flags;//flags记录各个寄存器状态 5 unsigned int timeout;//用来记录离超时还有多长时间,一旦这个剩余时间为0,程序就往FIFO缓冲区里发送数据,定时器就是用这种方法通知HariMain时间到了 6 struct FIFO8 *fifo;//消息队列 7 unsigned char data;//该定时器标志,用来向消息队列写的标志信息 8 }; 9 struct TIMERCTL{ 10 unsigned int count;//计数 11 struct TIMER timer[MAX_TIMER]; 12 }; 13 extern struct TIMERCTL timerctl; 14 void init_pit(void);//定时器初始化100hz 15 struct TIMER *timer_alloc(void);//分配定时器,遍历所有找到第一个没有使用的分配 16 void timer_free(struct TIMER *timer);//释放定时器 17 void timer_init(struct TIMER *timer, struct FIFO8 *fifo, unsigned char data);//初始化定时器,fifo和标志符data 18 void timer_settime(struct TIMER *timer, unsigned int timeout);//定时器设置,设定剩余时间 19 void inthandler20(int *esp);//定时器中断函数 20 //void settimer(unsigned int timeout, struct FIFO8 *fifo, unsigned char data);//设置定时器
1 /* PIT 定时器 */ 2 3 #include "bootpack.h" 4 5 #define PIT_CTRL 0x0043 6 #define PIT_CNT0 0x0040 7 8 struct TIMERCTL timerctl; 9 //struct TIMERCTL timerctl;//计数器结构体实例化 10 #define TIMER_FLAGS_ALLOC 1 //已配置状态 11 #define TIMER_FLAGS_USING 2 //定时器运行中 12 13 ///////////////////////////////////////////////////////////////////////////////////// 14 //功能:定时器初始化,要3次OUT指令,(0x34->0x34)(中断周期低8位->0x40)(高8位->0x40) 15 //参数: 16 //附加:设置结果为主频/设置数,这里中断周期设置为0x2e9c,大约为100hz,具体搜:IRQ0中断周期变更PIT 17 void init_pit(void) 18 { 19 int i; 20 io_out8(PIT_CTRL, 0x34); 21 io_out8(PIT_CNT0, 0x9c); 22 io_out8(PIT_CNT0, 0x2e); 23 timerctl.count=0;//初始化计数为0 24 // timerctl.timeout=0;//剩余时间为0 25 for(i=0;i<MAX_TIMER;i++){//初始化所有定时器未使用 26 timerctl.timer[i].flags=0;//未使用 27 } 28 return; 29 } 30 ///////////////////////////////////////////////////////////////////////////////////// 31 //功能:分配定时器 32 //参数: 33 struct TIMER *timer_alloc(void) 34 { 35 int i; 36 for (i = 0; i < MAX_TIMER; i++) {//从开始开始找没有使用的定时器,找到后设置为分配状态,反回 37 if (timerctl.timer[i].flags == 0) { 38 timerctl.timer[i].flags = TIMER_FLAGS_ALLOC; 39 return &timerctl.timer[i]; 40 } 41 } 42 return 0; /* 没有找到 */ 43 } 44 ///////////////////////////////////////////////////////////////////////////////////// 45 //功能:释放定时器,直接把标志位设为0即可 46 //参数: 47 void timer_free(struct TIMER *timer) 48 { 49 timer->flags = 0; /* 未使用 */ 50 return; 51 } 52 ///////////////////////////////////////////////////////////////////////////////////// 53 //功能:初始化定时器,赋值fifo,设置标志位 54 //参数: 55 void timer_init(struct TIMER *timer, struct FIFO8 *fifo, unsigned char data) 56 { 57 timer->fifo = fifo; 58 timer->data = data; 59 return; 60 } 61 ///////////////////////////////////////////////////////////////////////////////////// 62 //功能:设置timer 63 //参数:输入剩余时间 64 void timer_settime(struct TIMER *timer, unsigned int timeout) 65 { 66 timer->timeout = timeout; 67 timer->flags = TIMER_FLAGS_USING; 68 return; 69 } 70 71 72 ///////////////////////////////////////////////////////////////////////////////////// 73 //功能:定时器中断处理程序,和键盘鼠标中断类似 74 //参数: 75 void inthandler20(int *esp) 76 { 77 int i; 78 io_out8(PIC0_OCW2, 0x60); /* 把IRQ-00信号接受完了的信息通知给PIC */ 79 timerctl.count++;//计数 80 for (i = 0; i < MAX_TIMER; i++) {//遍历所有的定时器 81 if (timerctl.timer[i].flags == TIMER_FLAGS_USING) {//有正在使用的就剩余时间-- 82 timerctl.timer[i].timeout--; 83 if (timerctl.timer[i].timeout == 0) {//剩余时间为0就直接将标志位改为非使用,将消息写进队列 84 timerctl.timer[i].flags = TIMER_FLAGS_ALLOC; 85 fifo8_put(timerctl.timer[i].fifo, timerctl.timer[i].data);////剩余时间为0就向缓冲区写数据,用这种方法通知main函数 86 } 87 } 88 } 89 return; 90 } 91 ///////////////////////////////////////////////////////////////////////////////////// 92 //功能:定时器设置,因为没有设置好就发生中断就会混乱,所以先关闭中断,然后恢复中断 93 //参数:初始剩余时间,fifo,标志data(向缓冲区写的数据) 94 //void settimer(unsigned int timeout, struct FIFO8 *fifo, unsigned char data) 95 //{ 96 // int eflags; 97 // eflags = io_load_eflags(); 98 // io_cli(); 99 // timerctl.timeout = timeout; 100 // timerctl.fifo = fifo; 101 // timerctl.data = data; 102 // io_store_eflags(eflags); 103 // return; 104 //}
>_<" 这里定义一个计时器结构体和一个管理计时器的结构体,其中TIMERCTL中含有一个timer的数组,用来实现最多MAX_TIMER个计时器的管理。这里:
PS: 很显然,这种处理速度是很慢很慢的!接下来要一步步的优化~
2、有序数组[09g]
>_<" 在bootpack.h里面的timer.c的声明和结构体:
1 /* timer.c */ 2 #define MAX_TIMER 500 //最多500个定时器 3 struct TIMER{ 4 unsigned int flags;//flags记录各个寄存器状态 5 unsigned int timeout;//用来记录离超时还有多长时间,一旦这个剩余时间为0,程序就往FIFO缓冲区里发送数据,定时器就是用这种方法通知HariMain时间到了 6 struct FIFO8 *fifo;//消息队列 7 unsigned char data;//该定时器标志,用来向消息队列写的标志信息 8 }; 9 struct TIMERCTL { 10 unsigned int count, next, using;//using表示有几个定时器处于活动中,next是下一个设定时间点,count是累加时间轴 11 struct TIMER *timers[MAX_TIMER];//记录按照某种顺序存好的定时器地址 12 struct TIMER timers0[MAX_TIMER]; 13 }; 14 extern struct TIMERCTL timerctl; 15 void init_pit(void);//定时器初始化100hz 16 struct TIMER *timer_alloc(void);//分配定时器,遍历所有找到第一个没有使用的分配 17 void timer_free(struct TIMER *timer);//释放定时器 18 void timer_init(struct TIMER *timer, struct FIFO8 *fifo, unsigned char data);//初始化定时器,fifo和标志符data 19 void timer_settime(struct TIMER *timer, unsigned int timeout);//定时器设置,设定剩余时间 20 void inthandler20(int *esp);//定时器中断函数 21 //void settimer(unsigned int timeout, struct FIFO8 *fifo, unsigned char data);//设置定时器
1 /* PIT 定时器 */ 2 3 #include "bootpack.h" 4 5 #define PIT_CTRL 0x0043 6 #define PIT_CNT0 0x0040 7 8 struct TIMERCTL timerctl; 9 //struct TIMERCTL timerctl;//计数器结构体实例化 10 #define TIMER_FLAGS_ALLOC 1 //已配置状态 11 #define TIMER_FLAGS_USING 2 //定时器运行中 12 13 ///////////////////////////////////////////////////////////////////////////////////// 14 //功能:定时器初始化,要3次OUT指令,(0x34->0x34)(中断周期低8位->0x40)(高8位->0x40) 15 //参数: 16 //附加:设置结果为主频/设置数,这里中断周期设置为0x2e9c,大约为100hz,具体搜:IRQ0中断周期变更PIT 17 void init_pit(void) 18 { 19 int i; 20 io_out8(PIT_CTRL, 0x34); 21 io_out8(PIT_CNT0, 0x9c); 22 io_out8(PIT_CNT0, 0x2e); 23 timerctl.count=0;//初始化计数为0 24 timerctl.next=0xffffffff;//初始时没有计时器所以下一个为无穷大 25 timerctl.using=0;//正在使用的定时器为0 26 27 for(i=0;i<MAX_TIMER;i++){//初始化所有定时器未使用 28 timerctl.timers0[i].flags=0;//未使用 29 } 30 return; 31 } 32 ///////////////////////////////////////////////////////////////////////////////////// 33 //功能:分配定时器 34 //参数: 35 struct TIMER *timer_alloc(void) 36 { 37 int i; 38 for (i = 0; i < MAX_TIMER; i++) {//从开始开始找没有使用的定时器,找到后设置为分配状态,反回 39 if (timerctl.timers0[i].flags == 0) { 40 timerctl.timers0[i].flags = TIMER_FLAGS_ALLOC; 41 return &timerctl.timers0[i]; 42 } 43 } 44 return 0; /* 没有找到 */ 45 } 46 ///////////////////////////////////////////////////////////////////////////////////// 47 //功能:释放定时器,直接把标志位设为0即可 48 //参数: 49 void timer_free(struct TIMER *timer) 50 { 51 timer->flags = 0; /* 未使用 */ 52 return; 53 } 54 ///////////////////////////////////////////////////////////////////////////////////// 55 //功能:初始化定时器,赋值fifo,设置标志位 56 //参数: 57 void timer_init(struct TIMER *timer, struct FIFO8 *fifo, unsigned char data) 58 { 59 timer->fifo = fifo; 60 timer->data = data; 61 return; 62 } 63 ///////////////////////////////////////////////////////////////////////////////////// 64 //功能:设置timer 65 //参数:输入定时时间 66 void timer_settime(struct TIMER *timer, unsigned int timeout) 67 { 68 int e, i, j; 69 timer->timeout = timeout + timerctl.count;//当前时间+定时器定时时间 70 timer->flags = TIMER_FLAGS_USING;//设置成正在使用 71 e = io_load_eflags();//保存寄存器,关中断 72 io_cli(); 73 /* 搜索注册位置 */ 74 for (i = 0; i < timerctl.using; i++) {//把所有timeout从小到大排列,找出新建的定时器插入位置 75 if (timerctl.timers[i]->timeout >= timer->timeout) { 76 break; 77 } 78 } 79 /* i之后的全部后移1位 */ 80 for (j = timerctl.using; j > i; j--) { 81 timerctl.timers[j] = timerctl.timers[j - 1]; 82 } 83 timerctl.using++; 84 /* 插入到空位上 */ 85 timerctl.timers[i] = timer; 86 timerctl.next = timerctl.timers[0]->timeout; 87 io_store_eflags(e);//恢复寄存器 88 return; 89 } 90 91 92 ///////////////////////////////////////////////////////////////////////////////////// 93 //功能:定时器中断处理程序,和键盘鼠标中断类似 94 //参数: 95 void inthandler20(int *esp) 96 { 97 int i,j; 98 io_out8(PIC0_OCW2, 0x60); /* 把IRQ-00信号接受完了的信息通知给PIC */ 99 timerctl.count++;//计数 100 if(timerctl.next>timerctl.count){//如果下一个还没计数完毕就直接返回 101 return; 102 } 103 for(i=0;i<timerctl.using;i++){ 104 if(timerctl.timers[i]->timeout>timerctl.count){ 105 break; 106 }//从前往后遍历,一旦发现有计时未完成的计时器就跳出循环 107 /*除了上面的情况,都是定时已达的定时器*/ 108 timerctl.timers[i]->flags = TIMER_FLAGS_ALLOC; 109 fifo8_put(timerctl.timers[i]->fifo, timerctl.timers[i]->data); 110 } 111 /*从上面循环结束后,i的值就是前面有几个超时的定时器*/ 112 timerctl.using-=i;//所以减去超时的定时器 113 for(j=0;j<timerctl.using;j++){//将后面的定时器前移 114 timerctl.timers[j]=timerctl.timers[i+j]; 115 } 116 if(timerctl.using>0){//判断是否还有正在使用的定时器,有就用下一个剩余时间更新next 117 timerctl.next=timerctl.timers[0]->timeout; 118 }else{//没有,就直接设为无穷大 119 timerctl.next=0xffffffff; 120 } 121 return; 122 }
>_<" 这里和上一个的最大的不同之处是:上一个采用暴力遍历每一个的情况,而这个则采用插入和删除等操作时就事先调整好数组。此外为了方便实现这一数据结构,TIMERCTL里除了用timers0[]数组保存计时器外,还声明一个timers[]数组用来记录按照某种顺序排好的定时器,这里的using是出于活动中的定时器数,next是下一个设定的时间:
3、线性表[10h]
>_<" 在bootpack.h里面的timer.c的声明和结构体:
1 /* timer.c */ 2 #define MAX_TIMER 500 //最多500个定时器 3 struct TIMER{ 4 struct TIMER *next;//用来指下一个即将超时的定时器地址 5 unsigned int flags;//flags记录各个寄存器状态 6 unsigned int timeout;//用来记录离超时还有多长时间,一旦这个剩余时间为0,程序就往FIFO缓冲区里发送数据,定时器就是用这种方法通知HariMain时间到了 7 struct FIFO32 *fifo;//消息队列 8 int data;//该定时器标志,用来向消息队列写的标志信息 9 }; 10 struct TIMERCTL { 11 unsigned int count, next, using;//using表示有几个定时器处于活动中,next是下一个设定时间点,count是累加时间轴 12 struct TIMER *t0;//记录按照某种顺序存好的定时器地址,头指针 13 struct TIMER timers0[MAX_TIMER]; 14 }; 15 extern struct TIMERCTL timerctl; 16 void init_pit(void);//定时器初始化100hz 17 struct TIMER *timer_alloc(void);//分配定时器,遍历所有找到第一个没有使用的分配 18 void timer_free(struct TIMER *timer);//释放定时器 19 void timer_init(struct TIMER *timer, struct FIFO32 *fifo, int data);//初始化定时器,fifo和标志符data 20 void timer_settime(struct TIMER *timer, unsigned int timeout);//定时器设置,设定剩余时间 21 void inthandler20(int *esp);//定时器中断函数
1 /* PIT 定时器 */ 2 3 #include "bootpack.h" 4 5 #define PIT_CTRL 0x0043 6 #define PIT_CNT0 0x0040 7 8 struct TIMERCTL timerctl; 9 //struct TIMERCTL timerctl;//计数器结构体实例化 10 #define TIMER_FLAGS_ALLOC 1 //已配置状态 11 #define TIMER_FLAGS_USING 2 //定时器运行中 12 13 ///////////////////////////////////////////////////////////////////////////////////// 14 //功能:定时器初始化,要3次OUT指令,(0x34->0x34)(中断周期低8位->0x40)(高8位->0x40) 15 //参数: 16 //附加:设置结果为主频/设置数,这里中断周期设置为0x2e9c,大约为100hz,具体搜:IRQ0中断周期变更PIT 17 void init_pit(void) 18 { 19 int i; 20 io_out8(PIT_CTRL, 0x34); 21 io_out8(PIT_CNT0, 0x9c); 22 io_out8(PIT_CNT0, 0x2e); 23 timerctl.count=0;//初始化计数为0 24 timerctl.next=0xffffffff;//初始时没有计时器所以下一个为无穷大 25 timerctl.using=0;//正在使用的定时器为0 26 27 for(i=0;i<MAX_TIMER;i++){//初始化所有定时器未使用 28 timerctl.timers0[i].flags=0;//未使用 29 } 30 return; 31 } 32 ///////////////////////////////////////////////////////////////////////////////////// 33 //功能:分配定时器 34 //参数: 35 struct TIMER *timer_alloc(void) 36 { 37 int i; 38 for (i = 0; i < MAX_TIMER; i++) {//从开始开始找没有使用的定时器,找到后设置为分配状态,反回 39 if (timerctl.timers0[i].flags == 0) { 40 timerctl.timers0[i].flags = TIMER_FLAGS_ALLOC; 41 return &timerctl.timers0[i]; 42 } 43 } 44 return 0; /* 没有找到 */ 45 } 46 ///////////////////////////////////////////////////////////////////////////////////// 47 //功能:释放定时器,直接把标志位设为0即可 48 //参数: 49 void timer_free(struct TIMER *timer) 50 { 51 timer->flags = 0; /* 未使用 */ 52 return; 53 } 54 ///////////////////////////////////////////////////////////////////////////////////// 55 //功能:初始化定时器,赋值fifo,设置标志位 56 //参数: 57 void timer_init(struct TIMER *timer, struct FIFO32 *fifo, int data) 58 { 59 timer->fifo = fifo; 60 timer->data = data; 61 return; 62 } 63 ///////////////////////////////////////////////////////////////////////////////////// 64 //功能:设置timer 65 //参数:输入定时时间 66 void timer_settime(struct TIMER *timer, unsigned int timeout) 67 { 68 int e; 69 struct TIMER *t,*s; 70 timer->timeout = timeout + timerctl.count;//当前时间+定时器定时时间 71 timer->flags = TIMER_FLAGS_USING;//设置成正在使用 72 e = io_load_eflags();//保存寄存器,关中断 73 io_cli(); 74 75 timerctl.using++; 76 if (timerctl.using == 1) { 77 /* 处于运行状态的只有一个 */ 78 timerctl.t0 = timer; 79 timer->next = 0; /* 没有下一个 */ 80 timerctl.next = timer->timeout; 81 io_store_eflags(e); 82 return; 83 } 84 t = timerctl.t0; 85 if (timer->timeout <= t->timeout) { 86 /* 插入最前面 */ 87 timerctl.t0 = timer; 88 timer->next = t; /* 下面是t */ 89 timerctl.next = timer->timeout; 90 io_store_eflags(e); 91 return; 92 } 93 /* 搜寻插入位置 */ 94 for (;;) { 95 s = t; 96 t = t->next; 97 if (t == 0) { 98 break; /* 最后面 */ 99 } 100 if (timer->timeout <= t->timeout) { 101 /* 插入到s和t之间 */ 102 s->next = timer; /* s的先一个是timer */ 103 timer->next = t; /* timer的下一个是t */ 104 io_store_eflags(e); 105 return; 106 } 107 } 108 /* 插入最后面的情况 */ 109 s->next = timer; 110 timer->next = 0; 111 io_store_eflags(e); 112 return; 113 } 114 115 ///////////////////////////////////////////////////////////////////////////////////// 116 //功能:定时器中断处理程序,和键盘鼠标中断类似 117 //参数: 118 void inthandler20(int *esp) 119 { 120 int i,j; 121 struct TIMER *timer; 122 io_out8(PIC0_OCW2, 0x60); /* 把IRQ-00信号接受完了的信息通知给PIC */ 123 timerctl.count++;//计数 124 if(timerctl.next>timerctl.count){//如果下一个还没计数完毕就直接返回 125 return; 126 } 127 timer=timerctl.t0;//把最前面的地址赋址给timer 128 for(i=0;i<timerctl.using;i++){ 129 if(timer->timeout>timerctl.count){ 130 break; 131 }//从前往后遍历,一旦发现有计时未完成的计时器就跳出循环 132 /*除了上面的情况,都是定时已达的定时器*/ 133 timer->flags = TIMER_FLAGS_ALLOC; 134 fifo32_put(timer->fifo, timer->data); 135 timer=timer->next;//下一个定时器的地址赋址给timer 136 } 137 /*从上面循环结束后,i的值就是前面有几个超时的定时器*/ 138 timerctl.using-=i;//所以减去超时的定时器 139 timerctl.t0=timer;//新移位 140 //timectl.next设定 141 if(timerctl.using>0){//判断是否还有正在使用的定时器,有就用下一个剩余时间更新next 142 timerctl.next=timerctl.t0->timeout; 143 }else{//没有,就直接设为无穷大 144 timerctl.next=0xffffffff; 145 } 146 return; 147 }
>_<" 通过上面2个优化的实例发现,用数组避免不了大量数据的前移和后移,于是我们就想到了用指针来构成线性表,这样交换插入都可以在几步之能完成!这里在结构体TIMER里加入了*next指针,用来存放下一个即将超时的定时器地址。
PS: 在使用线性表之后发现TIMERCTR结构体里的TIMER数组可以只要一个首地址就行了,于是也简化为*t0
4、使用“哨兵”简化程序[10i]
>_<" 在bootpack.h里面的timer.c的声明和结构体:
1 /* timer.c */ 2 #define MAX_TIMER 500 //最多500个定时器 3 struct TIMER{ 4 struct TIMER *next;//用来指下一个即将超时的定时器地址 5 unsigned int flags;//flags记录各个寄存器状态 6 unsigned int timeout;//用来记录离超时还有多长时间,一旦这个剩余时间为0,程序就往FIFO缓冲区里发送数据,定时器就是用这种方法通知HariMain时间到了 7 struct FIFO32 *fifo;//消息队列 8 int data;//该定时器标志,用来向消息队列写的标志信息 9 }; 10 struct TIMERCTL { 11 unsigned int count, next;//next是下一个设定时间点,count是累加时间轴 12 struct TIMER *t0;//记录按照某种顺序存好的定时器地址,头指针 13 struct TIMER timers0[MAX_TIMER]; 14 }; 15 extern struct TIMERCTL timerctl; 16 void init_pit(void);//定时器初始化100hz 17 struct TIMER *timer_alloc(void);//分配定时器,遍历所有找到第一个没有使用的分配 18 void timer_free(struct TIMER *timer);//释放定时器 19 void timer_init(struct TIMER *timer, struct FIFO32 *fifo, int data);//初始化定时器,fifo和标志符data 20 void timer_settime(struct TIMER *timer, unsigned int timeout);//定时器设置,设定剩余时间 21 void inthandler20(int *esp);//定时器中断函数
1 /* PIT 定时器 */ 2 3 #include "bootpack.h" 4 5 #define PIT_CTRL 0x0043 6 #define PIT_CNT0 0x0040 7 8 struct TIMERCTL timerctl; 9 //struct TIMERCTL timerctl;//计数器结构体实例化 10 #define TIMER_FLAGS_ALLOC 1 //已配置状态 11 #define TIMER_FLAGS_USING 2 //定时器运行中 12 13 ///////////////////////////////////////////////////////////////////////////////////// 14 //功能:定时器初始化,要3次OUT指令,(0x34->0x34)(中断周期低8位->0x40)(高8位->0x40) 15 //参数: 16 //附加:设置结果为主频/设置数,这里中断周期设置为0x2e9c,大约为100hz,具体搜:IRQ0中断周期变更PIT 17 void init_pit(void) 18 { 19 int i; 20 struct TIMER *t; 21 io_out8(PIT_CTRL, 0x34); 22 io_out8(PIT_CNT0, 0x9c); 23 io_out8(PIT_CNT0, 0x2e); 24 timerctl.count=0;//初始化计数为0 25 for(i=0;i<MAX_TIMER;i++){//初始化所有定时器未使用 26 timerctl.timers0[i].flags=0;//未使用 27 } 28 t=timer_alloc();//取得一个 29 t->timeout=0xffffffff; 30 t->flags=TIMER_FLAGS_USING; 31 t->next=0;//末尾 32 timerctl.t0=t;//现在就一个 33 timerctl.next=0xffffffff;//下一个计时器为哨兵,所以下一个为无穷大 34 return; 35 } 36 ///////////////////////////////////////////////////////////////////////////////////// 37 //功能:分配定时器 38 //参数: 39 struct TIMER *timer_alloc(void) 40 { 41 int i; 42 for (i = 0; i < MAX_TIMER; i++) {//从开始开始找没有使用的定时器,找到后设置为分配状态,反回 43 if (timerctl.timers0[i].flags == 0) { 44 timerctl.timers0[i].flags = TIMER_FLAGS_ALLOC; 45 return &timerctl.timers0[i]; 46 } 47 } 48 return 0; /* 没有找到 */ 49 } 50 ///////////////////////////////////////////////////////////////////////////////////// 51 //功能:释放定时器,直接把标志位设为0即可 52 //参数: 53 void timer_free(struct TIMER *timer) 54 { 55 timer->flags = 0; /* 未使用 */ 56 return; 57 } 58 ///////////////////////////////////////////////////////////////////////////////////// 59 //功能:初始化定时器,赋值fifo,设置标志位 60 //参数: 61 void timer_init(struct TIMER *timer, struct FIFO32 *fifo, int data) 62 { 63 timer->fifo = fifo; 64 timer->data = data; 65 return; 66 } 67 ///////////////////////////////////////////////////////////////////////////////////// 68 //功能:设置timer 69 //参数:输入定时时间 70 void timer_settime(struct TIMER *timer, unsigned int timeout) 71 { 72 int e; 73 struct TIMER *t,*s; 74 timer->timeout = timeout + timerctl.count;//当前时间+定时器定时时间 75 timer->flags = TIMER_FLAGS_USING;//设置成正在使用 76 e = io_load_eflags();//保存寄存器,关中断 77 io_cli(); 78 79 t=timerctl.t0; 80 if (timer->timeout <= t->timeout) { 81 /* 插入最前面的情况 */ 82 timerctl.t0 = timer; 83 timer->next = t; /* 下面是设定t */ 84 timerctl.next = timer->timeout; 85 io_store_eflags(e); 86 return; 87 } 88 /* 搜寻插入位置 */ 89 for (;;) { 90 s = t; 91 t = t->next; 92 if (timer->timeout <= t->timeout) { 93 /* 插入s和t之间 */ 94 s->next = timer; /* s下一个是timer */ 95 timer->next = t; /* timer下一个是t */ 96 io_store_eflags(e); 97 return; 98 } 99 } 100 return; 101 } 102 103 ///////////////////////////////////////////////////////////////////////////////////// 104 //功能:定时器中断处理程序,和键盘鼠标中断类似 105 //参数: 106 void inthandler20(int *esp) 107 { 108 struct TIMER *timer; 109 io_out8(PIC0_OCW2, 0x60); /* 把IRQ-00信号接受完了的信息通知给PIC */ 110 timerctl.count++; 111 if (timerctl.next > timerctl.count) {//如果下一个还没计数完毕就直接返回 112 return; 113 } 114 timer = timerctl.t0; //把最前面的地址赋址给timer 115 for (;;) { 116 if (timer->timeout > timerctl.count) { 117 break; 118 }//从前往后遍历,一旦发现有计时未完成的计时器就跳出循环 119 /*除了上面的情况,都是定时已达的定时器*/ 120 timer->flags = TIMER_FLAGS_ALLOC; 121 fifo32_put(timer->fifo, timer->data); 122 timer = timer->next;//下一个定时器的地址赋址给timer 123 } 124 timerctl.t0 = timer;//新移位 125 timerctl.next = timer->timeout;//timectl.next设定 126 return; 127 }
>_<" “哨兵”听起来高大上,其实就是在10g的线性表的基础上多加一个空结点,这样就能把插入结点时的判断条件减少很多,用来达到精简代码的目的~其实由于多了一个空结点,这种处理虽然代码精简了,但是其速度就没有上面纯的线性表快了~这里就不仔细介绍细节的东西了,相信大家一看就懂~
5、工程代码链接:
包含上面项目工程的所有代码:http://pan.baidu.com/s/1bnEkjWN
LZ主页:http://www.cnblogs.com/zjutlitao/
1 /* 2 同一占用一个fifo,这里: 3 0~1 光标闪烁用定时器 4 3 3秒定时器 5 10 10秒定时器 6 256~511 键盘输入(从键盘控制器读入的值再加上256) 7 512~767 鼠标输入(从键盘控制器读入的值再加上512) 8 */
标签:des style blog http color io os 使用 java
原文地址:http://www.cnblogs.com/zjutlitao/p/3983279.html