-
Notifications
You must be signed in to change notification settings - Fork 69
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
DFU mode: improve programming robustness. #98
DFU mode: improve programming robustness. #98
Conversation
Thanks for thinking about this! I did not understand the click comment, what exactly happens in case of EPIPE without your patch applied? I'm thinking here it might be good to have a maximum number of retries, but perhaps you're saying that click swallows EPIPE completely, so this patch is in any case strictly better? |
As you can see here: https://github.com/pallets/click/blob/3984f9efce5a0d15f058e1abe1ea808c6abd243a/src/click/core.py#L944, click catches all (In the version I have been using, it catches When libusb1 returns a PIPE error, it raises So, when the error happens, without the patch, the programming stops immediately. However, there is no obvious feedback like a stacktrace, because this specific USBError is caught by click when handling the frequent CLI command event of writing to a closed pipe. Of course there will be no success message of the whole program/verify cycle. Unfortunately I did not know what to expect during my very first DFU programming try :( Also, the error happens so often (4-5 times during one full flash programming cycle), that it was impossible for me to do a full flash program in DFU mode. I only managed to program the bootloader without the patch, after some retries.
You're right of course, some limit to avoid an endless loop would be good. How would this be handled if |
2958b56
to
7350e45
Compare
I have changed the approach to try the ctrl transfer inside get_status up to three times in case of USBError/EPIPE. |
Thanks for the explanations! So this is about the I'm happy to merge this as-is if you're happy :) Regarding your original problem, I've never seen or heard of such frequent errors (we only had this kind of error in our deprecated web interface, which would interrupt flashing if users tabbed out). I wonder if it could be a bad connector, or what else could cause this. |
Exactly.
I've just verified on Windows 10 that the change doesn't seem to do any harm, either. Even though the programming also worked reliably without the patch! Same hardware where it is unstable on Linux (Ubuntu 20.04, Kernel 5.4.something).
I see the failures on two (somewhat different) Dell notebooks on Ubuntu 20.04 reliably. It's a Solo Hacker V1.2 having a USB-C plug + C-to-A adapter. I assume the adapter is passive. From my side you can merge if you feel comfortable to do so. Just don't blame me if bunches of Solo Hackers will be bricked in the next weeks ;-) |
The ctrl_transfer in dfu.get_status() might return usb.core.USBError with errno == EPIPE, seen when called in quick succession. This is the case when called from dfu.block_on_state(). The next call usually works. This change tries to catch this specific error and just re-tries up to two times in case it happens. Without this change, the error (and programming abort) might get undetected, as 'click' catches IOerror/EPIPE silently. This has significant potential to brick a device if you don't check the output and return code of 'solo' closely enough.
7350e45
to
dff5668
Compare
dfu.get_status() might return usb.core.USBError with errno == EPIPE,
when called in quick succession. This is the case when called from
dfu.block_on_state(). The next call usually works.
This change tries to catch this specific error and just re-tries in case
it happens.
Without this change, the error (and programming abort) might get
undetected, as click catches IOerror/EPIPE silently. This has
significant potential to brick a device.
This change addresses issue #97.