How to support different erase page size than transfer page size?
Multiplatform USB DFU host utility
Brought to you by:
tormod
I'm trying to use dfuse on a STM32F103VCT6. This device has 2k pages, but the bootloader only supports a 1k transfer size.Maybe that is a bug in the bootloader, but I don't have the code for it, and don't really want to write my own just for this issue.
My fix was to 1st erase all blocks before downloading the firmware to the device, but I'd like to know if this is something dfu_util is willing to support nateively and if so, what is the preferred implementation? I'll be happy to provide a patch if it is something that may be accepted
Anonymous
Hi, the code is intended to support different page size and transfer size. The page erase is done "on-demand" when the address written to is not in the "last erased page". So is there maybe a bug in this code?
The above should only break if e.g. a .dfu file has multiple overlapping segments, so that the second time a page is referenced (with another page having been erased in the meantime), it will be erased and thus lose what was written the first time the page was referenced. Is this the case here?
OTOH it is even in the TODO file to do all erase in one pass, so I am not against that approach :) However I would like to understand why the existing code doesn't work for you. Best regards, Tormod.
The issue is that the page-size reported by the bootloader is 1k, not 2k:
dfu-util reports:
As I said, the bootloader is buggy. But as I said, I don't want to replace it since it is functional and widely deployed. I just want to be able to put my firmware on the device (and let other users do the same) without using the terrible windows-only program they supply.
So, I see a couple options:
1) You tell me that you don't want to support buggy bootloaders, which I can fully understand
2) We add a new switch to override the page size vs what the dfu file says (in addition to the current transfer-size switch). I don't know how this woud play with a dfu with multiple segments though. You'd probably need to be able to select which segment to upload too.
3) we supply a way to override the identifcation descriptor
4) We change the code to do an erase pass before a write pass (which is what I've done). In this case, I still erase each page twice, but it causes no issue.
I've included a patch for (4). It only affects dfuse code. I don't have any non-dfuse devices, but looking at the code, it doesn't apear that a standard dfu download does erase before write.
Ideally we would do (3) by adding a quirk to fix up the descriptor if it is a silicon bug and we are be able to identify it (and same for transfer size potentially). But this is not a built-in bootloader, right? AFAIK, STM32F103VCT6 doesn't have one, USB ID is 0483:df12 and not 0483:df11, as well as "protected" 12KB in the beginning of flash, so this smells of a homebrew bootloader, which we wouldn't care so much for unless it is in a widespread device.
You don't have to write your own bootloader. The ST standard peripheral library includes an example dfuse bootloader, probably where you bootloader was taken from, but without taking care it was built for the right flash page size.
However I think your patch is great and can be applied anyway. It will make us immune to similar device bugs. What name and address can I put in your patch?
Standard DFU doesn't deal with erases, the device itself takes care of it there.
Thanks a lot,
Tormod
Sorry if I didn't explain clearly. Yes this is a softrware bootloader. But to replace it requires either a Stlink or to write a bootloader loader. I could do either of these, but the purpose is to support a device from a Chinese manufacturer (Radiolink AT9 RC transmitter), and I don't want the end user to need to replace the bootloader.
Geoffrey Hausheer rc2012@pblue.org
Thanks for the extra information, it is good to have for reference. It wouldn't be the first time we work around something from a clueless manufacturer...
Looking at this, I don't think we need to repeat the check for DFUSE_WRITEABLE in the write pass, since we checked that already in the erase pass.
Pushed (with the second DFUSE_WRITEABLE check omitted) to the repo. Thanks for your contribution!