lvhaow
驱动小牛
驱动小牛
  • 注册日期2001-10-31
  • 最后登录2018-05-29
  • 粉丝0
  • 关注0
  • 积分44分
  • 威望35点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
  • 社区居民
阅读:1294回复:3

在driverstudio下,我对系统线程的理解和做法对么?50分

楼主#
更多 发布于:2002-11-25 00:08
中断方式的WDM模式9052PCI卡驱动,中断间隔不到100ms,一次中断要输出1M数据,原来驱动设计方法是,APP层上异步写,写过后即组织下一批数据。IRP下来后,排入队列。中断到来时,在中断服务中,检查队列中有无待处的IRP,如有,申请一个DPC,在DPC例程中,将队列中的IRP取出,直接输出,输出完毕后,将IRP完成返回;APP上等待IRP完成的事件后,再将组织好的下一批数据写下来。

由于这种方法占用处理器时间太多,一开始由于APP上只写了数据输出部分,所以除了计算机对别的操作(如MOUSE)响应变得迟钝了之外,没显出处理器不够用;但现在APP上其它的功能都加上了,共计有32个文件的读,以及1M字节的逐一字节处理,结果处理器就不够用了,总是有前一个IRP已经完成,但数据还没组织好,中断发生时,并没有IRP下来,致使中断落空。因此,除了着手在APP上想办法之外,驱动占用太多资源,也不得不考虑节省的方法了!
    DPC中直接输出数据,CPU等于只在做这一项工作,使用系统线程来作,是不是可以将CPU与PCI的速度差的时间节省下来呢?《WDM驱动设计》上,称系统线程通常是用来做那种不能中断CPU的外设的驱动,以便于进行轮循!
    今天着手看driverstudio的随机文档中关于系统线程的部分以及其提供的范例,虽然看得云山雾绕,但也有了些模糊的认识,在这里说给大佬们听听,看我理解地对不对,以及我对新驱动的设想是否合理:(关于系统线程的部分基本上是从范例上抄来的,天下程序一大抄,只要抄对就行)

一:关于增加一个系统线程的步骤:
1:创建一个KSystemThread类的子类,命名为SysThread,增加两个公共成员变量
KInterlockedList<IRP> m_Queue;
KSemaphore              m_Mailbox;
2:在Device类中,定义一个SysThread类的实例作为成员,命名为m_Thread,定义一个成员函数MyThread(),作为系统线程的主函数。

3:在驱动的设备类构建函数MyDevice::MyDevice()中,调用m_Thread.Start(LinkTo( MyThread ),this)启动系统线程,并将线程函数链接到 MyThread()函数上。

二:如何完成我所希望的数据输出操作。
SysThread类中增加的成员函数POST,在范例中显然是用于传递一个IRP指针的。因此,我考虑解决方法如下:
1:当APP执行了一个写操作,IRP传到Write(KIrp I)函数时,Write()立刻将这个IRP挂起,然后将此IRP作为参数,调用m_Thread.m_Queue.InsertTail(I);将当前IRP的地址加入m_Queue对象的列表中。
2:当一个中断到来的时,在中断服务程序中,调用m_Thread.m_Mailbox.Signal();将m_Mailbox对象置为有信号状态。
3:系统线程的主函数中,使用一个无条件循环,循环体的前部,加入 m_Thread.m_Mailbox.Wait();阻塞线程的执行,直到m_Mailbox有信号,然后从m_Queue中提出首部的IRP,进行处理;程序如下:
  KIrp I = m_Thread.m_Queue.RemoveHead();
  KMemory Mem(NULL);
  Mem=KMemory(I.Mdl());
  PUCHAR pBuffer = (PUCHAR) Mem.MapToSystemSpace();
  m_MemoryRange1.outd(0,PULONG(pBuffer),dwTotalSize);
  I.Information() = dwTotalSize*4;
  I.Complete(STATUS_SUCCESS);

实际上,上面的处理程序,和原来的程序中的DPC基本相似,只是原程序使用的是系统队列来暂存IRP,而现在则是将IRP挂起,使用m_Queue对象来保存挂起的IRP地址,从语句上我看不出还有什么区别,因此,能不能达到我所希望的节省系统资源的目的,实在心里没底。

三:几个问题:
1:系统线程,是不是可以在任何位置启动,比如在DeviceControl(KIrp I)中由APP控制启动?
2:中断服务中,可否执行m_Thread.m_Mailbox.Signal();我记得有位大佬说过在中断中连置位事件对象都不可以。
3:IRP挂起(PENDING)后再将其地址压入m_Queue对列有什么意义?这是从范例上抄来的句子,我搞不懂为什么要挂起来!
4:系统线程是不是真能节省CPU时间??这才是我最关心的问题。

最新喜欢:

jinghuirenjinghu...
lvhaow
ysy
ysy
驱动中牛
驱动中牛
  • 注册日期2002-02-18
  • 最后登录2008-08-25
  • 粉丝0
  • 关注0
  • 积分201分
  • 威望29点
  • 贡献值0点
  • 好评度19点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2002-11-25 09:25
其实系统线程和普通线程在运行机制上没有什么区别,他们都公平竞争cpu时间。他们不过运行在系统空间,在一些函数的调用上减少从用户空间切换到系统空间的的开销。
我觉的“APP层上异步写,写过后即组织下一批数据”这句话有问题,是不是考虑在APP异步写的同时另外开辟线程进行数据处理?
你的pci卡处理数据是不是就是映射1M的卡上内存,然后把数据放进这块内存后启动传输?这样的话大可不必在DPC内部进行,可已使用系统线程或者工作者线程。如果用DMA的话我不是很清楚。
lvhaow
驱动小牛
驱动小牛
  • 注册日期2001-10-31
  • 最后登录2018-05-29
  • 粉丝0
  • 关注0
  • 积分44分
  • 威望35点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
  • 社区居民
板凳#
发布于:2002-11-26 12:42
数据处理是在APP上做的,单用一个线程。所谓处理,只是把1M字节数据的排列顺序按要求重新排列,然后将其输出,也就是在APP上用写文件的方式把输出请求发给驱动。
我希望在驱动中开一个系统线程专门用来输出数据。原来在DPC中输出数据,由于一次传输的数据量较大,输出期间独占了CPU,把其它线程都阻断了,这在APP上都能表现出来(系统响应变得迟钝了)。
lvhaow
ysy
ysy
驱动中牛
驱动中牛
  • 注册日期2002-02-18
  • 最后登录2008-08-25
  • 粉丝0
  • 关注0
  • 积分201分
  • 威望29点
  • 贡献值0点
  • 好评度19点
  • 原创分0分
  • 专家分0分
地板#
发布于:2002-11-26 13:45
应改是可以的.我还是想问一下,你的pci卡映射了多少内存?
游客

返回顶部