背景资料:
我目前有一个连接到 USB 端口的硬件设备。硬件设备负责将精确的周期性消息发送到它反过来连接的各种网络上。在硬件设备内部,我有几个 Microchip dsPIC。有两种操作模式。
一种情况是将简单的“作业”发送到 dsPIC,而 dsPIC 又可以以 0.001 毫秒的精度发送精确的消息。这种架构对于更复杂的消息传递并不理想,我们需要发送一个周期性数据包,该数据包会根据 PC 应用程序中发生的事件而变化。因此,我们有第二种操作模式,我们的 PC 应用程序将发送周期性消息,而 dsPIC 只需转换和发送响应。顺便说一下,所有这些对于我们软件的最终用户来说都是透明的。我们的硬件设备是用于汽车领域的测试工具。
目前,我们使用 FTDI 的 USB 转串行芯片和 FTDI Windows 驱动程序将硬件连接到我们的 PC 软件。
问题在于,在我们从 PC 发送消息的模式 2 中,我们能够达到的最佳效果是平均硬件范围约为 1 毫秒。我们受到 Windows 内核抢占。我尝试了许多“技巧”来改进,例如:
- 尽可能确保我们的读取器和写入器线程存在于单独的 CPU 关联上。
- 增加写入器的线程优先级,同时降低读取器的线程优先级。
- 通知用户在使用我们的软件时关闭屏幕保护程序和其他应用程序。
- 用 CreateTimerQueueTimer 调用替换 createthread 调用。
我们所有的软件都是用 C/C++ 编写的。我对高级 Windows 编程非常熟悉和熟悉;比如IO Completions、Overlapped I/O、无锁线程队列(真的是一种设计策略)、sockets、线程、信号量等等……
但是,我对 Windows 驱动程序开发一无所知。我已经阅读了一些关于 KMDF、UDMF 和 WDM 的论文。
我希望经验丰富的 Windows 内核模式驱动程序开发人员会在这里做出回应......
下一个版本。我们的硬件可以选择替换 FTDI 芯片并使用 dsPIC 的 USB 接口,或者可能将开源 Linux FTDI 东西移植到 Windows 并继续在我们的自定义驱动程序中使用 FTDI 芯片。我认为通过访问 PC 端的内核模式驱动程序,我可以建立一个内核驱动程序,它可以以更精确的间隔发送周期性消息,而无需抢占和/或可能利用 DMA。
我们的业务中有一个竞争对手,我认为他的工具与他们的工具完全相似。据我所知,用户空间应用程序调度线程的时间不能超过 1 毫秒。我们目前在一个线程中使用 timeGetTime。我已经体验过定时器队列(通过 CreateTimerQueueTimer),但没有真正的改进。
WDM 是实现更精确时序的正确方法吗?
我们的竞争对手如何实现从 Windows 驱动的信号到他们的硬件的非常精确的时序,他们确实加载了一个内核驱动程序 (.sys),他们的设备和我们的一样在 USB2.0 上运行。
如果 WDM 是要走的路,我可以就我应该研究哪些内核函数来设置时序获得一些建议吗?谢谢阅读