Menu

#38 Warn if DFU-UPLOAD not implemented

none
open
nobody
None
2025-05-10
2017-02-28
Uwe Bonnes
No

Hello,

the blackmagic debug probe (BMP, libopencm3) DFU firmware has DFU-UPLOAD not implemented:
case DFU_UPLOAD:
return 0;

In the functional descriptor, USB_DFU_CAN_UPLOAD is not set. Running dfu-util -s 0x08000000:0x1000 -U x.bin hangs indefinite.

It is not clear for me, where things go wrong.

  • Should BMP bootloader return some other value on the DFU_UPLOAD request?
  • Should DFU-UTILS reject the upload request as USB_DFU_CAN_UPLOAD is not set?
  • Or should DFU-UTILS react in another way on the 0 return from the BMP bootloader?

In the long run, I intend to add upload to the BMP(libopencm3) bootloader, but reaction on dfu-upload not available should be fixed anyhow. Any hints welcome!

Discussion

  • Tormod Volden

    Tormod Volden - 2017-02-28

    In principle dfu-util (and other clients) should not try to upload if the device doesn't announce that it supports it. However so many device bootloaders are sloppy with their descriptor bits so we are following a more forgiving policy, so as to not stand in the way between the user and his device.

    At the least we should print a warning if the user goes against what the device declares.

    In all cases, dfu-util should not be hanging indefinitely. Can you please check where and why this is happening?

    BTW, is this the bootloader included in the libopencm3-examples repo?

     
  • Uwe Bonnes

    Uwe Bonnes - 2017-02-28

    It is a bootloader very similar to the libopencm3 bootloader https://github.com/blacksphere

     

    Last edit: Tormod Volden 2017-02-28
  • Uwe Bonnes

    Uwe Bonnes - 2017-02-28

    The program loops in dfuse_special_command. Find a gdb log attached.

    I wonder why I see "DFU_STATE_dfuDNBUSY while this is an Upload.

     
  • Uwe Bonnes

    Uwe Bonnes - 2017-02-28

    A fitting bootloader is intended to be put in a STLINK from a STLINK Demo Board.

     
  • Tormod Volden

    Tormod Volden - 2017-02-28

    The DFU_STATE_dfuDNBUSY is probably because the first step in a DfuSe upload is to set the programming address using a DFU_DNLOAD request. If you don't specify a programming address (-s :0x1000) it would probably fail somewhere else.

    Now why is the device stuck in DNBUSY after receiving this request? :)

     
  • Tormod Volden

    Tormod Volden - 2017-02-28

    Hmm, the SET_ADDRESS request is also sent on downloads (which work) so that doesn't explain it fully. Can you please post the log from dfu-util adding -v -v -v?

     
  • Uwe Bonnes

    Uwe Bonnes - 2017-02-28

    Here a log. The poll with timeout 0 is repeated forever...

     
  • Tormod Volden

    Tormod Volden - 2017-02-28

    Thanks! I filtered out most of the libusb chatter:
    $ egrep "^[^l]|actual" bmp-upload.log
    <snip>
    Setting address pointer to 0x08000000
    libusb: debug [sync_transfer_cb] actual_length=5
    libusb: debug [sync_transfer_cb] actual_length=6
    Poll timeout 100 ms
    libusb: debug [sync_transfer_cb] actual_length=6
    Poll timeout 0 ms
    libusb: debug [sync_transfer_cb] actual_length=6
    Poll timeout 0 ms
    libusb: debug [sync_transfer_cb] actual_length=6
    Poll timeout 0 ms</snip>

    So the first get_status seems fine and has a non-zero poll timeout (unnecessarily long though) but afterwards 0 ms. You are not by chance outside the app_address - max_address area? Well, from seeing the memory map in your log, I think you are. So the device will in its usbdfu_getstatus_complete() lock the flash, stall the pipe and return without changing usbdfu_state ... Can you please confirm this by uploading from a "valid" address? Now why isn't the stalled pipe detected? Is it the right one?

     
  • Uwe Bonnes

    Uwe Bonnes - 2017-03-01

    You are right! 0x08000000 up to 0x08001fff is the bootloader itself. Reading in the target area above 0x08001fff times out as expected.

     
  • Uwe Bonnes

    Uwe Bonnes - 2017-03-01

    Here is the BMP bootloader code that I suspect to results in the infinite loop when a upload request to a region outside the writeable flash is done:
    uint32_t addr = get_le32(prog.buf + 1);
    if ((addr < app_address) || (addr >= max_address)) {
    flash_lock();
    usbd_ep_stall_set(dev, 0, 1);
    perhaps the stall is misplaced here, but dfu-util is running into a loop with it.

     
  • Tormod Volden

    Tormod Volden - 2017-03-02

    A stall (at the right place) should cause libusb_control_transfer() to fail and dfu-util to error out. Maybe the device needs to check the address during the transfer, and not after it has completed.

     
  • Tormod Volden

    Tormod Volden - 2017-03-02

    The DFU 1.1 specification reserves the DFU_GETSTATUS status value of 0x08 (errADDRESS) for the case of non-valid address. I think the device should set this status in addition to stalling the transfer. The figure A.1 in the specification also indicates that the state should be set to dfuERROR when status is not OK.

    It would be good if you can fix this in the device. The remaining question is whether there is a large enough need for dfu-util to workaround the device bug (and avoid hanging) in existing devices out there. In that case I don't see much other options than to limit the get_dfu_status loop to a certain number of iterations, maybe only counting the instances of zero bwPollTimeout (in a row) to narrow down the affected cases. I don't think repeated zero bwPollTimeout can make much sense.

    Please try the attached patch to see if it prevents hanging with the (broken) bootloader. I would like to blackmail you to fix the bootloader before I apply this though :) Preferrably also the bootloader version as advertised in the USB device descriptor will be bumped, so that a client like dfu-util can know if a connected device will exhibit this bug or not.

    I would also like to advertise the Black Magic Probe as supported by dfu-util. Can you please send me a lsusb and download log that we can file in our device-logs/ folder?

    Best regards,
    Tormod

    PS. While we're at it, you should also verify that wValue (wBlockNumber) is > 1 when using it to calculate the programming address, otherwise a client can use the reserved value 1 and it would end up writing below the start address.

     
  • Uwe Bonnes

    Uwe Bonnes - 2017-03-03

    Regarding the patch: Yes, it works fine. Now reading with an without the force option does not hang in or outside the visible region.

     

    Last edit: Tormod Volden 2017-03-03
  • Tormod Volden

    Tormod Volden - 2017-05-30

    Can you please address the other points in my last post?

     
  • Uwe Bonnes

    Uwe Bonnes - 2017-05-31

    In the meantime, my dfu-upload patch has been merged to
    https://github.com/blacksphere/blackmagic.git. So probably no need to work around th upload hang problem.

    BMP is primarily intended to run on the original hardware as sold on https://github.com/blacksphere/blackmagic/wiki. I use it with the STLink modified as on https://embdev.net/articles/STM_Discovery_as_Black_Magic_Probe.

    A pending problem is that firmware size is greater than announced flash size on Stlinks older than V2.1.
    Output below is with a Nucleo board that has an stlink V2.1 and announced 128b k Flask. I hope this is the information you requested.

    lsusb
    Bus 003 Device 076: ID 1d50:6018 OpenMoko, Inc.

    Appended is a lsusb -v log.

    dfu-util -l (in device mode)
    dfu-util 0.9

    Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
    Copyright 2010-2016 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/

    Found Runtime: [1d50:6018] ver=0100, devnum=76, cfg=1, intf=4, path="3-4.2", alt=0, name="Black Magic Firmware Upgrade (STLINK)", serial="C2C89BDB"

    dfu-util -l (in update mode, acchieved by pushing the reset button of a STM Nucleo board while plugging usb)
    dfu-util 0.9

    Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
    Copyright 2010-2016 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/

    Found DFU: [1d50:6017] ver=0100, devnum=77, cfg=1, intf=0, path="3-4.2", alt=0, name="@Internal Flash /0x08000000/8001Ka,120001Kg", serial="C2C89BDB"

    dfu-util -s 0x08002000:leave -D src/blackmagic.bin (again in device mode)
    dfu-util 0.9

    Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
    Copyright 2010-2016 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 1d50:6017
    Run-time device DFU version 011a
    Claiming USB DFU Interface...
    Setting Alternate Setting #0 ...
    Determining device status: state = dfuIDLE, status = 0
    dfuIDLE, continuing
    DFU mode device DFU version 011a
    Device returned transfer size 1024
    DfuSe interface name: "Internal Flash "
    Downloading to address = 0x08002000, size = 57496
    Download [=========================] 100% 57496 bytes
    Download done.
    File downloaded successfully
    dfu-util: Error during download get_status

     
  • Tormod Volden

    Tormod Volden - 2017-06-03
    • summary: Handle DFU-UPLOAD not implemented --> Warn if DFU-UPLOAD not implemented
     

Anonymous
Anonymous

Add attachments
Cancel





MongoDB Logo MongoDB