自从开始做USB的驱动程序这个项目,我就开始了跟定时器没完没了的拉锯战……
第一仗,在DDK和手上有的驱动开发书上一通乱翻,终于,找到了几个宝贝函数:KeInitializeTimer,KeInitializeDpc,KeSetTimerEx。哈,这样做出来的定时器,最小定时单位是1ms,够满足我那8ms的要求了。照着例子研究了一下下,花了一个小时,终于做好了这样一个定时器,回调函数也能周期性的调用了,我心里这个美啊。
旗开得胜,马上在回调函数里开始大展身手了,加了若干代码之后,运行(不好意思,我不会调试sys,所以我的办法就是用debugview看调试信息,根据调试信息解决问题),蓝屏!
唉,真是乐极生悲。问题在哪里?不知道。怎么办?一行一行去掉代码,定位问题吧。无数次的蓝屏、重启之后,有一个可疑的函数冒出来了:IoBuildDeviceIoControlRequest。
在Leoyin的大力帮助下,我终于看清了DDK文档中的那句话:Callers of IoBuildDeviceIoControlRequest must be running at IRQL <= PASSIVE_LEVEL。咦,我的定时器回调函数是啥level?又是在Leoyin的教导下,用了KeGetCurrentIrql,完了,这个该死的回调函数,居然是什么Dispatch_level。
在DDK里寻觅良久,终于发现,只能把这个所谓的Level提高,而不能把它降低。这意味着啥?我根本不能用这个定时器了L
郁闷中。。。
怕什么,屡败屡战嘛,我跟定时问题的第二仗开始了。
既然在驱动里已经没有了可用的定时器,沿用我在用户模式下编程的思维,那就用线程吧。恩,这个主意真是不错,于是又DDK里一通搜索,哈,再加上书上看到的例子,首先,我做好了一个线程。线程函数里一个for(;;),这不就成了?现在的问题,无非是叫这个for循环能够乖乖的等上8ms而已嘛。KeWaitForSingleObject,嘻嘻,这可是一个现成的函数么嘛。好,说干就干,根据DDK的说法,这个函数在事件变成有信号和设置的时间超时两种情况下返回。恩,事件用来通知线程退出,时间就设成8ms,这不就ok了?
如此这般之后,哈哈,搞定!
于是开始了sys里一些功能的调试,慢慢的,各种功能都完善起来了,胜利指日可待了~~
这天,跟做硬件的同事联调程序,咦,为什么偶的程序放音放的这么慢?音箱里放出来的声音,就好像40年代初国民党的电台报新闻一样,那叫一个慢啊~
我尚在懵懂中,同事大叫:为什么你每隔15.625ms才读写一次数据啊?打开debugview,输出每次进入循环的间隔,没错,15.625ms,不是原来设想的8ms啊。
郁闷中。。。这一回,在01的指点下,取得了KeWaitForSingleObject返回超时状态的时间间隔,晕了,我明明设置了8ms,它为什么要15.625ms才返回超时呢?一不做二不休,干脆把时间值设成了最小的时间单位:100ns。得,还是15.625的时间间隔。
这下蔫了。本来就不懂所谓的驱动开发,是被领导赶鸭子上架的。好不容易想出来这个自以为得意的定时方法,原来根本就不灵,那我可如何是好啊?
没办法,跟领导老老实实的汇报了战果。领导到还体谅,既然驱动里这个时间没有办法调整,那就叫硬件开发的同事配合一下好了。
于是,以前的驱动里所有跟8ms的定时有关的东西,都被我改了一个遍。如此这般之后,忽又发现,这个15.625ms也根本不能保证啊!CPU忙着干这个干那个,也不是给你这个线程专用的啊!
眼看距离交差的时间越来越近,怎么办?还是DDK渊博啊,依然是到处撒网,乱搜索之后,我的眼睛一亮:KeSetBasePriorityThread。这下发了狠,一口气把我这个宝贝线程的优先级提高了10,哈哈。这下好了。任你多少个程序同时打开,我这个线程都规规矩矩老老实实的每15.625ms做一次循环。
看来,我跟定时问题这一仗,最终还是我赢了耶~虽说被诸位警告说乱改线程优先级很危险,可是,火烧眉毛,咱不得先顾眼前么。。。
离最后期间越来越近了,咱这设备的功能也越来越全了。终于熬到了今天,把程序打包,整理,交给了测试组的同事测试去喽~
终于交差了,心里这个美啊,中午这一觉,睡的真是格外香甜,要知道,为了这个破驱动,我可是整整一个月,每天工作13个小时还多,强烈缺觉啊。
一觉醒来,就看见测试的同事站在面前,热切的看着我,我心生寒意,感觉必定有状况。果不其然,在他的测试机器上,这设备居然不能好好干活的说!了解了问题之后,我感觉真想从这12楼上跳下去。呜呜呜,该死的KeWaitForSingleObject,在他的机器上,等待超时的间隔,居然又变了。我明明在好几种系统和不同的机器配置上测试了很多遍,自以为这是个不太会改变的常量了,它它它,为什么还是不老实啊!
唉,明天就是最后期限,我唯一期望的,就是我们亲戚的客户,千万不要使用会出状况的环境。。。过了明天,一定老老实实的,听Panic的话,找一个准确的不变的硬件的定时方法。。。