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.
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!
Anonymous
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?
It is a bootloader very similar to the libopencm3 bootloader https://github.com/blacksphere
Last edit: Tormod Volden 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.
A fitting bootloader is intended to be put in a STLINK from a STLINK Demo Board.
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? :)
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?
Here a log. The poll with timeout 0 is repeated forever...
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?
You are right! 0x08000000 up to 0x08001fff is the bootloader itself. Reading in the target area above 0x08001fff times out as expected.
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.
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.
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.
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
Can you please address the other points in my last post?
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.
Appended is a lsusb -v log.
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"
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"
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