-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Windows: Get proper string description of usb serial port via DeviceIoControl. #725
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
|
I was exited to try this code, but unfortunately I did not have success with it on Windows 11 for listing the properties of BBC micro:bit v2. With unmodified Pyserial I got: but after applying your patch I got even less information: The value of the Product field I am looking for, is "BBC micro:bit CMSIS-DAP" and usbview.exe does report it like this. |
|
I also tested it on Windows 10 and got the same result. I'm attaching my usbview report from Windows 11, in case you'd like to investigate, why I didn't get the expected result. |
By the way, are you using the latest commit ( Since the earliest commit I forgot about the composite device. the latest commit should fix these issues. |
Yes, I was using https://github.com/pyserial/pyserial/blob/c090f45667c68b7a7259a38de7a59b49b016f851/serial/tools/list_ports_windows.py and https://github.com/pyserial/pyserial/blob/c090f45667c68b7a7259a38de7a59b49b016f851/serial/win32.py for patching my Pyserial. I'll see later, whether the patched version works with my other devices. |
|
I now tested your patch with more devices (SAMD-s from Adafruit, Rasperry Pi Pico, several ESP32-S2 and S3 devices, some plain ESP32 devices with CP and CH UART adapters, an ESP8266 with CP2104 UART adapter, a NRF52 device) and found out that with most of these it worked nicely. The few, that showed proper Product (and Manufacturer) in usbview.exe, but not with your patch, were:
Please let me know, if you need usbview report for any of these! |
I read the USBView report you provided for the BBC micro:bit v2. It looks like my patch misidentifies the composite device as a noncomposite device. This will result in an error similar to the one below. Reads the string description as a composite device: Reads the string description as a noncomposite device: Could you provide me with reports from the USB Device Tree Viewer for these devices? It could provide me with more information to solve the problem. Thanks a lot. |
|
Here come the reports from USB Device Tree Viewer: |
|
Thanks a lot! After your last commit, pyserial reports proper Product, Manufacturer and Serial number for my BBC micro:bit. I'll test with my other boards tomorrow. Great job! |
|
With all my boards I now get proper values for Manufacurer, Product and Serial number. For getting proper Interface, I'm combining your solution with #571. Thank you! |
I refactored the code and added comments to enhance readability. Thank you for your testing, I think this patch is ready to be merged now. |
…oControl. Based on pyserial#725 by @chinaheyu Co-Authored-By: 交叉坐标的星辰 <59406481+chinaheyu@users.noreply.github.com>
I noticed that you want to merge with #571. I've added the feature to read the interface (via I put the old code for getting usb info into |
Don't need pyserial#571 anymore, as pyserial#725 takes care of interface as well.
That's great! Somehow I missed it. I tested it and it works beautifully. I don't need #571 anymore. |
|
It is now possible to get the correct interface field on most devices. |
|
Unfortunately does not seem to work well on devices with multiple serial interfaces, like FT4232H that has 4 UARTs. Unpatched result: Patched result: Location is the same for all COM Ports, e.g. So there is no way to distinguish between the COM ports by location. For linux this seems to have been solved in PR #141 Here's an example of szHardwareID_str: FTDIBUS\VID_0403+PID_6011+6&1AD5555C&0&1&1\0000 |
Since the FTDI driver hides the location information, we had to do some dirty work to get the interface number. I referenced libusbp to parse the hardware id to get the interface number. But apparently it doesn't work. Could you provide me with reports from the USB Device Tree Viewer for your devices? |
ab3ced2 to
c3ffa2c
Compare
|
After the last change most of my devices seem to work same as before, but I get following exception with 3 of my ESP32-C3 devices: Here is the UsbTreeview report for one of them: SeeedXiaoESP32C3.txt The weird thing is that I get this exception only sometimes, usually the first time I call |
|
@chinaheyu, after latest changes I don't get these errors anymore, but I now discovered that with any of these problematic ESP32-C3 devices plugged in, I now occasionally get long delays before It looks like there are two methods, which may cause the delay:
The first call of either method gets stuck in The problem is present also in your older commits, e.g. aivarannamaa@bdab39f#diff-f9966444f1fafc17f351672a463bdcff7833ad6c14a68d9432329a458d1608b0 The next call to Unfortunately I can't create a simple script for reproducing this. The earlier I call Can you recommend some tweaks I could try to learn more about this problem? |
|
Adding to my last comment -- the |
|
@aivarannamaa Thank you very much for your feedback. This is a very peculiar issue that I haven't encountered before. Overall, the problem should be related to the device (ESP32-32 C3) as it seems not to respond with its string description promptly. Subsequent requests are fast because DeviceIoControl caches the result. After receiving your feedback, I purchased a Seeed Xiao ESP32 C3 board, which should arrive today. I will do my best to resolve this peculiar issue. Additionally, I used the same API as in USBView, so did you encounter this issue when using USBView? |
|
@waterfallwhitebread Thank you for providing the screenshot. The latest patch should be able to correctly retrieve the location field of the FT4232H chip. |
|
@aivarannamaa You are right, if another process opens and closes the serial port, it blocks DeviceIOControl. This phenomenon only occurs on ESP32 C3 devices. I also found an issue on StackOverflow that may be relevant: https://stackoverflow.com/questions/6749681/freeze-on-serialport-open-deviceiocontrol-getcommstate-with-usbser-sys I can't fix this, but we can cache the usb info to avoid calling DeviceIOControl every time. The latest commit should be helpful for your problem. |
|
@chinaheyu, thanks! Curiously, now I can't reproduce this problem anymore. |
|
Any chance it gets merged into pyserial ? Thanks for this @chinaheyu ! |
|
Hi! Is there anything that Adafruit can do to move inclusion of this patch forward? It would be very helpful to us. |
|
I have a report that this method doesn't work with Windows 7 (keirf/greaseweazle#472). Is that unexpected? |
|
It should theoretically support Windows 7 (though I haven't tested it), as Cfgmgr32 API has been available since Windows 2000. I plan to test it on Windows 7 next to see if I can reproduce the issue. Thank you @keirf . |
Sorry, I can't reproduce the problem. The patch works fine in Windows 7. Can you provide more detailed python version and system information? The system image used above: Windows 7 Ultimate with Service Pack 1 (7601.24214) (x64) |
|
Thanks for testing! My user's report is on I will get Hyper-V running and try a Win7 VM myself. At the end of the day though, Win7 is long EOL, and soon Python 3.8 will be too. And that's the last Python version to support Win7. So the problem will solve itself soon enough. :) |
|
Okay, I went to the hassle of installing Win7 in a VM to look at this, and what a pain that was! But I have reproduced the issue. I think it must depend on the device or its driver. Specifically, my "Greaseweazle" device enumerates as a generic CDC ACM device, and on Windows 7/8 requires use of Zadig to associate the driver usbser.sys (Zadig calls this "USB Serial (CDC)"). Curiously, the default pyserial list_port_windows.py finds the correct product string for this device on Windows 7 ("Greaseweazle"), which it fails to do on Windows 10/11. And on Win7 your list_port_windows.py fails to list it at all. Perhaps it gets filtered out somewhere? By the way, as a baseline I tested a PL2303 as regular proprietary USB serial device. This worked fine on Windows 7 with your implementation. |
|
I also confirmed this issue on Windows 8.1. This is perhaps more related to Zadig, or pre-Win10 usbser.sys. |
This fixes Zadig-bound devices pre Windows 10 Refs pyserial/pyserial#725
|
Is there any update on this? This functionality (corrected device naming on windows) is actually addressed in a couple of the pending PRs, but does not seem to ever get completed. It would be great if one of these could reach completion as this functionality would be very helpful for a number of different of implementations. |
|
I have a report of failure with empty port name (keirf/greaseweazle#549) with the following fix: keirf/greaseweazle#550 Could you please consider this fix, or equivalent, for this upstream PR? |
It seems that some serial devices are not assigned a COMx-style port name. I'm not sure what's causing this, but simply skipping these devices can prevent the program from crashing. In theory, even without a port name, we can still open these serial devices via their interface path, which might serve as an alternative when the port name is None (possibly a better solution than just skipping them). That said, keirf/greaseweazle#550 is correct and necessary. Many thanks for the fix. |
This fixes empty name fields in the Windows serial port list. Fixes #549 Refs pyserial/pyserial#725
|
Hello, Thanks. |
|
Hello, This also solved my issue on Windows 11 and interface field, with a USB composite (2 CDC ACM) device. Thank you. |
This pull request helps to get serial port information in windows consistent with other platforms (including description, hwid, serial_number, location, manufacturer, product and interface).
Since the original code didn't get the product string and the manufacturer string was often wrong (inconsistent with Linux and MacOS results), I rewrote all the code in
list_ports_windows.pyto request the usb device descriptor viaDeviceIoControlto get the correct string.Unpatched result:
Patched result:
Linux result:
This code gets the same product string, manufacturer string and serial number as in usbview.
Caution: This patch almost completely rewrites the
list_ports_windows.pyfile, and merging it with any other patch that also includeslist_ports_windows.pywill likely result in unpredictable conflicts.This patch shares the same goal as the following PR — to obtain USB descriptors consistent with those on other platforms:
This patch offers a more comprehensive solution to these related issues:
-hyphen. #771We have tested and verified this patch on the following chips:
This patch has no external dependencies. Before it is merged, you can copy the
serial/tools/list_ports_windows.pyfile from this patch and importcomportsfrom it as a quick workaround.