Linux/Qt/C下如何检测USB设备断开连接++
我正在编写一个系统(X-Platform Windows/Linux),该系统使用 FTDI USB 芯片与自定义设备进行通信。 我使用他们的 D2XX 驱动程序进行设备打开/关闭/读/写。 到目前为止,一切都很好。
我需要知道设备何时断开连接,以便程序可以正常响应。 目前,在 Windows 下,应用程序突然意外关闭。 在Linux下,当设备断开连接时,会出现分段故障。
我在 Windows 下找到了有关监听 WM_DEVICECHANGE 消息的信息。 不过我还没有找到如何在Windows下检测这个事件。 有与内核交互的设备驱动程序级别的信息。 但是,我不知道如何在应用程序级别执行此操作。 FTDI 驱动程序不提供任何此类服务。
该系统采用Qt框架和C++编写。 设备驱动程序是FTDI的D2XX驱动程序。
有人能指出我正确的方向吗?
非常感谢! 朱迪
I'm writing a system (X-Platform Windows/Linux) that talks to a custom device using an FTDI USB chip. I use their D2XX driver for device open/close/read/write. So far, so good.
I need to know when the device is disconnected so the program can respond gracefully. At present, under Windows the application receives a sudden unexpected close. Under Linux, when the device is disconnected, there is a sgementation fault.
I have found informaiton under Windows about listening for the WM_DEVICECHANGE message. However, I have not found how to detect this event under Windows. There is information for the device driver level interacting with the kernel. However, I can't figure out how to do this at an application level. The FTDI driver does not offer any such service.
The system is written using the Qt framework with C++. The device driver is FTDI's D2XX driver.
Can anyone point me in the right direction?
Thanks so much in advance!
Judy
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您可能需要使用 HAL (freedesktop.org 的硬件抽象层)。
将来您可能会想要使用 DeviceKit。 这是一个解决 HAL 的许多问题的项目。 但它尚未被所有主要发行版采用(我认为只有 Fedora),所以您现在可能不想使用它。
编辑:正如 Jeach 所说,您可以使用 udev还。 我不建议这样做,因为它的级别要低得多,并且更难编程,但如果延迟非常重要,这可能是最好的选择。
You'll probably want to use HAL (freedesktop.org's Hardware Abstraction Layer).
In the future you will probably want to use DeviceKit. It is a project fix the many problems with HAL. It hasn't been adopted by all major distros yet though (I think just Fedora), so you probably don't want to use it right now.
Edit: As Jeach said, you can use udev also. I wouldn't suggest this, as it is much lower level, and harder to program, but if latency is very important, this might be the best option.
虽然我要告诉你的内容不会直接回答你的问题,但它可能会给你下一步行动带来提示。
我使用“/etc/udev/rules.d/”中配置的 udev 规则来运行各种脚本。 当 USB 设备连接/断开连接时,我运行一个脚本,将 HUP 信号发送到我的二进制文件。 由于我的要求可以处理一点滞后,所以它对我来说非常适合。
但我的观点是,也许有一个 udev 库,您可以以编程方式(而不是脚本)链接到并注册事件。
希望它有帮助...祝你好运!
Although what I'm about to tell you won't directly answer your question, it may give you a hint as to your next move.
I use udev rules configured in '/etc/udev/rules.d/' which run various scripts. When a USB device gets connected/disconnected I run a script which sends a HUP signal to my binary. Since my requirements can handle a bit of lag it works perfectly fine for me.
But my point is that maybe there is a udev library you can link to and register events programmatically (instead of scripts).
Hope it helps... good luck!
显然,您必须为不同的操作系统编写不同的实现,除非您想创建一个连续运行的线程:
如果 numDevs 与之前的检查相比发生了变化,则枚举设备。
如果您像我一样并且不太喜欢在 USB 设备上进行这种连续轮询,那么您将必须针对您的特定操作系统。
以下是 FTDI 的一些示例代码的链接:
http://www.ftdichip.com/Support/SoftwareExamples/CodeExamples/VC.htm
示例7展示了如何在Windows上检测USB插入和拔出:
http://www.ftdichip.com/Support/Documents/AppNotes/AN_152_Detecting_USB_ %20Device_Insertion_and_Removal.pdf
在 Linux 上,我个人推荐使用 udev。
此代码用于枚举设备:
此代码我放入一个单独的线程中,等待接收插入或删除事件,
当您复制/粘贴此代码时,某些函数和变量显然未定义。
我保留检测到的设备列表,以检查路径和其他信息,例如插入设备的位置 ID。 我稍后需要通过 FT_OPEN_BY_LOCATION 向 FT_OpenEx 提供位置 ID。 为了获取位置 ID,我读取了以下文件的内容:
我不能保证位置 ID 是正确的,但到目前为止它似乎对我有用。
You obviously have to write different implementations for the different operating systems unless you want to create a thread to continuously run:
and enumerate the devices if numDevs changed compared to previous checks.
If you are like me and don't really like to do that sort of continuous polling on your USB devices then you will have to target your specific operating system.
Here's a link to some sample code from FTDI:
http://www.ftdichip.com/Support/SoftwareExamples/CodeExamples/VC.htm
Example 7 shows how to detect the USB insertion and removal on windows:
http://www.ftdichip.com/Support/Documents/AppNotes/AN_152_Detecting_USB_%20Device_Insertion_and_Removal.pdf
On Linux I can personally recommend using udev.
This code is for enumerating the devices:
This code I put in a separate thread that waits to receive an insertion or a removal event
some of the functions and variables are obviously not defined when you copy/paste this code.
I keep a list of detected devices to check the path and other information like the location ID of the inserted device. I need the location ID later to FT_OpenEx via FT_OPEN_BY_LOCATION. To get the location id I read the contents of the following files:
I can't guarantee that the locationid is correct but it seemed to work for me until now.
我最近有一个项目涉及通过 FTDI 芯片进行读取。 我也尝试过使用 libftdi,但发现使用 /dev/ttyUSB* 进行读写要简单得多。 这样就可以使用QFile('/dev/ttyUSB*')进行写入和读取了。 您还可以检查设备是否确实存在并且不会出现段错误。 当然,这并不是一种非常“平台无关”的方式。 要获得独立于平台的方法,您可以使用 Qt 的串行库。
I recently had a project which involved reading via an FTDI chip. I also tried using libftdi but found out that it is much simpler to use /dev/ttyUSB* for reading and writing. This way, you can use QFile('/dev/ttyUSB*') to write and read. You can also check if the device actually exists and it won't segfault. Of course, this is not a very 'Platform independent' way. To get a platform independent method, you can use a Serial library for Qt.
不要忘记您在这里有两个问题:
Zifre 已经解决了第一个问题。
但第二个问题仍然存在:当设备被删除时,你的 Linux 应用程序不应该出现段错误,我认为这两个问题是无关的:如果设备在写入或读取系统调用过程中被删除,那么这些系统调用将返回在收到任何通知之前出现错误,这不应该给您的应用程序带来段错误。
Don't forget that you have two problems here :
The first problem has been adressed by Zifre.
But the second problem remains : your Linux app should not be segfaulting when the device is removed, and I think the two problems are unrelated : if the device is removed in the middle of a write or read system call, then those system call will return with an error before you get any notification, and this should not segfault your app.