30天自制操作系统日志第12天

上传人:汽*** 文档编号:509821718 上传时间:2023-12-19 格式:DOCX 页数:11 大小:25KB
返回 下载 相关 举报
30天自制操作系统日志第12天_第1页
第1页 / 共11页
30天自制操作系统日志第12天_第2页
第2页 / 共11页
30天自制操作系统日志第12天_第3页
第3页 / 共11页
30天自制操作系统日志第12天_第4页
第4页 / 共11页
30天自制操作系统日志第12天_第5页
第5页 / 共11页
点击查看更多>>
资源描述

《30天自制操作系统日志第12天》由会员分享,可在线阅读,更多相关《30天自制操作系统日志第12天(11页珍藏版)》请在金锄头文库上搜索。

1、操作系统实验日志学号20160810520姓名甘昆禄专业年级班级智能1601实验日期2018.12.12实验项目第12天:定时器(1)一、实验主要内容1、使用定时器和计量时间终于要定时器了,定时器还是挺有用的,是计算机不可缺少的,特别是和中断联系起来。计时器用在很多程序中,就从功能上来说,就好像微波炉一样,你设定一个时间,然后从 现在开始计时,到那个时间的时候提醒你。可以用在过一定时间要完成某种动作或任务的事, 可以实现鼠标的光标闪烁、多任务等等。多任务的原理就是把时间分成一个个小小的时间片, 这个时间片就由定时器给出。定时器的原理:每隔一段时间往 CPU发送中断信号,因此CPU才不用自己去计

2、量时间。要用定时器,我们只要设定 PIT就好了。因为PIT连着IRQ,设定了 PIT就可以设定IRQ0 (也就是定时器对应的中断号)的中断间隔。和前面一样,PIT这样设定: AL=Ox34:OUT(Ox43)AL); 八1=中断周期的低8位;OUT(0x40,AL); AL=中断周期的高8位;OUT(0x40,AL);那么这里我们中断的频率是由时钟周期和设定的数值决定的,频率 =主频/设定的数值,如 果设定数值为11932,那么就可以得到100Hz的中断频率,也就是一秒中断 100次。11932的16进制就是0x2e9c所以我们把高低位依次用out发送到对应端口,如下:define PIT_C

3、TRL 0x0C43 #define PIT_CNTO 0x0040void(voidj( iOOuta(PIT_CTRL, 0x34 : iQ_out8(FIT_CNT0. 0x9c); logouts (PIT_CmO, 0x2e); return; 1这样中断就弄好了,那么定时中断后做什么呢,我们就编写定时中断的函数,这里要用到 汇编:_asm_inthandler20: PUSH ES PUSH DS PUSHAD MOVEAX,ESPPUSH EAX MOVAX,SSMOVDS,AXMOVES,AXCALL _inthandler20 POP EAX POPAD POP DS POP

4、 ES IRETD再然后就在dsctbl.c中注册这一中断函数: void init_gdtidt(void)(中略) /* IDT 设置*/set_gatedesc(idt + 0x20, (int) asm_inthandler20, 2 * 8, AR_INTGATE32);set_gatedesc(idt + 0x21, (int) asm_inthandler21,2 * 8, AR_INTGATE32);set_gatedesc(idt + 0x27, (int) asm_inthandler27, 2 * 8, AR_INTGATE32); set_gatedesc(idt +

5、0x2c, (int) asm_inthandler2c, 2 * 8, AR_INTGATE32);return;)这里我们让程序什么都不做,只是通知 PIC中断接收完了。之后我们想要做什么,在函数 里添加就好了。这里我们试试让定时器中断计数。我们定义一个变量count,然后一次中断加一,最后显示在我们之前准备好的窗口。这个 count应该算作我们一个定时器的成员,所以我 们把它放进结构体中,便于管理。然后在中断函数中让它加一,功能就做好了。bootpack.h 中:struct TIMERCTL unsigned int count;)timer.c 中:void inthandler20

6、(int *esp)io_out8(PIC0_OCW2, 0x60); /* 把 IRQ-00信号接收完了的信息通知给 PIC */ timerctl.count+;)2、超时功能超时,这个名字为什么这样起?就是说定时超过了限定的时间,就去做一件事情。很重要 的一个功能,定时器很多都这么用吧。这时我们就要完善定时器管理结构体。struct TIMERCTL unsigned int count;unsigned int tineout;struct FIF08 unsigned char data;);这里timeout就是我们限定的时间,时问到我们就往FIFO里发送数据。前面我们知道,FIF

7、O有数据就可以在主函数里做我们想做的一些事情了,而不是放在中断函数里面做,这样是很不科学的。我们在每次中断函数里将timeout减一,减到0就往FIFO传信息,主函数就会有相 应的动作。void settlmer (unsigned int timeout, struct FIFO8 *fifo, uwigned ctiw data) (int eflags;flaga = io_loadof lags();io_cli.();匕imereti.timeout m timeout;timerctl4fifo = fifo;timereti.data data;io_store_eflag3 J

8、oflags)f return;)这里我们在处理IRQ0的,要是又有其他中断进来就麻烦了,就先保存原来中断的状态,再禁 止中断我们想要10秒让主函数做一次动作,那么就要设置timeout为1000,这样1000/100=10秒,10FIFO就接收到信息,显示10secoelse if (fifo8 status!=)(i = fifo8_get (fitimerfifo); /* i:(力弓 4二寸石 Az 冷 IC) */io_sti ();putfonts8_a3c (buyback, binfo-scrnxf 色,C0L8_FFFFFFJ *10 I jec ; sheet refres

9、h(sht back, . t 三那么我们很多程序当然不满足于使用一个定时器的,我们需要使用多个。这样,我们就多定义一个定时器结构体,将定时器的成员放在里面。原来的定时器管理结构体就管理这些定时器结构体,跟前面图层很类似。struct TIMER unsigned int timeout, flags;/* 标志计时器的状态 */struct FIFO8 *fifo;unsigned char data;struct TIMERCTL unsigned int count, next, using;struct TIMER timers0MAX_TIMER;MAX_TIMER是500,就是最多

10、我们可以使用500个定时器,定500个不同时间,当然不同定 时器定相同时间也可以。这样我们每个定时器都有自己的限定时间 timeout 了,到达对应的时 问,对应定时器的FIFO就会接受到消息,程序就会去处理该定时器到时要做的事情。void inthandler20(int *esp)int i;io outa (PICO_OCW2r ; i* IRQ-00J*/timereti * count+;3 for (i = 0; i MAX TIMER; 1.+)(二if (timerctl.timerij - flags = TIMER_FLAGS_USING) time ret 1. t im

11、er i . timeout-;if (timereti.timeril.timeout = ) tinerctl.timeri.flags = TIMERFLAGS ALLOC;f ifot put (timerct.L timer i i fif o, timerctl i timer i .data); ). )return;主函数那里,我们就用像鼠标、键盘一样判断FIFO的方式去更改我们定时器要完成的事就好了。3、加快中断处理定时器的中断处理程序要保证高效率,需要进行一些优化,这里就是介绍优化的方法。1、前面的方法是我们设置好了 timeout,每一次中断,我们都要对每个定时器的tim

12、eout进行修改,修改timeout要对内存进行读写,我们知道这比寄存器的速度慢得多。所以我们改变策略,timeout不变,让我们的count+加好了,count加到和timeout 一样的 时间,不就表示定到时了吗,就这么做。?_ id Inthandler20 (ii,L *eap)int i;iO OUtQ (PIC0 QCW2, LM ) ;/* IRQ 00受付完了有 P工Ct二通如 */timerctlcount+;q for (1 = ; i MAX TIMER; i+) 3if (tirnerctl .timer j ,flags = T-MF:R_FLAGS_USTNG) J

13、if (timereti.timeri- timeout = timerctl-count) (timerctl.timeri.flags = TIMER FLAGS _ALLOC;f i fo put (t imereti +1i . f i f q , imereti . tzmer i . data);return;2、对于一个操作系统来说,会有多个定时器,假设该操作系统维护了500个定时器,当每一次定时中断发生时(这里我们设定1秒发生100次中断),调用中断处理程序,中断处理程序会对这500个定时器进行if判断,看哪些正在被使用,这样1秒内,就会 有500X100=10000次if判断

14、,而中断处理程序最讲究节省时间。实际上,我们不必每 发生一次定时中断就去对这 500个定时器进行判断。因为假设我们使用了500个定时器中的10个,而10个定时器中最小的超时时间是10s,即10s后才触发第一个定时器, 而在这10s内,会进行10000X10=10万次无用的if判断,如果能省去这10万次if判断 会是对性能的一次了不起的提升。这里采取的优化策略是:我们维护一个next链,即10个正在被使用的定时器按照超时时间由小到大形成next链,一开始next表示最小的超时时间(本例中为10s),这样每一次调用中断处理程序,先将当前时间count和next进行比较,如果count timerctl.count) return; / the next time has not arrived, so finish

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 办公文档 > 演讲稿/致辞

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号