我目前有一个连接USB端口的硬件设备.硬件设备负责将精确的周期性消息发送到各种网络上,而这些网络又连接起来.在硬件设备内部,我有两个Microchip dsPIC.有两种操作模式.
一种情况是将简单的“作业”发送到dsPIC,然后可以发送精确到0.001厘米的精确消息.这种架构不适用于更复杂的消息传递,我们需要根据PC应用程序中发生的事件发送周期性数据包.因此,我们有第二种操作模式,我们的PC应用程序将发送周期性消息,dsPIC只是简单地转换和发送响应.顺便说一下,所有这一切对我们软件的最终用户都是透明的.我们的硬件设备是汽车领域中使用的测试工具.
目前,我们使用FTDI的USB转串口芯片和FTDI Windows驱动程序将硬件连接到我们的PC软件.
问题是在我们从PC发送消息的模式二中,我们能够实现的最佳平均硬件范围约为1ms.我们受到Windows内核抢占.我尝试过一些“技巧”来改进以下内容:
>确保我们的读者和编写器线程尽可能依靠单独的cpu关联.
>增加编写器的线程优先级,同时减少读取器的线程优先级.
>使用我们的软件时,通知用户关闭屏幕保护程序和其他应用程序.
>使用CreateTimerQueueTimer调用替换createthread调用.
我们所有的软件都是用C/C++编写的.我对高级Windows编程非常熟悉和熟悉;例如IO Completions,Overlapped I / O,无锁线程队列(实际上是一种设计策略),套接字,线程,信号量等等……
但是,我对Windows驱动程序开发一无所知.我已经阅读了几篇关于KMDF与UDMF和WDM的论文.
我希望经验丰富的Windows内核模式驱动程序开发人员会在这里做出回应……
下一轮.我们的硬件可以选择更换FTDI芯片并使用dsPIC的USB接口,或者可能将开源Linux FTDI内容移植到Windows,并继续在我们的自定义驱动程序中使用FTDI芯片.我想通过转到PC端的内核模式驱动程序,我可以建立一个内核驱动程序,可以更精确的间隔发送周期性消息,而不会抢占和/或可能利用DMA.
我们在我们的业务中有一个竞争对手,我认为它与他们的工具完全相似.据我所知,用户空间应用程序无法安排任何优于1ms的线程.我们目前在一个线程中使用timeGetTime.我已经体验过计时器队列(通过CreateTimerQueueTimer)而没有真正的改进.
WDM是实现更精确计时的正确方法吗?
我们的竞争对手如何实现从Windows驱动信号到硬件的非常精确的时序,并且它们加载内核驱动程序(.sys),并且它们的设备通过USB2.0运行,就像我们的一样.
但是,您无法访问许多功能,例如分页内存,或DPC级别的特定线程的内存空间,因为它们在任意上下文中运行.使用可以访问更多功能的APC将处理推迟到您自己的用户模式进程的上下文可能很有用.
内核线程在优先级方面没有得到任何特殊处理.从调度程序的角度来看,它们与用户线程相同.内核线程可以获得更多优先级更高的级别,但通常没有内核线程使用它们中的任何一个.我不认为你的瓶颈是线程优先.无论您的优先级数量多大都没关系,只有一个优先于其他人就足以让您成为最重要的“神线”.拥有最高优先级并不意味着你会得到持续的关注.操作系统仍然会暂停你的线程以运行其他操作系统,因此不会发生量子饥饿.
关于Windows抢占行为的另一个注意事项:当异步事件(GUI点击,定时器触发,I / O完成)发出线程信号时,Balance Set Manager会临时提升线程的优先级,以允许完成代码以较少的抢占完成处理.使用异步计时器处理程序应该提供足够的提升以防止至少对量子进行抢占.我想知道为什么你的代码不属于那个窗口.但是,似乎您不是唯一一个定时器精度有问题的人:http://www.virtualdub.org/blog/pivot/entry.php?id=272
我同意保罗关于驾驶员发展的复杂性,但只要你有充分的理由,这不是火箭科学,而是更多的努力.