最近,公司使用STM32F407,开发了一个基于USB的CAN设备(内部称为CAN盒子),USB的固件使用STM32官方提供的BSP进行开发,而没有做任何修改的这个固件,只支持3个EndPoints: Control Enpoint, In/Out Interrupt Endpoint.
为了在Windows端操作该设备的CAN,我们拟定使用c#开发一个上位机程序,刚开始,看上去特别顺利,因为STM32官方固件使得该设备称为一个HID设备,所以windows自动给CAN盒子添加上了HID驱动,使用windows默认的hidusb.sys。阅读了windows官方对hid设备的指导,Introduction to HID Concepts ,于是很快就写了基于HidD_GetAttributes, HidD_GetHidGuid, HidD_GetManufacturerString 来读出设备信息,一切很顺利后,重头戏开始了,接下来,就是使用CreateFile创建读写句柄,然后使用WriteFile,ReadFile和预定义的协议来操作CAN,WriteFile使用同步写,ReadFile使用异步读,当执行完WriteFile时,使用Bus Hound来监测命令是否写下去了,一切貌似顺利,从Bus Hound看到了输入/输出命令,并且CAN通道的指示灯都亮起了。于是赶紧去执行ReadFile,看看是否能读出返回的结果,没有任何反应,以为是自己不熟悉,于是开始了对ReadFile各种资料查找,什么同步,异步,多线程,Bus Hound手动输入命令等等,期间还找了多年开发usb设备驱动的哥们远程协助,无果。
在尝试了各种关于HID设备资料和windows WDK HID例程之后,觉得需要自己动手写一个minidriver for usb了。
这时候,又想起了NI公司的LabView,安装一个称为VISA驱动之后,接下来就可以操作这个盒子了(并且taobao上找了几个使用STM32开发的USB板子,上位机也停留在使用LabView来操作USB)。我是否应该走LabView的路子,于是想起了刚开始查到VISA驱动使用的WinUSB(这个事情,我一开始,就注意到了,只可惜LabView的VISA工具,只能在windows7上成功安装和使用,并且驱动使用的WinUSB.sys,我的系统为Windows 10),How to Access a USB Device by Using WinUSB Functions,于是找来重读了几遍,确定了接下来的步骤。
1. 找到了zadig 来给设备安装上WinUSB驱动.
2. 按照How to Access a USB Device by Using WinUSB Functions ,和 Write a Windows desktop app based on the WinUSB template生成驱动和应用案例
3. 先关闭windows10的驱动签名,然后安装上2中新的驱动
4. 尝试读出设备信息,顺利后,参考了 Jan Axelson's lakeview research 和 例程 winusb_cs_31.zip
5. 使用WinUSB_PipeWrite和WinUSB_PipeRead接口,完成前面失败的工作。