Skip to content
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

USB DFU never enters DFU mode, when composite device is enabled and mcuboot is used #14882

Closed
ghost opened this issue Mar 25, 2019 · 6 comments
Closed
Assignees
Labels
area: USB Universal Serial Bus bug The issue is a bug, or the PR is fixing a bug priority: low Low impact/importance bug

Comments

@ghost
Copy link

ghost commented Mar 25, 2019

Describe the bug
When trying to use USB DFU in a composite device, the device never enters DFU mode. When you try to download new firmware using dfu-util, it fails with the message Device still in Runtime Mode

To Reproduce

  • Add CONFIG_USB_COMPOSITE_DEVICE=y to config of the USB DFU sample.
  • Flash mcuboot and the sample to the device
  • Attempt a DFU using sudo dfu-util --alt 1 --download signed-zephyr.bin --i 0

Impact
We are unable to use USB DFU in our product the relies on USB communication.

Screenshots or console output
dfu-util output:

dfu-util 0.9

Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
Copyright 2010-2019 Tormod Volden and Stefan Schmidt
This program is Free Software and has ABSOLUTELY NO WARRANTY
Please report bugs to http://sourceforge.net/p/dfu-util/tickets/

dfu-util: Invalid DFU suffix signature
dfu-util: A valid DFU suffix will be required in a future dfu-util release!!!
Opening DFU capable USB device...
ID 2fe3:0100
Run-time device DFU version 0110
Claiming USB DFU Runtime Interface...
Determining device status: state = appIDLE, status = 0
Device really in Runtime Mode, send DFU detach request...
Resetting USB...
Opening DFU USB Device...
Claiming USB DFU Interface...
Setting Alternate Setting #1 ...
Determining device status: state = appDETACH, status = 0
dfu-util: Device still in Runtime Mode!

Zephyr output:

***** Booting Zephyr OS v1.14.0-rc1-1394-g972221423cde *****
[00:00:00.000,396] <inf> main: This device supports USB DFU class.

[00:00:03.748,168] <dbg> usb_dfu.dfu_custom_handle_req: DFU alternate setting 0
[00:00:03.748,352] <dbg> usb_dfu.dfu_class_handle_req: DFU_GETSTATUS: status 0, state 0
[00:00:04.004,852] <dbg> usb_dfu.dfu_class_handle_req: DFU_DETACH timeout 1000, state 0
[00:00:04.563,629] <dbg> usb_dfu.dfu_status_cb: USB device configured
[00:00:09.286,804] <dbg> usb_dfu.dfu_custom_handle_req: DFU alternate setting 1
[00:00:09.287,384] <dbg> usb_dfu.dfu_class_handle_req: DFU_GETSTATUS: status 0, state 1
[00:00:09.543,975] <dbg> usb_dfu.dfu_custom_handle_req: DFU alternate setting 0

Environment (please complete the following information):

  • OS: Linux (Ubuntu)
  • Toolchain: Zephyr SDK
  • Commit SHA: 9722214

Additional context
I'm am unsure wheter or not this is related to this issue, but if also enable CDC ACM in the config, the DFU usb interface is listed as 2 instead of 0, and dfu-util fails with dfu-util: Lost device after RESET? instead. After the first failed attempt, the interface number is 0 again and the issue is the same as above.

@ghost ghost added the bug The issue is a bug, or the PR is fixing a bug label Mar 25, 2019
@jfischer-no jfischer-no added priority: low Low impact/importance bug area: USB Universal Serial Bus labels Mar 25, 2019
@jfischer-no jfischer-no self-assigned this Mar 25, 2019
@Qbicz
Copy link
Collaborator

Qbicz commented Mar 25, 2019

Hi @pileghoff, I just wanted to open a similar issue. I tried to perform DFU in a composite device (HID class + DFU class) and this fails on Ubuntu, waiting for USB reset:

$ sudo dfu-util --alt 1 --download zephyr/zephyr_signed
.bin
dfu-util 0.8

Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
Copyright 2010-2014 Tormod Volden and Stefan Schmidt
This program is Free Software and has ABSOLUTELY NO WARRANTY
Please report bugs to dfu-util@lists.gnumonks.org

dfu-util: Invalid DFU suffix signature
dfu-util: A valid DFU suffix will be required in a future dfu-util release!!!
Opening DFU capable USB device...
ID 1915:52de
Run-time device DFU version 0110
Claiming USB DFU Runtime Interface...
Determining device status: state = appIDLE, status = 0
Device really in Runtime Mode, send DFU detach request...
Resetting USB...

dfu-util: Lost device after RESET?

Logs on the device during the update:

[05802312] <dbg> usb_device.usb_handle_control_transfer: ep 0, status 0
[05802314] <dbg> usb_device.usb_handle_request: ** 0 **
[05802314] <dbg> usb_device.custom_handler: bRequest 0x6, wIndex 0x0
[05802314] <dbg> usb_device.usb_handle_std_device_req: REQ_GET_DESCRIPTOR
[05802318] <dbg> usb_device.usb_handle_control_transfer: ep 80, status 2
[05802358] <dbg> usb_device.usb_handle_control_transfer: ep 0, status 0
[05802359] <dbg> usb_device.usb_handle_request: ** 0 **
[05802360] <dbg> usb_device.custom_handler: bRequest 0x6, wIndex 0x409
[05802360] <dbg> usb_device.usb_handle_std_device_req: REQ_GET_DESCRIPTOR
[05802364] <dbg> usb_device.usb_handle_control_transfer: ep 80, status 2
[05802398] <dbg> usb_device.usb_handle_control_transfer: ep 0, status 0
[05802399] <dbg> usb_device.usb_handle_request: ** 0 **
[05802400] <dbg> usb_device.custom_handler: bRequest 0xb, wIndex 0x0
[05802400] <dbg> usb_dfu.dfu_custom_handle_req: DFU alternate setting 0
[05802423] <dbg> usb_device.usb_handle_control_transfer: ep 0, status 0
[05802425] <dbg> usb_device.usb_handle_request: ** 1 **
[05802425] <dbg> usb_device.class_handler: bRequest 0x3, wIndex 0x0
[05802426] <dbg> usb_dfu.dfu_class_handle_req: DFU_GETSTATUS: status 0, state 0
[05802430] <dbg> usb_device.usb_handle_control_transfer: ep 80, status 2
[05810885] <dbg> usb_device.usb_handle_control_transfer: ep 0, status 0
[05810887] <dbg> usb_device.usb_handle_request: ** 1 **
[05810887] <dbg> usb_device.class_handler: bRequest 0x0, wIndex 0x0
[05810888] <dbg> usb_dfu.dfu_class_handle_req: DFU_DETACH timeout 1000, state 0
[05810986] <dbg> usb_hid.hid_status_composite_cb: cfg 0x2000bdb8 status 1
[05810987] <dbg> usb_hid.hid_do_status_cb: USB device reset detected
[05814039] <dbg> usb_hid.hid_status_composite_cb: cfg 0x2000bdb8 status 1
[05814039] <dbg> usb_hid.hid_do_status_cb: USB device reset detected
[05817300] <dbg> usb_device.usb_handle_control_transfer: ep 0, status 0
[05817302] <dbg> usb_device.usb_handle_request: ** 0 **
[05817302] <dbg> usb_device.usb_handle_std_device_req: REQ_GET_DESCRIPTOR
[05817306] <dbg> usb_device.usb_handle_control_transfer: ep 80, status 2
[05817955] <dbg> usb_device.usb_handle_control_transfer: ep 0, status 0
[05817956] <dbg> usb_device.usb_handle_request: ** 0 **
[05817957] <dbg> usb_device.usb_handle_std_device_req: REQ_GET_DESCRIPTOR
[05817961] <dbg> usb_device.usb_handle_control_transfer: ep 80, status 2
[05817999] <dbg> usb_device.usb_handle_control_transfer: ep 0, status 0
[05818000] <dbg> usb_device.usb_handle_request: ** 0 **
[05818001] <dbg> usb_device.usb_handle_std_device_req: REQ_GET_DESCRIPTOR
[05818006] <dbg> usb_device.usb_handle_control_transfer: ep 80, status 2

@Qbicz
Copy link
Collaborator

Qbicz commented Mar 26, 2019

Update: USB composite device is not found properly after reset requested by dfu-util. Reset is performed by the USB device, but it will not be recognized by host afterwards. During this reset, HID in HID class is disabled and is not reenabled again.

Logs on dfu-util side with triple verbosity:

sudo dfu-util --alt 1 --download zephyr/zephyr_signed.bin -v -v -v
dfu-util 0.8

Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
Copyright 2010-2014 Tormod Volden and Stefan Schmidt
This program is Free Software and has ABSOLUTELY NO WARRANTY
Please report bugs to dfu-util@lists.gnumonks.org

dfu-util: Invalid DFU suffix signature
dfu-util: A valid DFU suffix will be required in a future dfu-util release!!!
libusb: debug [libusb_get_device_list]
libusb: debug [libusb_get_device_descriptor]
libusb: debug [libusb_get_config_descriptor] index 0
libusb: debug [parse_configuration] skipping descriptor 0xb
libusb: debug [libusb_get_device_descriptor]
libusb: debug [libusb_get_config_descriptor] index 0
libusb: debug [libusb_get_device_descriptor]
libusb: debug [libusb_get_config_descriptor] index 0
libusb: debug [libusb_open] open 2.85
libusb: debug [usbi_add_pollfd] add fd 9 events 4
libusb: debug [libusb_alloc_transfer] transfer 0x9080a8
libusb: debug [libusb_submit_transfer] transfer 0x9080a8
libusb: debug [add_to_flying_list] arm timerfd for timeout in 1000ms (first in line)
libusb: debug [libusb_handle_events_timeout_completed] doing our own event handling
libusb: debug [handle_events] poll fds modified, reallocating
libusb: debug [handle_events] poll() 3 fds with timeout in 60000ms
libusb: debug [handle_events] poll() returned 1
libusb: debug [reap_for_handle] urb type=2 status=0 transferred=4
libusb: debug [handle_control_completion] handling completion status 0
libusb: debug [disarm_timerfd]
libusb: debug [usbi_handle_transfer_completion] transfer 0x9080a8 has callback 0x7fbed2871520
libusb: debug [sync_transfer_cb] actual_length=4
libusb: debug [libusb_free_transfer] transfer 0x9080a8
libusb: debug [libusb_alloc_transfer] transfer 0x9080a8
libusb: debug [libusb_submit_transfer] transfer 0x9080a8
libusb: debug [add_to_flying_list] arm timerfd for timeout in 1000ms (first in line)
libusb: debug [libusb_handle_events_timeout_completed] doing our own event handling
libusb: debug [handle_events] poll() 3 fds with timeout in 60000ms
libusb: debug [handle_events] poll() returned 1
libusb: debug [reap_for_handle] urb type=2 status=0 transferred=10
libusb: debug [handle_control_completion] handling completion status 0
libusb: debug [disarm_timerfd]
libusb: debug [usbi_handle_transfer_completion] transfer 0x9080a8 has callback 0x7fbed2871520
libusb: debug [sync_transfer_cb] actual_length=10
libusb: debug [libusb_free_transfer] transfer 0x9080a8
libusb: debug [libusb_close]
libusb: debug [usbi_remove_pollfd] remove fd 9
libusb: debug [libusb_get_device_descriptor]
libusb: debug [libusb_get_config_descriptor] index 0
libusb: debug [libusb_get_device_descriptor]
libusb: debug [libusb_get_config_descriptor] index 0
libusb: debug [libusb_get_device_descriptor]
libusb: debug [libusb_get_config_descriptor] index 0
Opening DFU capable USB device...
libusb: debug [libusb_open] open 2.85
libusb: debug [usbi_add_pollfd] add fd 9 events 4
ID 1915:52de
Run-time device DFU version 0110
Claiming USB DFU Runtime Interface...
libusb: debug [libusb_claim_interface] interface 0
libusb: debug [libusb_set_interface_alt_setting] interface 0 altsetting 0
Determining device status: libusb: debug [libusb_alloc_transfer] transfer 0x9080a8
libusb: debug [libusb_submit_transfer] transfer 0x9080a8
libusb: debug [add_to_flying_list] arm timerfd for timeout in 5000ms (first in line)
libusb: debug [libusb_handle_events_timeout_completed] doing our own event handling
libusb: debug [handle_events] poll fds modified, reallocating
libusb: debug [handle_events] poll() 3 fds with timeout in 60000ms
libusb: debug [handle_events] poll() returned 1
libusb: debug [reap_for_handle] urb type=2 status=0 transferred=6
libusb: debug [handle_control_completion] handling completion status 0
libusb: debug [disarm_timerfd] 
libusb: debug [usbi_handle_transfer_completion] transfer 0x9080a8 has callback 0x7fbed2871520
libusb: debug [sync_transfer_cb] actual_length=6
libusb: debug [libusb_free_transfer] transfer 0x9080a8
state = appIDLE, status = 0
Device really in Runtime Mode, send DFU detach request...
libusb: debug [libusb_alloc_transfer] transfer 0x9080a8
libusb: debug [libusb_submit_transfer] transfer 0x9080a8
libusb: debug [add_to_flying_list] arm timerfd for timeout in 5000ms (first in line)
libusb: debug [libusb_handle_events_timeout_completed] doing our own event handling
libusb: debug [handle_events] poll() 3 fds with timeout in 60000ms
libusb: debug [handle_events] poll() returned 1
libusb: debug [reap_for_handle] urb type=2 status=0 transferred=0
libusb: debug [handle_control_completion] handling completion status 0
libusb: debug [disarm_timerfd] 
libusb: debug [usbi_handle_transfer_completion] transfer 0x9080a8 has callback 0x7fbed2871520
libusb: debug [sync_transfer_cb] actual_length=0
libusb: debug [libusb_free_transfer] transfer 0x9080a8
Resetting USB...
libusb: debug [libusb_reset_device] 
libusb: debug [libusb_release_interface] interface 0
libusb: debug [libusb_close] 
libusb: debug [usbi_remove_pollfd] remove fd 9
libusb: debug [linux_get_device_address] getting address for device: 2-2.1 detached: 1
libusb: debug [udev_hotplug_event] udev hotplug event. action: remove.
libusb: debug [libusb_get_device_list] 
libusb: debug [libusb_get_device_descriptor] 
libusb: debug [libusb_get_config_descriptor] index 0
libusb: debug [parse_configuration] skipping descriptor 0xb
libusb: debug [libusb_get_device_descriptor] 
libusb: debug [libusb_get_config_descriptor] index 0
libusb: debug [libusb_get_device_descriptor] 
libusb: debug [libusb_get_config_descriptor] index 0
libusb: debug [libusb_get_device_descriptor] 
libusb: debug [libusb_get_config_descriptor] index 0
libusb: debug [libusb_get_device_descriptor] 
libusb: debug [libusb_get_config_descriptor] index 0
dfu-util: Lost device after RESET?

Tests done on Ubuntu 16.04 with libusb-1.0-0:amd64 version 1.0.20.
Using dfu-util 0.9 results in the same problem.

jfischer-no added a commit to jfischer-no/zephyr that referenced this issue Mar 27, 2019
Add status callback for composite configuration.
Status callback is used to set the DFU state to dfuIDLE,
if the callback is not called the device remains in
appDETACH state and the dfu-util aborts.

fixes: zephyrproject-rtos#14882

Signed-off-by: Johann Fischer <j.fischer@phytec.de>
finikorg added a commit to finikorg/zephyr that referenced this issue Apr 1, 2019
Merge cb_usb_status_composite and cb_usb_status and use common
forward_status_cb for both composite and normal devices.

Fixes zephyrproject-rtos#14882

Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
@carlescufi carlescufi reopened this Apr 5, 2019
@carlescufi
Copy link
Member

Reopening since this doesn't seem fully fixed

@carlescufi carlescufi reopened this Apr 5, 2019
@jfischer-no jfischer-no reopened this Apr 5, 2019
@jfischer-no jfischer-no changed the title USB DFU never enters DFU mode, when composite device is enabled USB DFU never enters DFU mode, when composite device is enabled and mcuboot is used Apr 5, 2019
@jfischer-no
Copy link
Collaborator

jfischer-no commented Apr 5, 2019

similar issue #15205

@jfischer-no
Copy link
Collaborator

can not reproduce it on latest master, for nRF52840 see #15330, an example config can be found here

pawelzadrozniak added a commit to pawelzadrozniak/zephyr that referenced this issue Apr 11, 2019
When the device enters DFU mode, the descriptor set is switched
to DFU-specific. Device descriptor must match the previous one,
otherwise dfu-util will report an error. DFU descriptor was
missing a variant for composite device mode (currently composite
device mode has a special implementation in ifdefs - to be
refactored in future) causing a mismatch - composite before
DFU_DETACH and non-composite after.

Fixes zephyrproject-rtos#14882

Signed-off-by: Paweł Zadrożniak <pawel.zadrozniak@nordicsemi.no>
@pawelzadrozniak
Copy link
Collaborator

pawelzadrozniak commented Apr 11, 2019

I was able to reproduce it.
Fixed in #15360

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: USB Universal Serial Bus bug The issue is a bug, or the PR is fixing a bug priority: low Low impact/importance bug
Projects
None yet
5 participants