2009-04-24 01:29:12

by Sandro Giessl

[permalink] [raw]
Subject: bluez dfutool: patch & questions

Dear Marcel and others,

I'm developing DFU capabilities for a ARM7 STM32 based device. As I've been
new to DFU this wasn't a straigt forward process for me, but my endeavors are
slowly paying off. :) I must say that I've been glad to find dfutool. It was
very helpful to have a lean code base I was able to modify as I whished and
that could easily be stepped through with gdb.

While the device by now can be programmed more or less using the stock
dfutool, I have made some modifications (based on
http://www.usb.org/developers/devclass_docs/usbdfu10.pdf) that may be useful
to others; these are mainly:

- When waiting for the DNLOAD_BUSY -> idle state transition, do not sleep 1s,
but use the timeout suggested by the device in the state response. makes the
upgrade a little bit quicker.

- Between the last download request in the loop and the EOF (zero length)
download-request, there should also be repeated get_status requests; otherwise
the EOF-download request would fail (for me, it did).
The patch fixes it this way: basically, the order of get_status and download
within the download loop should better be reversed, in my eyes. Download
should be first, and get_status should wait for idle state.

- After the EOF download request, some devices want to get put into
manifestation state (initiated by get_status) where the write operation could
be finished and the device can reset itself. I have implemented this.


I didn't find information about the current state and goals for dfutool. Would
you mind elaborating a little about this?
Is dfutool only targeted at bluetooth device firmware upgrades? Does it cover
the full range of bluetooth devices (this would surprise me since DFU protocol
implementations seem to differ from device to device. there are various
different tools for linux, each with its own strength/weakness/list of
supported target devices)?

I'm curious about any experience of how devices in practise do differ in
details when talking to them via DFU. With DfuSe by STMicroelectronics there
is an effort of an DFU extension that allows devices to announce their
capabilities (memory layout, alternative memory settings to choose from, add
generic 'function' list and functions such as LIST_FUNCTIONS, SET_POINTER,
ERASE). I'm not considering to use it since it appears to be a little complex
for simple consumer devices. I consider it dangerous as well, since
SET_POINTER/ERASE allows to access any memory area, not just the one reserved
for the firmware image, possibly making the device not recoverable via DFU.
And ironically, is incompatible to most dfu tools because in UPLOAD/DOWNLOAD
requests, the blocks 0 and 1 are reserved for the generic function extension
thing (data blocks are numbered from 2 to n instead of 0 to n. when used with
e.g. dfutool, the device would get into STATUS_ERRSTALLEDPKT because it's
forbidden to DNLOAD to block 1).

Another question regarding the hardcoded upload/download packet size of 1023
bytes (in dfutool.c): Why this and not e.g. 1024? (I'm going to use a fixed
size of 1024 because this allows usb firmware code to erase one page of flash
memory and program it in one go).

Best regards,
Sandro


Attachments:
(No filename) (3.14 kB)
bluez-4.12-dfutool.diff (9.07 kB)
Download all attachments

2009-04-24 07:57:52

by Bjørn Mork

[permalink] [raw]
Subject: Re: bluez dfutool: patch & questions

Sandro Giessl <[email protected]> writes:

> Dear Marcel and others,
>
> I'm developing DFU capabilities for a ARM7 STM32 based device. As I've been
> new to DFU this wasn't a straigt forward process for me, but my endeavors are
> slowly paying off. :) I must say that I've been glad to find dfutool. It was
> very helpful to have a lean code base I was able to modify as I whished and
> that could easily be stepped through with gdb.
>
> While the device by now can be programmed more or less using the stock
> dfutool, I have made some modifications (based on
> http://www.usb.org/developers/devclass_docs/usbdfu10.pdf) that may be useful
> to others; these are mainly:
>
> - When waiting for the DNLOAD_BUSY -> idle state transition, do not sleep 1s,
> but use the timeout suggested by the device in the state response. makes the
> upgrade a little bit quicker.
>
> - Between the last download request in the loop and the EOF (zero length)
> download-request, there should also be repeated get_status requests; otherwise
> the EOF-download request would fail (for me, it did).
> The patch fixes it this way: basically, the order of get_status and download
> within the download loop should better be reversed, in my eyes. Download
> should be first, and get_status should wait for idle state.
>
> - After the EOF download request, some devices want to get put into
> manifestation state (initiated by get_status) where the write operation could
> be finished and the device can reset itself. I have implemented this.

Great!

I've also looked into using dfutool for other DFU capable devices in the
past (actually a DFU based PIC18F bootloader I wrote myself), but ran
into a few issues where it became difficult to both follow the spec and
allow dfutool to work. I assume that's because dfutool is adapted to
real world devices.

This is so long ago that I don't think the patches apply cleanly anymore
(this was done two years ago). So I'm the complete copies of my
modified dfu.{c,h} and dfutool.c, hoping that some of it may be useful
to you or anyone else.

Do note that my focus was getting this to work with my device, and that
there probably are lots of fixes needed to avoid loosing compatibility
with the original dfutool.

I see that I did quote parts of the spec here and there when I had to
change things to be conformant. I'd really like to hear about it if
anyone disagrees with my interpretation of the spec. It's not like it's
all crystal clear to me...


> I didn't find information about the current state and goals for dfutool. Would
> you mind elaborating a little about this?
> Is dfutool only targeted at bluetooth device firmware upgrades? Does it cover
> the full range of bluetooth devices (this would surprise me since DFU protocol
> implementations seem to differ from device to device. there are various
> different tools for linux, each with its own strength/weakness/list of
> supported target devices)?
>
> I'm curious about any experience of how devices in practise do differ in
> details when talking to them via DFU. With DfuSe by STMicroelectronics there
> is an effort of an DFU extension that allows devices to announce their
> capabilities (memory layout, alternative memory settings to choose from, add
> generic 'function' list and functions such as LIST_FUNCTIONS, SET_POINTER,
> ERASE). I'm not considering to use it since it appears to be a little complex
> for simple consumer devices. I consider it dangerous as well, since
> SET_POINTER/ERASE allows to access any memory area, not just the one reserved
> for the firmware image, possibly making the device not recoverable via DFU.
> And ironically, is incompatible to most dfu tools because in UPLOAD/DOWNLOAD
> requests, the blocks 0 and 1 are reserved for the generic function extension
> thing (data blocks are numbered from 2 to n instead of 0 to n. when used with
> e.g. dfutool, the device would get into STATUS_ERRSTALLEDPKT because it's
> forbidden to DNLOAD to block 1).
>
> Another question regarding the hardcoded upload/download packet size of 1023
> bytes (in dfutool.c): Why this and not e.g. 1024? (I'm going to use a fixed
> size of 1024 because this allows usb firmware code to erase one page of flash
> memory and program it in one go).

This was one of my issues too. Given a device with extremely limited
amounts of RAM, the hardcoded packet size became a real problem. If you
look at my code below, it uses the packet size from the DFU desciptor.
This should probably fall back to using 1023 for all the real world
devices without a DFU functional decriptor (guessing they must exist) or
with bogus packet sizes (e.g. 0).



Bjørn


Attachments:
dfu.h (3.78 kB)
dfutool.c (24.43 kB)
dfu.c (10.16 kB)
Download all attachments