Add cached dfu-util sources, as the original remote repo is no longer available for use as the source to the dfu-util folder as a submodule
This commit is contained in:
parent
dfc1f47381
commit
8ab4734573
|
@ -0,0 +1,30 @@
|
|||
Authors ordered by first contribution.
|
||||
|
||||
Harald Welte
|
||||
Werner Almesberger
|
||||
Michael Lauer
|
||||
Jim Huang
|
||||
Stefan Schmidt
|
||||
Daniel Willmann
|
||||
Mike Frysinger
|
||||
Uwe Hermann
|
||||
C. Scott Ananian
|
||||
Bernard Blackham
|
||||
Holger Freyther
|
||||
Marc Singer
|
||||
James Perkins
|
||||
Tommi Keisala
|
||||
Pascal Schweizer
|
||||
Bradley Scott
|
||||
Uwe Bonnes
|
||||
Andrey Smirnov
|
||||
Jussi Timperi
|
||||
Hans Petter Selasky
|
||||
Bo Shen
|
||||
Henrique de Almeida Mendonca
|
||||
Bernd Krumboeck
|
||||
Dennis Meier
|
||||
Veli-Pekka Peltola
|
||||
Dave Hylands
|
||||
Michael Grzeschik
|
||||
Paul Fertser
|
|
@ -0,0 +1,340 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
|
@ -0,0 +1,93 @@
|
|||
0.8:
|
||||
o New, separate dfu-prefix tool (Uwe Bonnes)
|
||||
o Allow filtering on serial number (Uwe Bonnes)
|
||||
o Improved VID/PID/serial filtering (Bradley Scott)
|
||||
o Support reading firmware from stdin (Tormod Volden)
|
||||
o Warn if missing DFU suffix (Tormod Volden)
|
||||
o Improved progress bar (Hans Petter Selasky)
|
||||
o Fix dfuse leave option (Uwe Bonnes)
|
||||
o Major code rework (Hans Petter Selasky)
|
||||
o MS Visual Studio build support (Henrique Mendonca)
|
||||
o dfuse-pack.py tool for .dfu files (Antonio Galeo)
|
||||
o Many other fixes from many people
|
||||
|
||||
2014-09-13: Tormod Volden <debian.tormod@gmail.com>
|
||||
|
||||
0.7:
|
||||
o Support for TI Stellaris devices (Tommi Keisala)
|
||||
o Fix libusb detection on MacOSX (Marc Singer)
|
||||
o Fix libusb detection on FreeBSD (Tormod Volden)
|
||||
o Improved DfuSe support (Tormod Volden)
|
||||
o Support all special commands (leave, unprotect, mass-erase)
|
||||
o Arbitrary upload lengths
|
||||
o "force" option for various possible (dangerous) overrides
|
||||
|
||||
2012-10-07: Tormod Volden <debian.tormod@gmail.com>
|
||||
|
||||
0.6:
|
||||
o Add detach mode (Stefan Schmidt)
|
||||
o Check return value on all libusb calls (Tormod Volden)
|
||||
o Fix segmentation fault with -s option (Tormod Volden)
|
||||
o Add DFU suffix manipulation tool (Stefan Schmidt)
|
||||
o Port to Windows: (Tormod Volden, some parts based on work from Satz
|
||||
Klauer)
|
||||
o Port file handling to stdio streams
|
||||
o Sleep() macros
|
||||
o C99 types
|
||||
o Pack structs
|
||||
o Detect DfuSe device correctly on big-endian architectures (Tormod
|
||||
Volden)
|
||||
o Add dfuse progress indication on download (Tormod Volden)
|
||||
o Cleanup: gcc pedantic, gcc extension, ... (Tormod Volden)
|
||||
o Rely on page size from functional descriptor. Please report if you get
|
||||
an error about it. (Tormod Volden)
|
||||
o Add quirk for Maple since it reports wrong DFU version (Tormod Volden)
|
||||
|
||||
2012-04-22: Stefan Schmidt <stefan@datenfreihafen.org>
|
||||
|
||||
0.5:
|
||||
o DfuSe extension support for ST devices (Tormod Volden)
|
||||
o Add initial support for bitWillDetach flag from DFU 1.1 (Tormod
|
||||
Volden)
|
||||
o Internal cleanup and some manual page fixes (Tormod Volden)
|
||||
|
||||
2011-11-02: Stefan Schmidt <stefan@datenfreihafen.org>
|
||||
|
||||
0.4:
|
||||
o Rework to use libusb-1.0 (Stefan Schmidt)
|
||||
o DFU suffix support (Tormod Volden, Stefan Schmidt)
|
||||
o Sspeed up DFU downloads directly into memory (Bernard Blackham)
|
||||
o More flexible -d vid:pid parsing (Tormod Volden)
|
||||
o Many bug fixes and cleanups
|
||||
|
||||
2011-07-20: Stefan Schmidt <stefan@datenfreihafen.org>
|
||||
|
||||
0.3:
|
||||
o quirks: Add OpenOCD to the poll timeout quirk table.
|
||||
|
||||
2010-12-22: Stefan Schmidt <stefan@datenfreihafen.org>
|
||||
|
||||
0.2:
|
||||
o Fix some typos on the website and the README (Antonio Ospite, Uwe
|
||||
Hermann)
|
||||
o Remove build rule for a static binary. We can use autotools for this.
|
||||
(Mike Frysinger)
|
||||
o Fix infinite loop in download error path (C. Scott Ananian)
|
||||
o Break out to show the 'finished' in upload (C. Scott Ananian)
|
||||
o Add GPLv2+ headers (Harald Welte)
|
||||
o Remove dead code (commands.[ch]) remnescent of dfu-programmer (Harald
|
||||
Welte)
|
||||
o Simple quirk system with Openmoko quirk for missing bwPollTimeout (Tormod Volden)
|
||||
o New default (1024) and clamping of transfer size (Tormod Volden)
|
||||
o Verify sending of completion packet (Tormod Volden)
|
||||
o Look for DFU functional descriptor among all descriptors (Tormod
|
||||
Volden)
|
||||
o Print out in which direction we are transferring data
|
||||
o Abort in upload if the file already exists
|
||||
|
||||
2010-11-17 Stefan Schmidt <stefan@datenfreihafen.org>
|
||||
|
||||
0.1:
|
||||
Initial release
|
||||
|
||||
2010-05-23 Stefan Schmidt <stefan@datenfreihafen.org>
|
|
@ -0,0 +1,20 @@
|
|||
List of supported software and hardware products:
|
||||
|
||||
Software user (bootloader, etc)
|
||||
-------------------------------
|
||||
- Sam7DFU: http://www.openpcd.org/Sam7dfu
|
||||
- U-boot: DFU patches
|
||||
- Barebox: http://www.barebox.org/
|
||||
- Leaflabs: http://code.google.com/p/leaflabs/
|
||||
- Blackmagic DFU
|
||||
|
||||
Products using DFU
|
||||
------------------
|
||||
- OpenPCD (sam7dfu)
|
||||
- Openmoko Neo 1973 and Freerunner (u-boot with DFU patches)
|
||||
- Leaflabs Maple
|
||||
- ATUSB from Qi Hardware
|
||||
- STM32F105/7, STM32F2/F3/F4 in System Bootloader
|
||||
- Blackmagic debug probe
|
||||
- NXP LPC31xx/LPC43XX, e.g. LPC-Link and LPC-Link2, need binaries
|
||||
with LPC prefix and encoding (LPC-Link)
|
|
@ -0,0 +1,3 @@
|
|||
SUBDIRS = src doc
|
||||
|
||||
EXTRA_DIST = autogen.sh TODO DEVICES.txt dfuse-pack.py
|
|
@ -0,0 +1,20 @@
|
|||
Dfu-util - Device Firmware Upgrade Utilities
|
||||
|
||||
Dfu-util is the host side implementation of the DFU 1.0 [1] and DFU 1.1 [2]
|
||||
specification of the USB forum.
|
||||
|
||||
DFU is intended to download and upload firmware to devices connected over
|
||||
USB. It ranges from small devices like micro-controller boards up to mobile
|
||||
phones. With dfu-util you are able to download firmware to your device or
|
||||
upload firmware from it.
|
||||
|
||||
dfu-util has been tested with Openmoko Neo1973 and Freerunner and many
|
||||
other devices.
|
||||
|
||||
[1] DFU 1.0 spec: http://www.usb.org/developers/devclass_docs/usbdfu10.pdf
|
||||
[2] DFU 1.1 spec: http://www.usb.org/developers/devclass_docs/DFU_1.1.pdf
|
||||
|
||||
The official website is:
|
||||
|
||||
http://dfu-util.gnumonks.org/
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
DfuSe:
|
||||
- Do erase and write in two separate passes when downloading
|
||||
- Skip "Set Address" command when downloading contiguous blocks
|
||||
- Implement "Get Commands" command
|
||||
|
||||
Devices:
|
||||
- Research iPhone/iPod/iPad support
|
||||
Heavily modified dfu-util fork here:
|
||||
https://github.com/planetbeing/xpwn/tree/master/dfu-util
|
||||
- Test against Niftylights
|
||||
|
||||
Non-Code:
|
||||
- Logo
|
||||
- Re-License as LGPL for usage as library?
|
|
@ -0,0 +1,2 @@
|
|||
#! /bin/sh
|
||||
autoreconf -v -i
|
|
@ -0,0 +1,41 @@
|
|||
# -*- Autoconf -*-
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ(2.59)
|
||||
AC_INIT([dfu-util],[0.8],[dfu-util@lists.gnumonks.org],,[http://dfu-util.gnumonks.org])
|
||||
AC_CONFIG_AUX_DIR(m4)
|
||||
AM_INIT_AUTOMAKE([foreign])
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
|
||||
# Test for new silent rules and enable only if they are available
|
||||
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
|
||||
|
||||
# Checks for programs.
|
||||
AC_PROG_CC
|
||||
|
||||
# Checks for libraries.
|
||||
# On FreeBSD the libusb-1.0 is called libusb and resides in system location
|
||||
AC_CHECK_LIB([usb], [libusb_init],, [native_libusb=no],)
|
||||
AS_IF([test x$native_libusb = xno], [
|
||||
PKG_CHECK_MODULES([USB], [libusb-1.0 >= 1.0.0],,
|
||||
AC_MSG_ERROR([*** Required libusb-1.0 >= 1.0.0 not installed ***]))
|
||||
])
|
||||
AC_CHECK_LIB([usbpath],[usb_path2devnum],,,-lusb)
|
||||
|
||||
LIBS="$LIBS $USB_LIBS"
|
||||
CFLAGS="$CFLAGS $USB_CFLAGS"
|
||||
|
||||
# Checks for header files.
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS([usbpath.h windows.h sysexits.h])
|
||||
|
||||
# Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_C_CONST
|
||||
AC_TYPE_SIZE_T
|
||||
|
||||
# Checks for library functions.
|
||||
AC_FUNC_MEMCMP
|
||||
AC_CHECK_FUNCS([ftruncate getpagesize nanosleep err])
|
||||
|
||||
AC_CONFIG_FILES(Makefile src/Makefile doc/Makefile)
|
||||
AC_OUTPUT
|
|
@ -0,0 +1,77 @@
|
|||
Device:
|
||||
-------
|
||||
qi-hardware-atusb:
|
||||
- Qi Hardware ben-wpan
|
||||
- DFU implementation:
|
||||
http://projects.qi-hardware.com/index.php/p/ben-wpan/source/tree/master/atusb/fw/usb
|
||||
- Tester: Stefan Schmidt
|
||||
|
||||
openpcd:
|
||||
- OpenPCD RFID reader
|
||||
- DFU implementation: SAM7DFU
|
||||
http://www.openpcd.org/Sam7dfu, git://git.gnumonks.org/openpcd.git
|
||||
- Tester: Stefan Schmidt
|
||||
|
||||
simtrace:
|
||||
- Sysmocom SimTrace
|
||||
- DFU implementation: SAM7DFU
|
||||
http://www.openpcd.org/Sam7dfu, git://git.gnumonks.org/openpcd.git
|
||||
- Tester: Stefan Schmidt
|
||||
|
||||
openmoko-freerunner:
|
||||
- Openmoko Freerunner
|
||||
- DFU implementation: Old U-Boot
|
||||
http://git.openmoko.org/?p=u-boot.git;a=shortlog;h=refs/heads/mokopatches
|
||||
- Tester: Stefan Schmidt
|
||||
|
||||
openmoko-neo1973:
|
||||
- Openmoko Neo1073
|
||||
- DFU implementation: Old U-Boot
|
||||
http://git.openmoko.org/?p=u-boot.git;a=shortlog;h=refs/heads/mokopatches
|
||||
- Tester: Stefan Schmidt
|
||||
|
||||
tdk-bluetooth:
|
||||
- TDK Corp. Bluetooth Adapter
|
||||
- DFU implementation: closed soure
|
||||
- Only upload has been tested
|
||||
- Tester: Stefan Schmidt
|
||||
|
||||
stm32f107:
|
||||
- STM32 microcontrollers with built-in (ROM) DFU loader
|
||||
- DFU implementation: Closed source but probably similar to the one
|
||||
in their USB device libraries. Some relevant application notes:
|
||||
http://www.st.com -> AN3156 and AN2606
|
||||
- Tested by Uwe Bonnes
|
||||
|
||||
stm32f4discovery:
|
||||
- STM32 microcontroller board with built-in (ROM) DFU loader
|
||||
- DFU implementation: Closed source, probably similar to stm32f107.
|
||||
- Tested by Joe Rothweiler
|
||||
|
||||
dso-nano:
|
||||
- DSO Nano pocket oscilloscope
|
||||
- DFU implementation: Based on ST Microelectronics USB FS Library 1.0
|
||||
http://dsonano.googlecode.com/files/DS0201_OpenSource.rar
|
||||
- Tester: Tormod Volden
|
||||
|
||||
opc-20:
|
||||
- Custom devices based on STM32F1xx
|
||||
- DFU implementation: ST Microelectronics USB FS Device Library 3.1.0
|
||||
http://www.st.com -> um0424.zip
|
||||
- Tester: Tormod Volden
|
||||
|
||||
lpc-link, lpclink2:
|
||||
- NXP LPCXpresso debug adapters
|
||||
- Proprietary DFU implementation, uses special download files with
|
||||
LPC prefix and encoding of the target firmware code
|
||||
- Tested by Uwe Bonnes
|
||||
|
||||
Adding the lsusb output and a download log of your device here helps
|
||||
us to avoid regressions for hardware we cannot test while working on
|
||||
the code. To extract the lsusb output use this command:
|
||||
sudo lsusb -v -d $USBID > $DEVICE.lsusb
|
||||
Prepare a description snippet as above, and send it to us. A log
|
||||
(copy-paste of the command window) of a firmware download is also
|
||||
nice, please use the double verbose option -v -v and include the
|
||||
command line in the log file.
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
|
||||
Bus 002 Device 004: ID 0483:df11 SGS Thomson Microelectronics
|
||||
Device Descriptor:
|
||||
bLength 18
|
||||
bDescriptorType 1
|
||||
bcdUSB 1.00
|
||||
bDeviceClass 0 (Defined at Interface level)
|
||||
bDeviceSubClass 0
|
||||
bDeviceProtocol 0
|
||||
bMaxPacketSize0 64
|
||||
idVendor 0x0483 SGS Thomson Microelectronics
|
||||
idProduct 0xdf11
|
||||
bcdDevice 1.1a
|
||||
iManufacturer 1 STMicroelectronics
|
||||
iProduct 2 STM32 DFU
|
||||
iSerial 3 001
|
||||
bNumConfigurations 1
|
||||
Configuration Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 2
|
||||
wTotalLength 36
|
||||
bNumInterfaces 1
|
||||
bConfigurationValue 1
|
||||
iConfiguration 0
|
||||
bmAttributes 0x80
|
||||
(Bus Powered)
|
||||
MaxPower 64mA
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 0
|
||||
bAlternateSetting 0
|
||||
bNumEndpoints 0
|
||||
bInterfaceClass 254 Application Specific Interface
|
||||
bInterfaceSubClass 1 Device Firmware Update
|
||||
bInterfaceProtocol 0
|
||||
iInterface 4 @Internal Flash /0x08000000/12*001Ka,116*001Kg
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 0
|
||||
bAlternateSetting 1
|
||||
bNumEndpoints 0
|
||||
bInterfaceClass 254 Application Specific Interface
|
||||
bInterfaceSubClass 1 Device Firmware Update
|
||||
bInterfaceProtocol 0
|
||||
iInterface 5 @SPI Flash : M25P64/0x00000000/64*064Kg,64*064Kg
|
||||
Device Firmware Upgrade Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 33
|
||||
bmAttributes 11
|
||||
Will Detach
|
||||
Manifestation Intolerant
|
||||
Upload Supported
|
||||
Download Supported
|
||||
wDetachTimeout 255 milliseconds
|
||||
wTransferSize 1024 bytes
|
||||
bcdDFUVersion 1.1a
|
||||
Device Status: 0x0000
|
||||
(Bus Powered)
|
|
@ -0,0 +1,59 @@
|
|||
(The on-board LPC3154 has some encryption key set and LPCXpressoWIN.enc
|
||||
is encrypted.)
|
||||
|
||||
$ lsusb | grep NXP
|
||||
Bus 003 Device 011: ID 0471:df55 Philips (or NXP) LPCXpresso LPC-Link
|
||||
|
||||
$ dfu-util -v -v -v -R -D /opt/lpc/lpcxpresso/bin/LPCXpressoWIN.enc
|
||||
|
||||
dfu-util 0.7
|
||||
|
||||
Copyright 2005-2008 Weston Schmidt, Harald Welte and OpenMoko Inc.
|
||||
Copyright 2010-2012 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!!!
|
||||
Deducing device DFU version from functional descriptor length
|
||||
Opening DFU capable USB device...
|
||||
ID 0471:df55
|
||||
Run-time device DFU version 0100
|
||||
Claiming USB DFU Runtime Interface...
|
||||
Determining device status:
|
||||
state = dfuIDLE, status = 0
|
||||
dfu-util: WARNING: Runtime device already in DFU state ?!?
|
||||
Claiming USB DFU Interface...
|
||||
Setting Alternate Setting #0 ...
|
||||
Determining device status:
|
||||
state = dfuIDLE, status = 0
|
||||
dfuIDLE, continuing
|
||||
DFU mode device DFU version 0100
|
||||
Device returned transfer size 2048
|
||||
Copying data from PC to DFU device
|
||||
Download [ ] 0% 0 bytes
|
||||
Download [= ] 6% 2048 bytes
|
||||
Download [=== ] 13% 4096 bytes
|
||||
Download [==== ] 19% 6144 bytes
|
||||
Download [====== ] 26% 8192 bytes
|
||||
Download [======== ] 32% 10240 bytes
|
||||
Download [========= ] 39% 12288 bytes
|
||||
Download [=========== ] 45% 14336 bytes
|
||||
Download [============= ] 52% 16384 bytes
|
||||
Download [============== ] 59% 18432 bytes
|
||||
Download [================ ] 65% 20480 bytes
|
||||
Download [================== ] 72% 22528 bytes
|
||||
Download [=================== ] 78% 24576 bytes
|
||||
Download [===================== ] 85% 26624 bytes
|
||||
Download [====================== ] 91% 28672 bytes
|
||||
Download [======================== ] 98% 29192 bytes
|
||||
Download [=========================] 100% 29192 bytes
|
||||
Download done.
|
||||
Sent a total of 29192 bytes
|
||||
state(8) = dfuMANIFEST-WAIT-RESET, status(0) = No error condition is present
|
||||
Done!
|
||||
dfu-util: can't detach
|
||||
Resetting USB to switch back to runtime mode
|
||||
|
||||
$ lsusb | grep NXP
|
||||
Bus 003 Device 012: ID 1fc9:0009 NXP Semiconductors
|
|
@ -0,0 +1,58 @@
|
|||
|
||||
Bus 003 Device 008: ID 0471:df55 Philips (or NXP) LPCXpresso LPC-Link
|
||||
Device Descriptor:
|
||||
bLength 18
|
||||
bDescriptorType 1
|
||||
bcdUSB 2.00
|
||||
bDeviceClass 0 (Defined at Interface level)
|
||||
bDeviceSubClass 0
|
||||
bDeviceProtocol 0
|
||||
bMaxPacketSize0 64
|
||||
idVendor 0x0471 Philips (or NXP)
|
||||
idProduct 0xdf55 LPCXpresso LPC-Link
|
||||
bcdDevice 0.01
|
||||
iManufacturer 0
|
||||
iProduct 0
|
||||
iSerial 0
|
||||
bNumConfigurations 1
|
||||
Configuration Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 2
|
||||
wTotalLength 25
|
||||
bNumInterfaces 1
|
||||
bConfigurationValue 1
|
||||
iConfiguration 0
|
||||
bmAttributes 0x80
|
||||
(Bus Powered)
|
||||
MaxPower 100mA
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 0
|
||||
bAlternateSetting 0
|
||||
bNumEndpoints 0
|
||||
bInterfaceClass 254 Application Specific Interface
|
||||
bInterfaceSubClass 1 Device Firmware Update
|
||||
bInterfaceProtocol 0
|
||||
iInterface 0
|
||||
Device Firmware Upgrade Interface Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 33
|
||||
bmAttributes 1
|
||||
Will Not Detach
|
||||
Manifestation Intolerant
|
||||
Upload Unsupported
|
||||
Download Supported
|
||||
wDetachTimeout 65535 milliseconds
|
||||
wTransferSize 2048 bytes
|
||||
Device Qualifier (for other device speed):
|
||||
bLength 10
|
||||
bDescriptorType 6
|
||||
bcdUSB 2.00
|
||||
bDeviceClass 0 (Defined at Interface level)
|
||||
bDeviceSubClass 0
|
||||
bDeviceProtocol 0
|
||||
bMaxPacketSize0 64
|
||||
bNumConfigurations 1
|
||||
Device Status: 0x0000
|
||||
(Bus Powered)
|
|
@ -0,0 +1,59 @@
|
|||
$ lsusb | grep NXP
|
||||
Bus 003 Device 013: ID 1fc9:000c NXP Semiconductors
|
||||
|
||||
$ dfu-util -D ~/devel/dfu-util/firmware.bin.qthdr
|
||||
|
||||
dfu-util 0.7
|
||||
|
||||
Copyright 2005-2008 Weston Schmidt, Harald Welte and OpenMoko Inc.
|
||||
Copyright 2010-2012 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!!!
|
||||
Possible unencryptes NXP LPC DFU prefix with the following properties
|
||||
Payload length: 39 kiByte
|
||||
Opening DFU capable USB device...
|
||||
ID 1fc9:000c
|
||||
Run-time device DFU version 0100
|
||||
Claiming USB DFU Runtime Interface...
|
||||
Determining device status:
|
||||
state = dfuIDLE, status = 0
|
||||
dfu-util: WARNING: Runtime device already in DFU state ?!?
|
||||
Claiming USB DFU Interface...
|
||||
Setting Alternate Setting #0 ...
|
||||
Determining device status:
|
||||
state = dfuIDLE, status = 0
|
||||
dfuIDLE, continuing
|
||||
DFU mode device DFU version 0100
|
||||
Device returned transfer size 2048
|
||||
Copying data from PC to DFU device
|
||||
Download [ ] 0% 0 bytes
|
||||
Download [= ] 4% 2048 bytes
|
||||
Download [== ] 9% 4096 bytes
|
||||
Download [=== ] 14% 6144 bytes
|
||||
Download [==== ] 19% 8192 bytes
|
||||
Download [====== ] 24% 10240 bytes
|
||||
Download [======= ] 28% 12288 bytes
|
||||
Download [======== ] 33% 14336 bytes
|
||||
Download [========= ] 38% 16384 bytes
|
||||
Download [========== ] 43% 18432 bytes
|
||||
Download [============ ] 48% 20480 bytes
|
||||
Download [============= ] 53% 22528 bytes
|
||||
Download [============== ] 57% 24576 bytes
|
||||
Download [=============== ] 62% 26624 bytes
|
||||
Download [================ ] 67% 28672 bytes
|
||||
Download [================== ] 72% 30720 bytes
|
||||
Download [=================== ] 77% 32768 bytes
|
||||
Download [==================== ] 82% 34816 bytes
|
||||
Download [===================== ] 86% 36864 bytes
|
||||
Download [====================== ] 91% 38912 bytes
|
||||
Download [======================== ] 96% 40356 bytes
|
||||
Download [=========================] 100% 40356 bytes
|
||||
Download done.
|
||||
Sent a total of 40356 bytes
|
||||
dfu-util: unable to read DFU status
|
||||
|
||||
$ lsusb | grep NXP
|
||||
Bus 003 Device 014: ID 1fc9:0018 NXP Semiconductors
|
|
@ -0,0 +1,203 @@
|
|||
|
||||
Bus 003 Device 007: ID 0c72:000c PEAK System PCAN-USB
|
||||
Device Descriptor:
|
||||
bLength 18
|
||||
bDescriptorType 1
|
||||
bcdUSB 1.00
|
||||
bDeviceClass 0 (Defined at Interface level)
|
||||
bDeviceSubClass 0
|
||||
bDeviceProtocol 0
|
||||
bMaxPacketSize0 16
|
||||
idVendor 0x0c72 PEAK System
|
||||
idProduct 0x000c PCAN-USB
|
||||
bcdDevice 1c.ff
|
||||
iManufacturer 0
|
||||
iProduct 3 VER1:PEAK
|
||||
VER2:02.8.01
|
||||
DAT :06.05.2004
|
||||
TIME:09:35:37
|
||||
...
|
||||
iSerial 0
|
||||
bNumConfigurations 3
|
||||
Configuration Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 2
|
||||
wTotalLength 46
|
||||
bNumInterfaces 1
|
||||
bConfigurationValue 1
|
||||
iConfiguration 0
|
||||
bmAttributes 0x80
|
||||
(Bus Powered)
|
||||
MaxPower 200mA
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 0
|
||||
bAlternateSetting 0
|
||||
bNumEndpoints 4
|
||||
bInterfaceClass 0 (Defined at Interface level)
|
||||
bInterfaceSubClass 0
|
||||
bInterfaceProtocol 0
|
||||
iInterface 0
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x81 EP 1 IN
|
||||
bmAttributes 2
|
||||
Transfer Type Bulk
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0010 1x 16 bytes
|
||||
bInterval 20
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x01 EP 1 OUT
|
||||
bmAttributes 2
|
||||
Transfer Type Bulk
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0010 1x 16 bytes
|
||||
bInterval 20
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x82 EP 2 IN
|
||||
bmAttributes 2
|
||||
Transfer Type Bulk
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0040 1x 64 bytes
|
||||
bInterval 1
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x02 EP 2 OUT
|
||||
bmAttributes 2
|
||||
Transfer Type Bulk
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0040 1x 64 bytes
|
||||
bInterval 1
|
||||
Configuration Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 2
|
||||
wTotalLength 46
|
||||
bNumInterfaces 1
|
||||
bConfigurationValue 2
|
||||
iConfiguration 0
|
||||
bmAttributes 0x80
|
||||
(Bus Powered)
|
||||
MaxPower 394mA
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 0
|
||||
bAlternateSetting 0
|
||||
bNumEndpoints 4
|
||||
bInterfaceClass 0 (Defined at Interface level)
|
||||
bInterfaceSubClass 0
|
||||
bInterfaceProtocol 0
|
||||
iInterface 0
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x81 EP 1 IN
|
||||
bmAttributes 2
|
||||
Transfer Type Bulk
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0010 1x 16 bytes
|
||||
bInterval 20
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x01 EP 1 OUT
|
||||
bmAttributes 2
|
||||
Transfer Type Bulk
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0010 1x 16 bytes
|
||||
bInterval 20
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x82 EP 2 IN
|
||||
bmAttributes 2
|
||||
Transfer Type Bulk
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0040 1x 64 bytes
|
||||
bInterval 1
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x02 EP 2 OUT
|
||||
bmAttributes 2
|
||||
Transfer Type Bulk
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0040 1x 64 bytes
|
||||
bInterval 1
|
||||
Configuration Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 2
|
||||
wTotalLength 46
|
||||
bNumInterfaces 1
|
||||
bConfigurationValue 3
|
||||
iConfiguration 0
|
||||
bmAttributes 0x80
|
||||
(Bus Powered)
|
||||
MaxPower 200mA
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 0
|
||||
bAlternateSetting 0
|
||||
bNumEndpoints 4
|
||||
bInterfaceClass 0 (Defined at Interface level)
|
||||
bInterfaceSubClass 0
|
||||
bInterfaceProtocol 0
|
||||
iInterface 0
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x81 EP 1 IN
|
||||
bmAttributes 3
|
||||
Transfer Type Interrupt
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0010 1x 16 bytes
|
||||
bInterval 1
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x01 EP 1 OUT
|
||||
bmAttributes 3
|
||||
Transfer Type Interrupt
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0010 1x 16 bytes
|
||||
bInterval 1
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x82 EP 2 IN
|
||||
bmAttributes 2
|
||||
Transfer Type Bulk
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0040 1x 64 bytes
|
||||
bInterval 1
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x02 EP 2 OUT
|
||||
bmAttributes 2
|
||||
Transfer Type Bulk
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0040 1x 64 bytes
|
||||
bInterval 1
|
||||
Device Status: 0x0001
|
||||
Self Powered
|
|
@ -0,0 +1,60 @@
|
|||
|
||||
Bus 001 Device 004: ID 0483:df11 SGS Thomson Microelectronics
|
||||
Device Descriptor:
|
||||
bLength 18
|
||||
bDescriptorType 1
|
||||
bcdUSB 1.00
|
||||
bDeviceClass 0 (Defined at Interface level)
|
||||
bDeviceSubClass 0
|
||||
bDeviceProtocol 0
|
||||
bMaxPacketSize0 64
|
||||
idVendor 0x0483 SGS Thomson Microelectronics
|
||||
idProduct 0xdf11
|
||||
bcdDevice 2.00
|
||||
iManufacturer 1 STMicroelectronics
|
||||
iProduct 2 STM32 DFU
|
||||
iSerial 3 ÿÿÿÿÿÿÿÿÿÿÿÿ
|
||||
bNumConfigurations 1
|
||||
Configuration Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 2
|
||||
wTotalLength 36
|
||||
bNumInterfaces 1
|
||||
bConfigurationValue 1
|
||||
iConfiguration 0
|
||||
bmAttributes 0xc0
|
||||
Self Powered
|
||||
MaxPower 100mA
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 0
|
||||
bAlternateSetting 0
|
||||
bNumEndpoints 0
|
||||
bInterfaceClass 254 Application Specific Interface
|
||||
bInterfaceSubClass 1 Device Firmware Update
|
||||
bInterfaceProtocol 2
|
||||
iInterface 4 @Internal Flash /0x08000000/12*001Ka,116*001Kg
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 0
|
||||
bAlternateSetting 1
|
||||
bNumEndpoints 0
|
||||
bInterfaceClass 254 Application Specific Interface
|
||||
bInterfaceSubClass 1 Device Firmware Update
|
||||
bInterfaceProtocol 2
|
||||
iInterface 5 @SPI Flash : M25P64/0x00000000/128*64Kg
|
||||
Device Firmware Upgrade Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 33
|
||||
bmAttributes 11
|
||||
Will Detach
|
||||
Manifestation Intolerant
|
||||
Upload Supported
|
||||
Download Supported
|
||||
wDetachTimeout 255 milliseconds
|
||||
wTransferSize 1024 bytes
|
||||
bcdDFUVersion 1a.01
|
||||
Device Status: 0x0001
|
||||
Self Powered
|
|
@ -0,0 +1,109 @@
|
|||
Bus 003 Device 017: ID 1d50:5119 OpenMoko, Inc. GTA01/GTA02 U-Boot Bootloader
|
||||
Device Descriptor:
|
||||
bLength 18
|
||||
bDescriptorType 1
|
||||
bcdUSB 1.00
|
||||
bDeviceClass 0 (Defined at Interface level)
|
||||
bDeviceSubClass 0
|
||||
bDeviceProtocol 0
|
||||
bMaxPacketSize0 16
|
||||
idVendor 0x1d50 OpenMoko, Inc.
|
||||
idProduct 0x5119 GTA01/GTA02 U-Boot Bootloader
|
||||
bcdDevice 0.00
|
||||
iManufacturer 1 OpenMoko, Inc
|
||||
iProduct 2 Neo1973 Bootloader U-Boot 1.3.2-moko12
|
||||
iSerial 3 0000000
|
||||
bNumConfigurations 1
|
||||
Configuration Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 2
|
||||
wTotalLength 81
|
||||
bNumInterfaces 1
|
||||
bConfigurationValue 1
|
||||
iConfiguration 7 USB Device Firmware Upgrade
|
||||
bmAttributes 0x80
|
||||
(Bus Powered)
|
||||
MaxPower 100mA
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 0
|
||||
bAlternateSetting 0
|
||||
bNumEndpoints 0
|
||||
bInterfaceClass 254 Application Specific Interface
|
||||
bInterfaceSubClass 1 Device Firmware Update
|
||||
bInterfaceProtocol 2
|
||||
iInterface 8 RAM 0x32000000
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 0
|
||||
bAlternateSetting 1
|
||||
bNumEndpoints 0
|
||||
bInterfaceClass 254 Application Specific Interface
|
||||
bInterfaceSubClass 1 Device Firmware Update
|
||||
bInterfaceProtocol 2
|
||||
iInterface 9 u-boot
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 0
|
||||
bAlternateSetting 2
|
||||
bNumEndpoints 0
|
||||
bInterfaceClass 254 Application Specific Interface
|
||||
bInterfaceSubClass 1 Device Firmware Update
|
||||
bInterfaceProtocol 2
|
||||
iInterface 10 u-boot_env
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 0
|
||||
bAlternateSetting 3
|
||||
bNumEndpoints 0
|
||||
bInterfaceClass 254 Application Specific Interface
|
||||
bInterfaceSubClass 1 Device Firmware Update
|
||||
bInterfaceProtocol 2
|
||||
iInterface 11 kernel
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 0
|
||||
bAlternateSetting 4
|
||||
bNumEndpoints 0
|
||||
bInterfaceClass 254 Application Specific Interface
|
||||
bInterfaceSubClass 1 Device Firmware Update
|
||||
bInterfaceProtocol 2
|
||||
iInterface 12 splash
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 0
|
||||
bAlternateSetting 5
|
||||
bNumEndpoints 0
|
||||
bInterfaceClass 254 Application Specific Interface
|
||||
bInterfaceSubClass 1 Device Firmware Update
|
||||
bInterfaceProtocol 2
|
||||
iInterface 13 factory
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 0
|
||||
bAlternateSetting 6
|
||||
bNumEndpoints 0
|
||||
bInterfaceClass 254 Application Specific Interface
|
||||
bInterfaceSubClass 1 Device Firmware Update
|
||||
bInterfaceProtocol 2
|
||||
iInterface 14 rootfs
|
||||
Device Firmware Upgrade Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 33
|
||||
bmAttributes 7
|
||||
Will Not Detach
|
||||
Manifestation Tolerant
|
||||
Upload Supported
|
||||
Download Supported
|
||||
wDetachTimeout 65280 milliseconds
|
||||
wTransferSize 4096 bytes
|
||||
bcdDFUVersion 1.00
|
||||
Device Status: 0x0a00
|
||||
(Bus Powered)
|
|
@ -0,0 +1,179 @@
|
|||
Bus 005 Device 033: ID 1d50:5119 OpenMoko, Inc. GTA01/GTA02 U-Boot Bootloader
|
||||
Device Descriptor:
|
||||
bLength 18
|
||||
bDescriptorType 1
|
||||
bcdUSB 1.10
|
||||
bDeviceClass 2 Communications
|
||||
bDeviceSubClass 0
|
||||
bDeviceProtocol 0
|
||||
bMaxPacketSize0 16
|
||||
idVendor 0x1d50 OpenMoko, Inc.
|
||||
idProduct 0x5119 GTA01/GTA02 U-Boot Bootloader
|
||||
bcdDevice 0.00
|
||||
iManufacturer 1 OpenMoko, Inc
|
||||
iProduct 2 Neo1973 Bootloader U-Boot 1.3.2-moko12
|
||||
iSerial 3 0000000
|
||||
bNumConfigurations 2
|
||||
Configuration Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 2
|
||||
wTotalLength 85
|
||||
bNumInterfaces 3
|
||||
bConfigurationValue 1
|
||||
iConfiguration 4 TTY via USB
|
||||
bmAttributes 0x80
|
||||
(Bus Powered)
|
||||
MaxPower 500mA
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 0
|
||||
bAlternateSetting 0
|
||||
bNumEndpoints 1
|
||||
bInterfaceClass 2 Communications
|
||||
bInterfaceSubClass 2 Abstract (modem)
|
||||
bInterfaceProtocol 1 AT-commands (v.25ter)
|
||||
iInterface 6 Control Interface
|
||||
CDC Header:
|
||||
bcdCDC 0.6e
|
||||
CDC Call Management:
|
||||
bmCapabilities 0x00
|
||||
bDataInterface 1
|
||||
CDC ACM:
|
||||
bmCapabilities 0x00
|
||||
CDC Union:
|
||||
bMasterInterface 0
|
||||
bSlaveInterface 1
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x81 EP 1 IN
|
||||
bmAttributes 3
|
||||
Transfer Type Interrupt
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0010 1x 16 bytes
|
||||
bInterval 255
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 1
|
||||
bAlternateSetting 0
|
||||
bNumEndpoints 2
|
||||
bInterfaceClass 10 CDC Data
|
||||
bInterfaceSubClass 0 Unused
|
||||
bInterfaceProtocol 0
|
||||
iInterface 5 Bulk Data Interface
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x02 EP 2 OUT
|
||||
bmAttributes 2
|
||||
Transfer Type Bulk
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0010 1x 16 bytes
|
||||
bInterval 255
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x83 EP 3 IN
|
||||
bmAttributes 2
|
||||
Transfer Type Bulk
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0010 1x 16 bytes
|
||||
bInterval 255
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 2
|
||||
bAlternateSetting 0
|
||||
bNumEndpoints 0
|
||||
bInterfaceClass 254 Application Specific Interface
|
||||
bInterfaceSubClass 1 Device Firmware Update
|
||||
bInterfaceProtocol 1
|
||||
iInterface 7 USB Device Firmware Upgrade
|
||||
Device Firmware Upgrade Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 33
|
||||
bmAttributes 7
|
||||
Will Not Detach
|
||||
Manifestation Tolerant
|
||||
Upload Supported
|
||||
Download Supported
|
||||
wDetachTimeout 65280 milliseconds
|
||||
wTransferSize 4096 bytes
|
||||
bcdDFUVersion 1.00
|
||||
Configuration Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 2
|
||||
wTotalLength 67
|
||||
bNumInterfaces 2
|
||||
bConfigurationValue 2
|
||||
iConfiguration 4 TTY via USB
|
||||
bmAttributes 0x80
|
||||
(Bus Powered)
|
||||
MaxPower 100mA
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 0
|
||||
bAlternateSetting 0
|
||||
bNumEndpoints 1
|
||||
bInterfaceClass 2 Communications
|
||||
bInterfaceSubClass 2 Abstract (modem)
|
||||
bInterfaceProtocol 1 AT-commands (v.25ter)
|
||||
iInterface 6 Control Interface
|
||||
CDC Header:
|
||||
bcdCDC 0.6e
|
||||
CDC Call Management:
|
||||
bmCapabilities 0x00
|
||||
bDataInterface 1
|
||||
CDC ACM:
|
||||
bmCapabilities 0x00
|
||||
CDC Union:
|
||||
bMasterInterface 0
|
||||
bSlaveInterface 1
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x81 EP 1 IN
|
||||
bmAttributes 3
|
||||
Transfer Type Interrupt
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0010 1x 16 bytes
|
||||
bInterval 255
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 1
|
||||
bAlternateSetting 0
|
||||
bNumEndpoints 2
|
||||
bInterfaceClass 10 CDC Data
|
||||
bInterfaceSubClass 0 Unused
|
||||
bInterfaceProtocol 0
|
||||
iInterface 5 Bulk Data Interface
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x02 EP 2 OUT
|
||||
bmAttributes 2
|
||||
Transfer Type Bulk
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0010 1x 16 bytes
|
||||
bInterval 255
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x83 EP 3 IN
|
||||
bmAttributes 2
|
||||
Transfer Type Bulk
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0010 1x 16 bytes
|
||||
bInterval 255
|
||||
Device Status: 0x9a00
|
||||
(Bus Powered)
|
|
@ -0,0 +1,182 @@
|
|||
|
||||
Bus 006 Device 020: ID 1457:5119 First International Computer, Inc. OpenMoko Neo1973 u-boot cdc_acm serial port
|
||||
Device Descriptor:
|
||||
bLength 18
|
||||
bDescriptorType 1
|
||||
bcdUSB 1.10
|
||||
bDeviceClass 2 Communications
|
||||
bDeviceSubClass 0
|
||||
bDeviceProtocol 0
|
||||
bMaxPacketSize0 16
|
||||
idVendor 0x1457 First International Computer, Inc.
|
||||
idProduct 0x5119 OpenMoko Neo1973 u-boot cdc_acm serial port
|
||||
bcdDevice 0.00
|
||||
iManufacturer 1
|
||||
iProduct 2
|
||||
iSerial 3
|
||||
bNumConfigurations 2
|
||||
Configuration Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 2
|
||||
wTotalLength 85
|
||||
bNumInterfaces 3
|
||||
bConfigurationValue 1
|
||||
iConfiguration 4
|
||||
bmAttributes 0x80
|
||||
(Bus Powered)
|
||||
MaxPower 500mA
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 0
|
||||
bAlternateSetting 0
|
||||
bNumEndpoints 1
|
||||
bInterfaceClass 2 Communications
|
||||
bInterfaceSubClass 2 Abstract (modem)
|
||||
bInterfaceProtocol 1 AT-commands (v.25ter)
|
||||
iInterface 6
|
||||
CDC Header:
|
||||
bcdCDC 0.6e
|
||||
CDC Call Management:
|
||||
bmCapabilities 0x00
|
||||
bDataInterface 1
|
||||
CDC ACM:
|
||||
bmCapabilities 0x00
|
||||
CDC Union:
|
||||
bMasterInterface 0
|
||||
bSlaveInterface 1
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x81 EP 1 IN
|
||||
bmAttributes 3
|
||||
Transfer Type Interrupt
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0010 1x 16 bytes
|
||||
bInterval 255
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 1
|
||||
bAlternateSetting 0
|
||||
bNumEndpoints 2
|
||||
bInterfaceClass 10 CDC Data
|
||||
bInterfaceSubClass 0 Unused
|
||||
bInterfaceProtocol 0
|
||||
iInterface 5
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x02 EP 2 OUT
|
||||
bmAttributes 2
|
||||
Transfer Type Bulk
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0010 1x 16 bytes
|
||||
bInterval 255
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x83 EP 3 IN
|
||||
bmAttributes 2
|
||||
Transfer Type Bulk
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0010 1x 16 bytes
|
||||
bInterval 255
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 2
|
||||
bAlternateSetting 0
|
||||
bNumEndpoints 0
|
||||
bInterfaceClass 254 Application Specific Interface
|
||||
bInterfaceSubClass 1 Device Firmware Update
|
||||
bInterfaceProtocol 1
|
||||
iInterface 7
|
||||
Device Firmware Upgrade Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 33
|
||||
bmAttributes 7
|
||||
Will Not Detach
|
||||
Manifestation Tolerant
|
||||
Upload Supported
|
||||
Download Supported
|
||||
wDetachTimeout 65280 milliseconds
|
||||
wTransferSize 4096 bytes
|
||||
bcdDFUVersion 1.00
|
||||
Configuration Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 2
|
||||
wTotalLength 67
|
||||
bNumInterfaces 2
|
||||
bConfigurationValue 2
|
||||
iConfiguration 4
|
||||
bmAttributes 0x80
|
||||
(Bus Powered)
|
||||
MaxPower 100mA
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 0
|
||||
bAlternateSetting 0
|
||||
bNumEndpoints 1
|
||||
bInterfaceClass 2 Communications
|
||||
bInterfaceSubClass 2 Abstract (modem)
|
||||
bInterfaceProtocol 1 AT-commands (v.25ter)
|
||||
iInterface 6
|
||||
CDC Header:
|
||||
bcdCDC 0.6e
|
||||
CDC Call Management:
|
||||
bmCapabilities 0x00
|
||||
bDataInterface 1
|
||||
CDC ACM:
|
||||
bmCapabilities 0x00
|
||||
CDC Union:
|
||||
bMasterInterface 0
|
||||
bSlaveInterface 1
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x81 EP 1 IN
|
||||
bmAttributes 3
|
||||
Transfer Type Interrupt
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0010 1x 16 bytes
|
||||
bInterval 255
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 1
|
||||
bAlternateSetting 0
|
||||
bNumEndpoints 2
|
||||
bInterfaceClass 10 CDC Data
|
||||
bInterfaceSubClass 0 Unused
|
||||
bInterfaceProtocol 0
|
||||
iInterface 5
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x02 EP 2 OUT
|
||||
bmAttributes 2
|
||||
Transfer Type Bulk
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0010 1x 16 bytes
|
||||
bInterval 255
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x83 EP 3 IN
|
||||
bmAttributes 2
|
||||
Transfer Type Bulk
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0010 1x 16 bytes
|
||||
bInterval 255
|
||||
Device Status: 0x0006
|
||||
(Bus Powered)
|
||||
Remote Wakeup Enabled
|
||||
Test Mode
|
|
@ -0,0 +1,60 @@
|
|||
|
||||
Bus 006 Device 016: ID 16c0:076b VOTI OpenPCD 13.56MHz RFID Reader
|
||||
Device Descriptor:
|
||||
bLength 18
|
||||
bDescriptorType 1
|
||||
bcdUSB 1.00
|
||||
bDeviceClass 0 (Defined at Interface level)
|
||||
bDeviceSubClass 0
|
||||
bDeviceProtocol 0
|
||||
bMaxPacketSize0 8
|
||||
idVendor 0x16c0 VOTI
|
||||
idProduct 0x076b OpenPCD 13.56MHz RFID Reader
|
||||
bcdDevice 0.00
|
||||
iManufacturer 1
|
||||
iProduct 2 OpenPCD RFID Simulator - DFU Mode
|
||||
iSerial 0
|
||||
bNumConfigurations 1
|
||||
Configuration Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 2
|
||||
wTotalLength 36
|
||||
bNumInterfaces 1
|
||||
bConfigurationValue 1
|
||||
iConfiguration 0
|
||||
bmAttributes 0x80
|
||||
(Bus Powered)
|
||||
MaxPower 200mA
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 0
|
||||
bAlternateSetting 0
|
||||
bNumEndpoints 0
|
||||
bInterfaceClass 254 Application Specific Interface
|
||||
bInterfaceSubClass 1 Device Firmware Update
|
||||
bInterfaceProtocol 2
|
||||
iInterface 0
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 0
|
||||
bAlternateSetting 1
|
||||
bNumEndpoints 0
|
||||
bInterfaceClass 254 Application Specific Interface
|
||||
bInterfaceSubClass 1 Device Firmware Update
|
||||
bInterfaceProtocol 2
|
||||
iInterface 0
|
||||
Device Firmware Upgrade Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 33
|
||||
bmAttributes 3
|
||||
Will Not Detach
|
||||
Manifestation Intolerant
|
||||
Upload Supported
|
||||
Download Supported
|
||||
wDetachTimeout 65280 milliseconds
|
||||
wTransferSize 256 bytes
|
||||
bcdDFUVersion 1.00
|
||||
Device Status: 0x0000
|
||||
(Bus Powered)
|
|
@ -0,0 +1,59 @@
|
|||
|
||||
Bus 006 Device 013: ID 20b7:1540 Qi Hardware ben-wpan, AT86RF230-based
|
||||
Device Descriptor:
|
||||
bLength 18
|
||||
bDescriptorType 1
|
||||
bcdUSB 2.00
|
||||
bDeviceClass 255 Vendor Specific Class
|
||||
bDeviceSubClass 0
|
||||
bDeviceProtocol 0
|
||||
bMaxPacketSize0 64
|
||||
idVendor 0x20b7 Qi Hardware
|
||||
idProduct 0x1540 ben-wpan, AT86RF230-based
|
||||
bcdDevice 0.01
|
||||
iManufacturer 0
|
||||
iProduct 0
|
||||
iSerial 1 4630333438371508231a
|
||||
bNumConfigurations 1
|
||||
Configuration Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 2
|
||||
wTotalLength 34
|
||||
bNumInterfaces 2
|
||||
bConfigurationValue 1
|
||||
iConfiguration 0
|
||||
bmAttributes 0x80
|
||||
(Bus Powered)
|
||||
MaxPower 40mA
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 0
|
||||
bAlternateSetting 0
|
||||
bNumEndpoints 1
|
||||
bInterfaceClass 255 Vendor Specific Class
|
||||
bInterfaceSubClass 0
|
||||
bInterfaceProtocol 0
|
||||
iInterface 0
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x81 EP 1 IN
|
||||
bmAttributes 2
|
||||
Transfer Type Bulk
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0040 1x 64 bytes
|
||||
bInterval 0
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 1
|
||||
bAlternateSetting 0
|
||||
bNumEndpoints 0
|
||||
bInterfaceClass 254 Application Specific Interface
|
||||
bInterfaceSubClass 1 Device Firmware Update
|
||||
bInterfaceProtocol 1
|
||||
iInterface 0
|
||||
Device Status: 0x0000
|
||||
(Bus Powered)
|
|
@ -0,0 +1,70 @@
|
|||
|
||||
Bus 006 Device 017: ID 16c0:0762 VOTI
|
||||
Device Descriptor:
|
||||
bLength 18
|
||||
bDescriptorType 1
|
||||
bcdUSB 1.00
|
||||
bDeviceClass 0 (Defined at Interface level)
|
||||
bDeviceSubClass 0
|
||||
bDeviceProtocol 0
|
||||
bMaxPacketSize0 8
|
||||
idVendor 0x16c0 VOTI
|
||||
idProduct 0x0762
|
||||
bcdDevice 0.00
|
||||
iManufacturer 1 sysmocom - systems for mobile communications GmbH
|
||||
iProduct 2 SimTrace SIM Sniffer - DFU Mode
|
||||
iSerial 0
|
||||
bNumConfigurations 1
|
||||
Configuration Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 2
|
||||
wTotalLength 45
|
||||
bNumInterfaces 1
|
||||
bConfigurationValue 1
|
||||
iConfiguration 3 SimTrace DFU Configuration
|
||||
bmAttributes 0x80
|
||||
(Bus Powered)
|
||||
MaxPower 200mA
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 0
|
||||
bAlternateSetting 0
|
||||
bNumEndpoints 0
|
||||
bInterfaceClass 254 Application Specific Interface
|
||||
bInterfaceSubClass 1 Device Firmware Update
|
||||
bInterfaceProtocol 2
|
||||
iInterface 4 SimTrace DFU Interface - Application Partition
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 0
|
||||
bAlternateSetting 1
|
||||
bNumEndpoints 0
|
||||
bInterfaceClass 254 Application Specific Interface
|
||||
bInterfaceSubClass 1 Device Firmware Update
|
||||
bInterfaceProtocol 2
|
||||
iInterface 5 SimTrace DFU Interface - Bootloader Partition
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 0
|
||||
bAlternateSetting 2
|
||||
bNumEndpoints 0
|
||||
bInterfaceClass 254 Application Specific Interface
|
||||
bInterfaceSubClass 1 Device Firmware Update
|
||||
bInterfaceProtocol 2
|
||||
iInterface 6 SimTrace DFU Interface - RAM
|
||||
Device Firmware Upgrade Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 33
|
||||
bmAttributes 3
|
||||
Will Not Detach
|
||||
Manifestation Intolerant
|
||||
Upload Supported
|
||||
Download Supported
|
||||
wDetachTimeout 65280 milliseconds
|
||||
wTransferSize 256 bytes
|
||||
bcdDFUVersion 1.00
|
||||
Device Status: 0x0000
|
||||
(Bus Powered)
|
|
@ -0,0 +1,60 @@
|
|||
|
||||
Bus 001 Device 008: ID 1d50:607f OpenMoko, Inc.
|
||||
Device Descriptor:
|
||||
bLength 18
|
||||
bDescriptorType 1
|
||||
bcdUSB 1.00
|
||||
bDeviceClass 0 (Defined at Interface level)
|
||||
bDeviceSubClass 0
|
||||
bDeviceProtocol 0
|
||||
bMaxPacketSize0 64
|
||||
idVendor 0x1d50 OpenMoko, Inc.
|
||||
idProduct 0x607f
|
||||
bcdDevice 2.00
|
||||
iManufacturer 1 Spark Devices
|
||||
iProduct 2 CORE DFU
|
||||
iSerial 3 8D80527B5055
|
||||
bNumConfigurations 1
|
||||
Configuration Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 2
|
||||
wTotalLength 36
|
||||
bNumInterfaces 1
|
||||
bConfigurationValue 1
|
||||
iConfiguration 0
|
||||
bmAttributes 0xc0
|
||||
Self Powered
|
||||
MaxPower 100mA
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 0
|
||||
bAlternateSetting 0
|
||||
bNumEndpoints 0
|
||||
bInterfaceClass 254 Application Specific Interface
|
||||
bInterfaceSubClass 1 Device Firmware Update
|
||||
bInterfaceProtocol 2
|
||||
iInterface 4 @Internal Flash /0x08000000/20*001Ka,108*001Kg
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 0
|
||||
bAlternateSetting 1
|
||||
bNumEndpoints 0
|
||||
bInterfaceClass 254 Application Specific Interface
|
||||
bInterfaceSubClass 1 Device Firmware Update
|
||||
bInterfaceProtocol 2
|
||||
iInterface 5 @SPI Flash : SST25x/0x00000000/512*04Kg
|
||||
Device Firmware Upgrade Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 33
|
||||
bmAttributes 11
|
||||
Will Detach
|
||||
Manifestation Intolerant
|
||||
Upload Supported
|
||||
Download Supported
|
||||
wDetachTimeout 255 milliseconds
|
||||
wTransferSize 1024 bytes
|
||||
bcdDFUVersion 1.1a
|
||||
Device Status: 0x0001
|
||||
Self Powered
|
|
@ -0,0 +1,48 @@
|
|||
> src/dfu-util --intf 0 --alt 0 -v -v -v -s 0x8000000 -D test3
|
||||
dfu-util 0.4
|
||||
|
||||
(C) 2005-2008 by Weston Schmidt, Harald Welte and OpenMoko Inc.
|
||||
(C) 2010-2011 Tormod Volden (DfuSe support)
|
||||
This program is Free Software and has ABSOLUTELY NO WARRANTY
|
||||
|
||||
dfu-util does currently only support DFU version 1.0
|
||||
|
||||
Opening DFU USB device... ID 0483:df11
|
||||
Run-time device DFU version 011a
|
||||
Found DFU: [0483:df11] devnum=0, cfg=1, intf=0, alt=0, name="@Internal Flash /0x08000000/128*002Kg"
|
||||
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 2048
|
||||
No valid DFU suffix signature
|
||||
Warning: File has no DFU suffix
|
||||
DfuSe interface name: "Internal Flash "
|
||||
Memory segment at 0x08000000 128 x 2048 = 262144 (rew)
|
||||
Uploading to address = 0x08000000, size = 16384
|
||||
Erasing page size 2048 at address 0x08000000, page starting at 0x08000000
|
||||
Download from image offset 00000000 to memory 08000000-080007ff, size 2048
|
||||
Setting address pointer to 0x08000000
|
||||
Erasing page size 2048 at address 0x08000800, page starting at 0x08000800
|
||||
Download from image offset 00000800 to memory 08000800-08000fff, size 2048
|
||||
Setting address pointer to 0x08000800
|
||||
Erasing page size 2048 at address 0x08001000, page starting at 0x08001000
|
||||
Download from image offset 00001000 to memory 08001000-080017ff, size 2048
|
||||
Setting address pointer to 0x08001000
|
||||
Erasing page size 2048 at address 0x08001800, page starting at 0x08001800
|
||||
Download from image offset 00001800 to memory 08001800-08001fff, size 2048
|
||||
Setting address pointer to 0x08001800
|
||||
Erasing page size 2048 at address 0x08002000, page starting at 0x08002000
|
||||
Download from image offset 00002000 to memory 08002000-080027ff, size 2048
|
||||
Setting address pointer to 0x08002000
|
||||
Erasing page size 2048 at address 0x08002800, page starting at 0x08002800
|
||||
Download from image offset 00002800 to memory 08002800-08002fff, size 2048
|
||||
Setting address pointer to 0x08002800
|
||||
Erasing page size 2048 at address 0x08003000, page starting at 0x08003000
|
||||
Download from image offset 00003000 to memory 08003000-080037ff, size 2048
|
||||
Setting address pointer to 0x08003000
|
||||
Erasing page size 2048 at address 0x08003800, page starting at 0x08003800
|
||||
Download from image offset 00003800 to memory 08003800-08003fff, size 2048
|
||||
Setting address pointer to 0x08003800
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
|
||||
Bus 001 Device 028: ID 0483:df11 SGS Thomson Microelectronics STM Device in DFU Mode
|
||||
Device Descriptor:
|
||||
bLength 18
|
||||
bDescriptorType 1
|
||||
bcdUSB 1.00
|
||||
bDeviceClass 0 (Defined at Interface level)
|
||||
bDeviceSubClass 0
|
||||
bDeviceProtocol 0
|
||||
bMaxPacketSize0 64
|
||||
idVendor 0x0483 SGS Thomson Microelectronics
|
||||
idProduct 0xdf11 STM Device in DFU Mode
|
||||
bcdDevice 20.00
|
||||
iManufacturer 1 STMicroelectronics
|
||||
iProduct 2 STM32 0x418 DFU Bootloader
|
||||
iSerial 3 STM32
|
||||
bNumConfigurations 1
|
||||
Configuration Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 2
|
||||
wTotalLength 36
|
||||
bNumInterfaces 1
|
||||
bConfigurationValue 1
|
||||
iConfiguration 0
|
||||
bmAttributes 0xc0
|
||||
Self Powered
|
||||
MaxPower 100mA
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 0
|
||||
bAlternateSetting 0
|
||||
bNumEndpoints 0
|
||||
bInterfaceClass 254 Application Specific Interface
|
||||
bInterfaceSubClass 1 Device Firmware Update
|
||||
bInterfaceProtocol 2
|
||||
iInterface 4 @Internal Flash /0x08000000/128*002Kg
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 0
|
||||
bAlternateSetting 1
|
||||
bNumEndpoints 0
|
||||
bInterfaceClass 254 Application Specific Interface
|
||||
bInterfaceSubClass 1 Device Firmware Update
|
||||
bInterfaceProtocol 2
|
||||
iInterface 5 @Option Bytes /0x1FFFF800/01*016 g
|
||||
Device Firmware Upgrade Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 33
|
||||
bmAttributes 11
|
||||
Will Detach
|
||||
Manifestation Intolerant
|
||||
Upload Supported
|
||||
Download Supported
|
||||
wDetachTimeout 255 milliseconds
|
||||
wTransferSize 2048 bytes
|
||||
bcdDFUVersion 1.1a
|
||||
Device Status: 0x0000
|
||||
(Bus Powered)
|
|
@ -0,0 +1,36 @@
|
|||
dfu-util --device 0483:df11 --alt 0 \
|
||||
--dfuse-address 0x08000000 \
|
||||
-v -v -v \
|
||||
--download arm/iotoggle.bin
|
||||
No valid DFU suffix signature
|
||||
Warning: File has no DFU suffix
|
||||
dfu-util 0.5
|
||||
|
||||
(C) 2005-2008 by Weston Schmidt, Harald Welte and OpenMoko Inc.
|
||||
(C) 2010-2011 Tormod Volden (DfuSe support)
|
||||
This program is Free Software and has ABSOLUTELY NO WARRANTY
|
||||
|
||||
dfu-util does currently only support DFU version 1.0
|
||||
|
||||
Filter on vendor = 0x0483 product = 0xdf11
|
||||
Opening DFU capable USB device... ID 0483:df11
|
||||
Run-time device DFU version 011a
|
||||
Found DFU: [0483:df11] devnum=0, cfg=1, intf=0, alt=0, name="@Internal Flash /0x08000000/04*016Kg,01*064Kg,07*128Kg"
|
||||
Claiming USB DFU Interface...
|
||||
Setting Alternate Setting #0 ...
|
||||
Determining device status: state = dfuERROR, status = 10
|
||||
dfuERROR, clearing status
|
||||
Determining device status: state = dfuIDLE, status = 0
|
||||
dfuIDLE, continuing
|
||||
DFU mode device DFU version 011a
|
||||
Device returned transfer size 2048
|
||||
DfuSe interface name: "Internal Flash "
|
||||
Memory segment at 0x08000000 4 x 16384 = 65536 (rew)
|
||||
Memory segment at 0x08010000 1 x 65536 = 65536 (rew)
|
||||
Memory segment at 0x08020000 7 x 131072 = 917504 (rew)
|
||||
Uploading to address = 0x08000000, size = 2308
|
||||
Erasing page size 16384 at address 0x08000000, page starting at 0x08000000
|
||||
Download from image offset 00000000 to memory 08000000-080007ff, size 2048
|
||||
Setting address pointer to 0x08000000
|
||||
Download from image offset 00000800 to memory 08000800-08000903, size 260
|
||||
Setting address pointer to 0x08000800
|
|
@ -0,0 +1,80 @@
|
|||
|
||||
Bus 001 Device 010: ID 0483:df11 SGS Thomson Microelectronics STM Device in DFU Mode
|
||||
Device Descriptor:
|
||||
bLength 18
|
||||
bDescriptorType 1
|
||||
bcdUSB 1.00
|
||||
bDeviceClass 0 (Defined at Interface level)
|
||||
bDeviceSubClass 0
|
||||
bDeviceProtocol 0
|
||||
bMaxPacketSize0 64
|
||||
idVendor 0x0483 SGS Thomson Microelectronics
|
||||
idProduct 0xdf11 STM Device in DFU Mode
|
||||
bcdDevice 21.00
|
||||
iManufacturer 1 STMicroelectronics
|
||||
iProduct 2 STM32 BOOTLOADER
|
||||
iSerial 3 315A28A0B956
|
||||
bNumConfigurations 1
|
||||
Configuration Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 2
|
||||
wTotalLength 54
|
||||
bNumInterfaces 1
|
||||
bConfigurationValue 1
|
||||
iConfiguration 0
|
||||
bmAttributes 0xc0
|
||||
Self Powered
|
||||
MaxPower 100mA
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 0
|
||||
bAlternateSetting 0
|
||||
bNumEndpoints 0
|
||||
bInterfaceClass 254 Application Specific Interface
|
||||
bInterfaceSubClass 1 Device Firmware Update
|
||||
bInterfaceProtocol 2
|
||||
iInterface 4 @Internal Flash /0x08000000/04*016Kg,01*064Kg,07*128Kg
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 0
|
||||
bAlternateSetting 1
|
||||
bNumEndpoints 0
|
||||
bInterfaceClass 254 Application Specific Interface
|
||||
bInterfaceSubClass 1 Device Firmware Update
|
||||
bInterfaceProtocol 2
|
||||
iInterface 5 @Option Bytes /0x1FFFC000/01*016 g
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 0
|
||||
bAlternateSetting 2
|
||||
bNumEndpoints 0
|
||||
bInterfaceClass 254 Application Specific Interface
|
||||
bInterfaceSubClass 1 Device Firmware Update
|
||||
bInterfaceProtocol 2
|
||||
iInterface 6 @OTP Memory /0x1FFF7800/01*512 g,01*016 g
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 0
|
||||
bAlternateSetting 3
|
||||
bNumEndpoints 0
|
||||
bInterfaceClass 254 Application Specific Interface
|
||||
bInterfaceSubClass 1 Device Firmware Update
|
||||
bInterfaceProtocol 2
|
||||
iInterface 7 @Device Feature/0xFFFF0000/01*004 g
|
||||
Device Firmware Upgrade Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 33
|
||||
bmAttributes 11
|
||||
Will Detach
|
||||
Manifestation Intolerant
|
||||
Upload Supported
|
||||
Download Supported
|
||||
wDetachTimeout 255 milliseconds
|
||||
wTransferSize 2048 bytes
|
||||
bcdDFUVersion 1.1a
|
||||
Device Status: 0x0001
|
||||
Self Powered
|
|
@ -0,0 +1,269 @@
|
|||
|
||||
Bus 006 Device 014: ID 04bf:0320 TDK Corp. Bluetooth Adapter
|
||||
Device Descriptor:
|
||||
bLength 18
|
||||
bDescriptorType 1
|
||||
bcdUSB 2.00
|
||||
bDeviceClass 224 Wireless
|
||||
bDeviceSubClass 1 Radio Frequency
|
||||
bDeviceProtocol 1 Bluetooth
|
||||
bMaxPacketSize0 64
|
||||
idVendor 0x04bf TDK Corp.
|
||||
idProduct 0x0320 Bluetooth Adapter
|
||||
bcdDevice 26.52
|
||||
iManufacturer 1 Ezurio
|
||||
iProduct 2 Turbo Bluetooth Adapter
|
||||
iSerial 3 008098D4FFBD
|
||||
bNumConfigurations 1
|
||||
Configuration Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 2
|
||||
wTotalLength 193
|
||||
bNumInterfaces 3
|
||||
bConfigurationValue 1
|
||||
iConfiguration 0
|
||||
bmAttributes 0x80
|
||||
(Bus Powered)
|
||||
MaxPower 64mA
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 0
|
||||
bAlternateSetting 0
|
||||
bNumEndpoints 3
|
||||
bInterfaceClass 224 Wireless
|
||||
bInterfaceSubClass 1 Radio Frequency
|
||||
bInterfaceProtocol 1 Bluetooth
|
||||
iInterface 0
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x81 EP 1 IN
|
||||
bmAttributes 3
|
||||
Transfer Type Interrupt
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0010 1x 16 bytes
|
||||
bInterval 1
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x02 EP 2 OUT
|
||||
bmAttributes 2
|
||||
Transfer Type Bulk
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0040 1x 64 bytes
|
||||
bInterval 1
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x82 EP 2 IN
|
||||
bmAttributes 2
|
||||
Transfer Type Bulk
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0040 1x 64 bytes
|
||||
bInterval 1
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 1
|
||||
bAlternateSetting 0
|
||||
bNumEndpoints 2
|
||||
bInterfaceClass 224 Wireless
|
||||
bInterfaceSubClass 1 Radio Frequency
|
||||
bInterfaceProtocol 1 Bluetooth
|
||||
iInterface 0
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x03 EP 3 OUT
|
||||
bmAttributes 1
|
||||
Transfer Type Isochronous
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0000 1x 0 bytes
|
||||
bInterval 1
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x83 EP 3 IN
|
||||
bmAttributes 1
|
||||
Transfer Type Isochronous
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0000 1x 0 bytes
|
||||
bInterval 1
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 1
|
||||
bAlternateSetting 1
|
||||
bNumEndpoints 2
|
||||
bInterfaceClass 224 Wireless
|
||||
bInterfaceSubClass 1 Radio Frequency
|
||||
bInterfaceProtocol 1 Bluetooth
|
||||
iInterface 0
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x03 EP 3 OUT
|
||||
bmAttributes 1
|
||||
Transfer Type Isochronous
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0009 1x 9 bytes
|
||||
bInterval 1
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x83 EP 3 IN
|
||||
bmAttributes 1
|
||||
Transfer Type Isochronous
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0009 1x 9 bytes
|
||||
bInterval 1
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 1
|
||||
bAlternateSetting 2
|
||||
bNumEndpoints 2
|
||||
bInterfaceClass 224 Wireless
|
||||
bInterfaceSubClass 1 Radio Frequency
|
||||
bInterfaceProtocol 1 Bluetooth
|
||||
iInterface 0
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x03 EP 3 OUT
|
||||
bmAttributes 1
|
||||
Transfer Type Isochronous
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0011 1x 17 bytes
|
||||
bInterval 1
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x83 EP 3 IN
|
||||
bmAttributes 1
|
||||
Transfer Type Isochronous
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0011 1x 17 bytes
|
||||
bInterval 1
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 1
|
||||
bAlternateSetting 3
|
||||
bNumEndpoints 2
|
||||
bInterfaceClass 224 Wireless
|
||||
bInterfaceSubClass 1 Radio Frequency
|
||||
bInterfaceProtocol 1 Bluetooth
|
||||
iInterface 0
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x03 EP 3 OUT
|
||||
bmAttributes 1
|
||||
Transfer Type Isochronous
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0019 1x 25 bytes
|
||||
bInterval 1
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x83 EP 3 IN
|
||||
bmAttributes 1
|
||||
Transfer Type Isochronous
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0019 1x 25 bytes
|
||||
bInterval 1
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 1
|
||||
bAlternateSetting 4
|
||||
bNumEndpoints 2
|
||||
bInterfaceClass 224 Wireless
|
||||
bInterfaceSubClass 1 Radio Frequency
|
||||
bInterfaceProtocol 1 Bluetooth
|
||||
iInterface 0
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x03 EP 3 OUT
|
||||
bmAttributes 1
|
||||
Transfer Type Isochronous
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0021 1x 33 bytes
|
||||
bInterval 1
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x83 EP 3 IN
|
||||
bmAttributes 1
|
||||
Transfer Type Isochronous
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0021 1x 33 bytes
|
||||
bInterval 1
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 1
|
||||
bAlternateSetting 5
|
||||
bNumEndpoints 2
|
||||
bInterfaceClass 224 Wireless
|
||||
bInterfaceSubClass 1 Radio Frequency
|
||||
bInterfaceProtocol 1 Bluetooth
|
||||
iInterface 0
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x03 EP 3 OUT
|
||||
bmAttributes 1
|
||||
Transfer Type Isochronous
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0031 1x 49 bytes
|
||||
bInterval 1
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x83 EP 3 IN
|
||||
bmAttributes 1
|
||||
Transfer Type Isochronous
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0031 1x 49 bytes
|
||||
bInterval 1
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 2
|
||||
bAlternateSetting 0
|
||||
bNumEndpoints 0
|
||||
bInterfaceClass 254 Application Specific Interface
|
||||
bInterfaceSubClass 1 Device Firmware Update
|
||||
bInterfaceProtocol 0
|
||||
iInterface 0
|
||||
Device Firmware Upgrade Interface Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 33
|
||||
bmAttributes 7
|
||||
Will Not Detach
|
||||
Manifestation Tolerant
|
||||
Upload Supported
|
||||
Download Supported
|
||||
wDetachTimeout 5000 milliseconds
|
||||
wTransferSize 1023 bytes
|
||||
Device Status: 0x0000
|
||||
(Bus Powered)
|
|
@ -0,0 +1,121 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
# Written by Antonio Galea - 2010/11/18
|
||||
# Distributed under Gnu LGPL 3.0
|
||||
# see http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
|
||||
import sys,struct,zlib,os
|
||||
from optparse import OptionParser
|
||||
|
||||
DEFAULT_DEVICE="0x0483:0xdf11"
|
||||
|
||||
def named(tuple,names):
|
||||
return dict(zip(names.split(),tuple))
|
||||
def consume(fmt,data,names):
|
||||
n = struct.calcsize(fmt)
|
||||
return named(struct.unpack(fmt,data[:n]),names),data[n:]
|
||||
def cstring(string):
|
||||
return string.split('\0',1)[0]
|
||||
def compute_crc(data):
|
||||
return 0xFFFFFFFF & -zlib.crc32(data) -1
|
||||
|
||||
def parse(file,dump_images=False):
|
||||
print 'File: "%s"' % file
|
||||
data = open(file,'rb').read()
|
||||
crc = compute_crc(data[:-4])
|
||||
prefix, data = consume('<5sBIB',data,'signature version size targets')
|
||||
print '%(signature)s v%(version)d, image size: %(size)d, targets: %(targets)d' % prefix
|
||||
for t in range(prefix['targets']):
|
||||
tprefix, data = consume('<6sBI255s2I',data,'signature altsetting named name size elements')
|
||||
tprefix['num'] = t
|
||||
if tprefix['named']:
|
||||
tprefix['name'] = cstring(tprefix['name'])
|
||||
else:
|
||||
tprefix['name'] = ''
|
||||
print '%(signature)s %(num)d, alt setting: %(altsetting)s, name: "%(name)s", size: %(size)d, elements: %(elements)d' % tprefix
|
||||
tsize = tprefix['size']
|
||||
target, data = data[:tsize], data[tsize:]
|
||||
for e in range(tprefix['elements']):
|
||||
eprefix, target = consume('<2I',target,'address size')
|
||||
eprefix['num'] = e
|
||||
print ' %(num)d, address: 0x%(address)08x, size: %(size)d' % eprefix
|
||||
esize = eprefix['size']
|
||||
image, target = target[:esize], target[esize:]
|
||||
if dump_images:
|
||||
out = '%s.target%d.image%d.bin' % (file,t,e)
|
||||
open(out,'wb').write(image)
|
||||
print ' DUMPED IMAGE TO "%s"' % out
|
||||
if len(target):
|
||||
print "target %d: PARSE ERROR" % t
|
||||
suffix = named(struct.unpack('<4H3sBI',data[:16]),'device product vendor dfu ufd len crc')
|
||||
print 'usb: %(vendor)04x:%(product)04x, device: 0x%(device)04x, dfu: 0x%(dfu)04x, %(ufd)s, %(len)d, 0x%(crc)08x' % suffix
|
||||
if crc != suffix['crc']:
|
||||
print "CRC ERROR: computed crc32 is 0x%08x" % crc
|
||||
data = data[16:]
|
||||
if data:
|
||||
print "PARSE ERROR"
|
||||
|
||||
def build(file,targets,device=DEFAULT_DEVICE):
|
||||
data = ''
|
||||
for t,target in enumerate(targets):
|
||||
tdata = ''
|
||||
for image in target:
|
||||
tdata += struct.pack('<2I',image['address'],len(image['data']))+image['data']
|
||||
tdata = struct.pack('<6sBI255s2I','Target',0,1,'ST...',len(tdata),len(target)) + tdata
|
||||
data += tdata
|
||||
data = struct.pack('<5sBIB','DfuSe',1,len(data)+11,len(targets)) + data
|
||||
v,d=map(lambda x: int(x,0) & 0xFFFF, device.split(':',1))
|
||||
data += struct.pack('<4H3sB',0,d,v,0x011a,'UFD',16)
|
||||
crc = compute_crc(data)
|
||||
data += struct.pack('<I',crc)
|
||||
open(file,'wb').write(data)
|
||||
|
||||
if __name__=="__main__":
|
||||
usage = """
|
||||
%prog [-d|--dump] infile.dfu
|
||||
%prog {-b|--build} address:file.bin [-b address:file.bin ...] [{-D|--device}=vendor:device] outfile.dfu"""
|
||||
parser = OptionParser(usage=usage)
|
||||
parser.add_option("-b", "--build", action="append", dest="binfiles",
|
||||
help="build a DFU file from given BINFILES", metavar="BINFILES")
|
||||
parser.add_option("-D", "--device", action="store", dest="device",
|
||||
help="build for DEVICE, defaults to %s" % DEFAULT_DEVICE, metavar="DEVICE")
|
||||
parser.add_option("-d", "--dump", action="store_true", dest="dump_images",
|
||||
default=False, help="dump contained images to current directory")
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
if options.binfiles and len(args)==1:
|
||||
target = []
|
||||
for arg in options.binfiles:
|
||||
try:
|
||||
address,binfile = arg.split(':',1)
|
||||
except ValueError:
|
||||
print "Address:file couple '%s' invalid." % arg
|
||||
sys.exit(1)
|
||||
try:
|
||||
address = int(address,0) & 0xFFFFFFFF
|
||||
except ValueError:
|
||||
print "Address %s invalid." % address
|
||||
sys.exit(1)
|
||||
if not os.path.isfile(binfile):
|
||||
print "Unreadable file '%s'." % binfile
|
||||
sys.exit(1)
|
||||
target.append({ 'address': address, 'data': open(binfile,'rb').read() })
|
||||
outfile = args[0]
|
||||
device = DEFAULT_DEVICE
|
||||
if options.device:
|
||||
device=options.device
|
||||
try:
|
||||
v,d=map(lambda x: int(x,0) & 0xFFFF, device.split(':',1))
|
||||
except:
|
||||
print "Invalid device '%s'." % device
|
||||
sys.exit(1)
|
||||
build(outfile,[target],device)
|
||||
elif len(args)==1:
|
||||
infile = args[0]
|
||||
if not os.path.isfile(infile):
|
||||
print "Unreadable file '%s'." % infile
|
||||
sys.exit(1)
|
||||
parse(infile, dump_images=options.dump_images)
|
||||
else:
|
||||
parser.print_help()
|
||||
sys.exit(1)
|
|
@ -0,0 +1,4 @@
|
|||
# Example udev rules (usually placed in /etc/udev/rules.d)
|
||||
# Makes STM32 DfuSe device writeable for the "plugdev" group
|
||||
|
||||
ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="df11", MODE="664", GROUP="plugdev"
|
|
@ -0,0 +1,2 @@
|
|||
man_MANS = dfu-util.1
|
||||
EXTRA_DIST = dfu-util.1 40-dfuse.rules
|
|
@ -0,0 +1,21 @@
|
|||
From 1.0 to 1.1:
|
||||
----------------
|
||||
(Page references in 1.1 spec)
|
||||
|
||||
Page 10: Added protocol column to table 3.2
|
||||
Page 12: Changed value for bInterfaceProtocol from 00h to 01h (table 4.1)
|
||||
Page 13: Added bitWillDetach flag in bmAttributes at bit 3 (table 4.2)
|
||||
Changed bLength from 07h to 09h (table 4.2)
|
||||
Page 14: Added bcdDFUVersion (table 4.2)
|
||||
Changed bDeviceClass value from FEh to 00h (table 4.3)
|
||||
Changed bDevicesubClass value from 01h to 00h (table 4.3)
|
||||
Page 15: Changed bInterfaceProtocol value from 00h to 02h (table 4.4)
|
||||
Page 17: Adjust wording for bitWillDetach addition (5.1)
|
||||
Page 26: Adjust wording for bitWillDetach addition (7)
|
||||
Page 29: Adjust wording for bitWillDetach addition (A.2.1)
|
||||
|
||||
Summary:
|
||||
- Addition of the bitWillDetach flag which allows the device to detach instead
|
||||
of waiting of the host to reset the device.
|
||||
- Version changes for bInterfaceProtocol, bDeviceClass and bDevicesubClass
|
||||
- Addition of bcdDFUVersion
|
|
@ -0,0 +1,248 @@
|
|||
.TH DFU-UTIL 1 "September 23, 2012"
|
||||
.SH NAME
|
||||
dfu-util \- Device firmware update (DFU) USB programmer
|
||||
.SH SYNOPSIS
|
||||
.\" Listing devices
|
||||
.HP
|
||||
.B dfu-util
|
||||
.B \-l
|
||||
.RB [\| \-v \|]
|
||||
.RB [\| \-d
|
||||
.IR vid:pid [\|, vid:pid \|]\|]
|
||||
.RB [\| \-p
|
||||
.IR path \|]
|
||||
.RB [\| \-c
|
||||
.IR configuration \|]
|
||||
.RB [\| \-i
|
||||
.IR interface \|]
|
||||
.RB [\| \-a
|
||||
.IR alt-intf \|]
|
||||
.RB [\| \-S
|
||||
.IR serial [\|, serial \|]\|]
|
||||
.\" Download to or upload from device
|
||||
.HP
|
||||
.B dfu-util
|
||||
.RB [\| \-v \|]
|
||||
.RB [\| \-d
|
||||
.IR vid:pid [\|, vid:pid \|]\|]
|
||||
.RB [\| \-p
|
||||
.IR path \|]
|
||||
.RB [\| \-c
|
||||
.IR configuration \|]
|
||||
.RB [\| \-i
|
||||
.IR interface \|]
|
||||
.RB [\| \-a
|
||||
.IR alt-intf \|]
|
||||
.RB [\| \-S
|
||||
.IR serial [\|, serial \|]\|]
|
||||
.RB [\| \-t
|
||||
.IR size \|]
|
||||
.RB [\| \-Z
|
||||
.IR size \|]
|
||||
.RB [\| \-s
|
||||
.IR address \|]
|
||||
.RB [\| \-R \|]
|
||||
.RB [\| \-D \||\| \-U
|
||||
.IR file \|]
|
||||
.\" --help and --version
|
||||
.HP
|
||||
.B dfu-util
|
||||
.RB [\| \-hV \|]
|
||||
.SH DESCRIPTION
|
||||
.B dfu-util
|
||||
is a program that implements the host (computer) side of the USB DFU
|
||||
(Universal Serial Bus Device Firmware Upgrade) protocol.
|
||||
.sp
|
||||
dfu-util communicates with devices that implement the device side of the
|
||||
USB DFU protocol, and is often used to upgrade the firmware of such
|
||||
devices.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B "\-l, \-\-list"
|
||||
List the currently attached DFU capable USB devices.
|
||||
.TP
|
||||
.BR "\-d, \-\-device" " [\fIRun-Time VENDOR\fP]:[\fIRun-Time PRODUCT\fP][,[\fIDFU Mode VENDOR\fP]:[\fIDFU Mode PRODUCT\fP]]"
|
||||
.RS
|
||||
Specify run-time and/or DFU mode vendor and/or product IDs of the DFU device
|
||||
to work with. \fBVENDOR\fP and \fBPRODUCT\fP are hexadecimal numbers (no prefix
|
||||
needed), "*" (match any), or "-" (match nothing). By default, any DFU capable
|
||||
device in either run-time or DFU mode will be considered.
|
||||
.sp
|
||||
If you only have one standards-compliant DFU device attached to your computer,
|
||||
this parameter is optional. However, as soon as you have multiple DFU devices
|
||||
connected, dfu-util will detect this and abort, asking you to specify which
|
||||
device to use.
|
||||
.sp
|
||||
If only run-time IDs are specified (e.g. "\fB--device 1457:51ab\fP"), then in
|
||||
addition to the specified run-time IDs, any DFU mode devices will also be
|
||||
considered. This is beneficial to allow a DFU capable device to be found
|
||||
again after a switch to DFU mode, since the vendor and/or product ID of a
|
||||
device usually changes in DFU mode.
|
||||
.sp
|
||||
If only DFU mode IDs are specified (e.g. "\fB--device ,951:26\fP"), then all
|
||||
run-time devices will be ignored, making it easy to target a specific device in
|
||||
DFU mode.
|
||||
.sp
|
||||
If both run-time and DFU mode IDs are specified (e.g. "\fB--device
|
||||
1457:51ab,:2bc\fP"), then unspecified DFU mode components will use the run-time
|
||||
value specified.
|
||||
.sp
|
||||
Examples:
|
||||
.TP
|
||||
.B "--device 1457:51ab,951:26"
|
||||
.br
|
||||
Work with a device in run-time mode with
|
||||
vendor ID 0x1457 and product ID 0x51ab, or in DFU mode with vendor ID 0x0951
|
||||
and product ID 0x0026
|
||||
.sp
|
||||
.TP
|
||||
.B "--device 1457:51ab,:2bc"
|
||||
.br
|
||||
Work with a device in run-time mode with vendor ID 0x1457 and product ID
|
||||
0x51ab, or in DFU mode with vendor ID 0x1457 and product ID 0x02bc
|
||||
.sp
|
||||
.TP
|
||||
.B "--device 1457:51ab"
|
||||
.br
|
||||
Work with a device in run-time mode with vendor ID 0x1457 and product ID
|
||||
0x51ab, or in DFU mode with any vendor and product ID
|
||||
.sp
|
||||
.TP
|
||||
.B "--device ,951:26"
|
||||
.br
|
||||
Work with a device in DFU mode with vendor ID 0x0951 and product ID 0x0026
|
||||
.sp
|
||||
.TP
|
||||
.B "--device *,-"
|
||||
.br
|
||||
Work with any device in run-time mode, and ignore any device in DFU mode
|
||||
.sp
|
||||
.TP
|
||||
.B "--device ,"
|
||||
.br
|
||||
Ignore any device in run-time mode, and Work with any device in DFU mode
|
||||
.RE
|
||||
.TP
|
||||
.BR "\-p, \-\-path" " BUS-PORT. ... .PORT"
|
||||
Specify the path to the DFU device.
|
||||
.TP
|
||||
.BR "\-c, \-\-cfg" " CONFIG-NR"
|
||||
Specify the configuration of the DFU device. Note that this is only used for matching, the configuration is not set by dfu-util.
|
||||
.TP
|
||||
.BR "\-i, \-\-intf" " INTF-NR"
|
||||
Specify the DFU interface number.
|
||||
.TP
|
||||
.BR "\-a, \-\-alt" " ALT"
|
||||
Specify the altsetting of the DFU interface by name or by number.
|
||||
.TP
|
||||
.BR "\-S, \-\-serial" " [\fIRun-Time SERIAL\fP][,[\fIDFU Mode SERIAL\fP]]"
|
||||
Specify the run-time and DFU mode serial numbers used to further restrict
|
||||
device matches. If multiple, identical DFU devices are simultaneously
|
||||
connected to a system then vendor and product ID will be insufficient for
|
||||
targeting a single device. In this situation, it may be possible to use this
|
||||
parameter to specify a serial number which also must match.
|
||||
.sp
|
||||
If only a single serial number is specified, then the same serial number is
|
||||
used in both run-time and DFU mode. An empty serial number will match any
|
||||
serial number in the corresponding mode.
|
||||
.TP
|
||||
.B "\-t, \-\-transfer-size" " SIZE"
|
||||
Specify the number of bytes per USB transfer. The optimal value is
|
||||
usually determined automatically so this option is rarely useful. If
|
||||
you need to use this option for a device, please report it as a bug.
|
||||
.TP
|
||||
.B "\-Z, \-\-upload-size" " SIZE"
|
||||
Specify the expected upload size, in bytes.
|
||||
.TP
|
||||
.BR "\-U, \-\-upload" " FILE"
|
||||
Read firmware from device into
|
||||
.BR FILE .
|
||||
.TP
|
||||
.BR "\-D, \-\-download" " FILE"
|
||||
Write firmware from
|
||||
.B FILE
|
||||
into device. When FILE is \-, the firmware is read from stdin.
|
||||
.TP
|
||||
.B "\-R, \-\-reset"
|
||||
Issue USB reset signalling after upload or download has finished.
|
||||
.TP
|
||||
.BR "\-s, \-\-dfuse-address" " address"
|
||||
Specify target address for raw binary download/upload on DfuSe devices. Do
|
||||
.B not
|
||||
use this for downloading DfuSe (.dfu) files. Modifiers can be added
|
||||
to the address, separated by a colon, to perform special DfuSE commands such
|
||||
as "leave" DFU mode, "unprotect" and "mass-erase" flash memory.
|
||||
.TP
|
||||
.B "\-v, \-\-verbose"
|
||||
Print more information about dfu-util's operation. A second
|
||||
.B -v
|
||||
will turn on verbose logging of USB requests. Repeat this option to further
|
||||
increase verbosity.
|
||||
.TP
|
||||
.B "\-h, \-\-help"
|
||||
Show a help text and exit.
|
||||
.TP
|
||||
.B "\-V, \-\-version"
|
||||
Show version information and exit.
|
||||
.SH EXAMPLES
|
||||
.SS Using dfu-util in the OpenMoko project
|
||||
(with the Neo1973 hardware)
|
||||
.PP
|
||||
Flashing the rootfs:
|
||||
.br
|
||||
.B " $ dfu-util -a rootfs -R -D /path/to/openmoko-devel-image.jffs2"
|
||||
.PP
|
||||
Flashing the kernel:
|
||||
.br
|
||||
.B " $ dfu-util -a kernel -R -D /path/to/uImage"
|
||||
.PP
|
||||
Flashing the bootloader:
|
||||
.br
|
||||
.B " $ dfu-util -a u-boot -R -D /path/to/u-boot.bin"
|
||||
.PP
|
||||
Copying a kernel into RAM:
|
||||
.br
|
||||
.B " $ dfu-util -a 0 -R -D /path/to/uImage"
|
||||
.sp
|
||||
Once this has finished, the kernel will be available at the default load
|
||||
address of 0x32000000 in Neo1973 RAM.
|
||||
.B Note:
|
||||
You cannot transfer more than 2MB of data into RAM using this method.
|
||||
.sp
|
||||
.SS Using dfu-util with a DfuSe device
|
||||
.PP
|
||||
Flashing a
|
||||
.B .dfu
|
||||
(special DfuSe format) file to the device:
|
||||
.br
|
||||
.B " $ dfu-util -a 0 -D /path/to/dfuse-image.dfu"
|
||||
.PP
|
||||
Reading out 1 KB of flash starting at address 0x8000000:
|
||||
.br
|
||||
.B " $ dfu-util -a 0 -s 0x08000000:1024 -U newfile.bin"
|
||||
.PP
|
||||
Flashing a binary file to address 0x8004000 of device memory and
|
||||
ask the device to leave DFU mode:
|
||||
.br
|
||||
.B " $ dfu-util -a 0 -s 0x08004000:leave -D /path/to/image.bin"
|
||||
.\" There are no bugs of course
|
||||
.SH BUGS
|
||||
Please report any bugs to the dfu-util mailing list at
|
||||
.BR dfu-util@lists.gnumonks.org .
|
||||
Please use the
|
||||
.IR --verbose " option (repeated as necessary) to provide more"
|
||||
information in your bug report.
|
||||
.SH SEE ALSO
|
||||
The dfu-util home page is
|
||||
.B http://dfu-util.gnumonks.org
|
||||
.SH HISTORY
|
||||
dfu-util was originally written for the OpenMoko project by
|
||||
Weston Schmidt <weston_schmidt@yahoo.com> and
|
||||
Harald Welte <hwelte@hmw-consulting.de>. Over time, nearly complete
|
||||
support of DFU 1.0, DFU 1.1 and DfuSe ("1.1a") has been added.
|
||||
.SH LICENCE
|
||||
.B dfu-util
|
||||
is covered by the GNU General Public License (GPL), version 2 or later.
|
||||
.SH COPYRIGHT
|
||||
This manual page was originally written by Uwe Hermann <uwe@hermann-uwe.de>,
|
||||
and is now part of the dfu-util project.
|
|
@ -0,0 +1,10 @@
|
|||
# (C) Roger Meier <r.meier@siemens.com>
|
||||
# (C) Pascal Schweizer <pascal.schweizer@siemens.com>
|
||||
# msvc folder is GPL-2.0+, LGPL-2.1+, BSD-3-Clause or MIT license(SPDX)
|
||||
|
||||
Building dfu-util native on Windows with Visual Studio
|
||||
|
||||
3rd party dependencies:
|
||||
- libusbx ( git clone https://github.com/libusbx/libusbx.git )
|
||||
- getopt (part of libusbx: libusbx/examples/getopt)
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{8F7600A2-3B37-4956-B39B-A1D43EF29EDA}</ProjectGuid>
|
||||
<RootNamespace>dfusuffix</RootNamespace>
|
||||
<ProjectName>dfu-suffix</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<IncludePath>$(SolutionDir)..\..\libusbx\examples\getopt;$(SolutionDir)..\..\libusbx\libusb;$(IncludePath)</IncludePath>
|
||||
<OutDir>$(SolutionDir)..\$(Platform)\$(ProjectName)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)..\$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
|
||||
<LibraryPath>$(SolutionDir)..\$(Platform)\$(ProjectName)\$(Configuration)\dll;$(LibraryPath)</LibraryPath>
|
||||
<ReferencePath>$(VCInstallDir)atlmfc\lib;$(VCInstallDir)lib</ReferencePath>
|
||||
<ExecutablePath>$(ExecutablePath)</ExecutablePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ExecutablePath>$(ExecutablePath)</ExecutablePath>
|
||||
<IncludePath>$(SolutionDir)..\..\libusbx\examples\getopt;$(SolutionDir)..\..\libusbx\libusb;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(SolutionDir)..\$(Platform)\$(ProjectName)\$(Configuration)\dll;$(LibraryPath)</LibraryPath>
|
||||
<OutDir>$(SolutionDir)..\$(Platform)\$(ProjectName)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)..\$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>HAVE_WINDOWS_H;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>HAVE_WINDOWS_H;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\src\dfu_file.c" />
|
||||
<ClCompile Include="..\src\suffix.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\src\dfu_file.h" />
|
||||
<ClInclude Include="..\src\portable.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\libusbx\msvc\getopt_2010.vcxproj">
|
||||
<Project>{a2169bc8-cf99-40bf-83f3-b0e38f7067bd}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\libusbx\msvc\libusb_static_2010.vcxproj">
|
||||
<Project>{349ee8f9-7d25-4909-aaf5-ff3fade72187}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -0,0 +1,54 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# Visual Studio 2010
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dfu-util", "dfu-util_2010.vcxproj", "{0E071A60-7EF2-4427-BAA8-9143CACB5BCB}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{C4F8746D-B27E-4806-95E5-2052174E923B}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dfu-suffix", "dfu-suffix_2010.vcxproj", "{8F7600A2-3B37-4956-B39B-A1D43EF29EDA}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "getopt_2010", "..\..\libusbx\msvc\getopt_2010.vcxproj", "{AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libusb-1.0 (static)", "..\..\libusbx\msvc\libusb_static_2010.vcxproj", "{349EE8F9-7D25-4909-AAF5-FF3FADE72187}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Debug|x64 = Debug|x64
|
||||
Release|Win32 = Release|Win32
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{0E071A60-7EF2-4427-BAA8-9143CACB5BCB}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{0E071A60-7EF2-4427-BAA8-9143CACB5BCB}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{0E071A60-7EF2-4427-BAA8-9143CACB5BCB}.Debug|x64.ActiveCfg = Debug|Win32
|
||||
{0E071A60-7EF2-4427-BAA8-9143CACB5BCB}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{0E071A60-7EF2-4427-BAA8-9143CACB5BCB}.Release|Win32.Build.0 = Release|Win32
|
||||
{0E071A60-7EF2-4427-BAA8-9143CACB5BCB}.Release|x64.ActiveCfg = Release|Win32
|
||||
{8F7600A2-3B37-4956-B39B-A1D43EF29EDA}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{8F7600A2-3B37-4956-B39B-A1D43EF29EDA}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{8F7600A2-3B37-4956-B39B-A1D43EF29EDA}.Debug|x64.ActiveCfg = Debug|Win32
|
||||
{8F7600A2-3B37-4956-B39B-A1D43EF29EDA}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{8F7600A2-3B37-4956-B39B-A1D43EF29EDA}.Release|Win32.Build.0 = Release|Win32
|
||||
{8F7600A2-3B37-4956-B39B-A1D43EF29EDA}.Release|x64.ActiveCfg = Release|Win32
|
||||
{AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}.Debug|x64.Build.0 = Debug|x64
|
||||
{AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}.Release|Win32.Build.0 = Release|Win32
|
||||
{AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}.Release|x64.ActiveCfg = Release|x64
|
||||
{AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}.Release|x64.Build.0 = Release|x64
|
||||
{349EE8F9-7D25-4909-AAF5-FF3FADE72187}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{349EE8F9-7D25-4909-AAF5-FF3FADE72187}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{349EE8F9-7D25-4909-AAF5-FF3FADE72187}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{349EE8F9-7D25-4909-AAF5-FF3FADE72187}.Debug|x64.Build.0 = Debug|x64
|
||||
{349EE8F9-7D25-4909-AAF5-FF3FADE72187}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{349EE8F9-7D25-4909-AAF5-FF3FADE72187}.Release|Win32.Build.0 = Release|Win32
|
||||
{349EE8F9-7D25-4909-AAF5-FF3FADE72187}.Release|x64.ActiveCfg = Release|x64
|
||||
{349EE8F9-7D25-4909-AAF5-FF3FADE72187}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -0,0 +1,120 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{0E071A60-7EF2-4427-BAA8-9143CACB5BCB}</ProjectGuid>
|
||||
<RootNamespace>dfuutil</RootNamespace>
|
||||
<ProjectName>dfu-util</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<IncludePath>$(SolutionDir)..\..\libusbx\examples\getopt;$(SolutionDir)..\..\libusbx\libusb;$(IncludePath)</IncludePath>
|
||||
<OutDir>$(SolutionDir)..\$(Platform)\$(ProjectName)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)..\$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
|
||||
<LibraryPath>$(SolutionDir)..\$(Platform)\getopt\$(Configuration);$(LibraryPath)</LibraryPath>
|
||||
<ReferencePath>$(VCInstallDir)atlmfc\lib;$(VCInstallDir)lib</ReferencePath>
|
||||
<ExecutablePath>$(ExecutablePath)</ExecutablePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ExecutablePath>$(ExecutablePath)</ExecutablePath>
|
||||
<IncludePath>$(SolutionDir)..\..\libusbx\examples\getopt;$(SolutionDir)..\..\libusbx\libusb;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(SolutionDir)..\$(Platform)\getopt\$(Configuration);$(LibraryPath)</LibraryPath>
|
||||
<OutDir>$(SolutionDir)..\$(Platform)\$(ProjectName)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)..\$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>HAVE_WINDOWS_H;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>
|
||||
</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>HAVE_WINDOWS_H;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>copy $(SolutionDir)..\$(Platform)\$(Configuration)\dll\libusb-1.0.dll $(SolutionDir)..\$(Platform)\$(ProjectName)\$(Configuration)\</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\src\dfu.c" />
|
||||
<ClCompile Include="..\src\dfuse.c" />
|
||||
<ClCompile Include="..\src\dfuse_mem.c" />
|
||||
<ClCompile Include="..\src\dfu_file.c" />
|
||||
<ClCompile Include="..\src\dfu_load.c" />
|
||||
<ClCompile Include="..\src\dfu_util.c" />
|
||||
<ClCompile Include="..\src\main.c" />
|
||||
<ClCompile Include="..\src\quirks.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\src\dfu.h" />
|
||||
<ClInclude Include="..\src\dfuse.h" />
|
||||
<ClInclude Include="..\src\dfuse_mem.h" />
|
||||
<ClInclude Include="..\src\dfu_file.h" />
|
||||
<ClInclude Include="..\src\dfu_load.h" />
|
||||
<ClInclude Include="..\src\dfu_util.h" />
|
||||
<ClInclude Include="..\src\portable.h" />
|
||||
<ClInclude Include="..\src\quirks.h" />
|
||||
<ClInclude Include="..\src\usb_dfu.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\libusbx\msvc\getopt_2010.vcxproj">
|
||||
<Project>{a2169bc8-cf99-40bf-83f3-b0e38f7067bd}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\libusbx\msvc\libusb_static_2010.vcxproj">
|
||||
<Project>{349ee8f9-7d25-4909-aaf5-ff3fade72187}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -0,0 +1,28 @@
|
|||
AM_CFLAGS = -Wall -Wextra
|
||||
|
||||
bin_PROGRAMS = dfu-util dfu-suffix dfu-prefix
|
||||
dfu_util_SOURCES = main.c \
|
||||
portable.h \
|
||||
dfu_load.c \
|
||||
dfu_load.h \
|
||||
dfu_util.c \
|
||||
dfu_util.h \
|
||||
dfuse.c \
|
||||
dfuse.h \
|
||||
dfuse_mem.c \
|
||||
dfuse_mem.h \
|
||||
dfu.c \
|
||||
dfu.h \
|
||||
usb_dfu.h \
|
||||
dfu_file.c \
|
||||
dfu_file.h \
|
||||
quirks.c \
|
||||
quirks.h
|
||||
|
||||
dfu_suffix_SOURCES = suffix.c \
|
||||
dfu_file.h \
|
||||
dfu_file.c
|
||||
|
||||
dfu_prefix_SOURCES = prefix.c \
|
||||
dfu_file.h \
|
||||
dfu_file.c
|
|
@ -0,0 +1,357 @@
|
|||
/*
|
||||
* Low-level DFU communication routines, originally taken from
|
||||
* $Id: dfu.c,v 1.3 2006/06/20 06:28:04 schmidtw Exp $
|
||||
* (part of dfu-programmer).
|
||||
*
|
||||
* Copyright 2005-2006 Weston Schmidt <weston_schmidt@alumni.purdue.edu>
|
||||
* Copyright 2011-2014 Tormod Volden <debian.tormod@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <libusb.h>
|
||||
|
||||
#include "portable.h"
|
||||
#include "dfu.h"
|
||||
#include "quirks.h"
|
||||
|
||||
static int dfu_timeout = 5000; /* 5 seconds - default */
|
||||
|
||||
/*
|
||||
* DFU_DETACH Request (DFU Spec 1.0, Section 5.1)
|
||||
*
|
||||
* device - the usb_dev_handle to communicate with
|
||||
* interface - the interface to communicate with
|
||||
* timeout - the timeout in ms the USB device should wait for a pending
|
||||
* USB reset before giving up and terminating the operation
|
||||
*
|
||||
* returns 0 or < 0 on error
|
||||
*/
|
||||
int dfu_detach( libusb_device_handle *device,
|
||||
const unsigned short interface,
|
||||
const unsigned short timeout )
|
||||
{
|
||||
return libusb_control_transfer( device,
|
||||
/* bmRequestType */ LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE,
|
||||
/* bRequest */ DFU_DETACH,
|
||||
/* wValue */ timeout,
|
||||
/* wIndex */ interface,
|
||||
/* Data */ NULL,
|
||||
/* wLength */ 0,
|
||||
dfu_timeout );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* DFU_DNLOAD Request (DFU Spec 1.0, Section 6.1.1)
|
||||
*
|
||||
* device - the usb_dev_handle to communicate with
|
||||
* interface - the interface to communicate with
|
||||
* length - the total number of bytes to transfer to the USB
|
||||
* device - must be less than wTransferSize
|
||||
* data - the data to transfer
|
||||
*
|
||||
* returns the number of bytes written or < 0 on error
|
||||
*/
|
||||
int dfu_download( libusb_device_handle *device,
|
||||
const unsigned short interface,
|
||||
const unsigned short length,
|
||||
const unsigned short transaction,
|
||||
unsigned char* data )
|
||||
{
|
||||
int status;
|
||||
|
||||
status = libusb_control_transfer( device,
|
||||
/* bmRequestType */ LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE,
|
||||
/* bRequest */ DFU_DNLOAD,
|
||||
/* wValue */ transaction,
|
||||
/* wIndex */ interface,
|
||||
/* Data */ data,
|
||||
/* wLength */ length,
|
||||
dfu_timeout );
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* DFU_UPLOAD Request (DFU Spec 1.0, Section 6.2)
|
||||
*
|
||||
* device - the usb_dev_handle to communicate with
|
||||
* interface - the interface to communicate with
|
||||
* length - the maximum number of bytes to receive from the USB
|
||||
* device - must be less than wTransferSize
|
||||
* data - the buffer to put the received data in
|
||||
*
|
||||
* returns the number of bytes received or < 0 on error
|
||||
*/
|
||||
int dfu_upload( libusb_device_handle *device,
|
||||
const unsigned short interface,
|
||||
const unsigned short length,
|
||||
const unsigned short transaction,
|
||||
unsigned char* data )
|
||||
{
|
||||
int status;
|
||||
|
||||
status = libusb_control_transfer( device,
|
||||
/* bmRequestType */ LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE,
|
||||
/* bRequest */ DFU_UPLOAD,
|
||||
/* wValue */ transaction,
|
||||
/* wIndex */ interface,
|
||||
/* Data */ data,
|
||||
/* wLength */ length,
|
||||
dfu_timeout );
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* DFU_GETSTATUS Request (DFU Spec 1.0, Section 6.1.2)
|
||||
*
|
||||
* device - the usb_dev_handle to communicate with
|
||||
* interface - the interface to communicate with
|
||||
* status - the data structure to be populated with the results
|
||||
*
|
||||
* return the number of bytes read in or < 0 on an error
|
||||
*/
|
||||
int dfu_get_status( struct dfu_if *dif, struct dfu_status *status )
|
||||
{
|
||||
unsigned char buffer[6];
|
||||
int result;
|
||||
|
||||
/* Initialize the status data structure */
|
||||
status->bStatus = DFU_STATUS_ERROR_UNKNOWN;
|
||||
status->bwPollTimeout = 0;
|
||||
status->bState = STATE_DFU_ERROR;
|
||||
status->iString = 0;
|
||||
|
||||
result = libusb_control_transfer( dif->dev_handle,
|
||||
/* bmRequestType */ LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE,
|
||||
/* bRequest */ DFU_GETSTATUS,
|
||||
/* wValue */ 0,
|
||||
/* wIndex */ dif->interface,
|
||||
/* Data */ buffer,
|
||||
/* wLength */ 6,
|
||||
dfu_timeout );
|
||||
|
||||
if( 6 == result ) {
|
||||
status->bStatus = buffer[0];
|
||||
if (dif->quirks & QUIRK_POLLTIMEOUT)
|
||||
status->bwPollTimeout = DEFAULT_POLLTIMEOUT;
|
||||
else
|
||||
status->bwPollTimeout = ((0xff & buffer[3]) << 16) |
|
||||
((0xff & buffer[2]) << 8) |
|
||||
(0xff & buffer[1]);
|
||||
status->bState = buffer[4];
|
||||
status->iString = buffer[5];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* DFU_CLRSTATUS Request (DFU Spec 1.0, Section 6.1.3)
|
||||
*
|
||||
* device - the usb_dev_handle to communicate with
|
||||
* interface - the interface to communicate with
|
||||
*
|
||||
* return 0 or < 0 on an error
|
||||
*/
|
||||
int dfu_clear_status( libusb_device_handle *device,
|
||||
const unsigned short interface )
|
||||
{
|
||||
return libusb_control_transfer( device,
|
||||
/* bmRequestType */ LIBUSB_ENDPOINT_OUT| LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE,
|
||||
/* bRequest */ DFU_CLRSTATUS,
|
||||
/* wValue */ 0,
|
||||
/* wIndex */ interface,
|
||||
/* Data */ NULL,
|
||||
/* wLength */ 0,
|
||||
dfu_timeout );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* DFU_GETSTATE Request (DFU Spec 1.0, Section 6.1.5)
|
||||
*
|
||||
* device - the usb_dev_handle to communicate with
|
||||
* interface - the interface to communicate with
|
||||
* length - the maximum number of bytes to receive from the USB
|
||||
* device - must be less than wTransferSize
|
||||
* data - the buffer to put the received data in
|
||||
*
|
||||
* returns the state or < 0 on error
|
||||
*/
|
||||
int dfu_get_state( libusb_device_handle *device,
|
||||
const unsigned short interface )
|
||||
{
|
||||
int result;
|
||||
unsigned char buffer[1];
|
||||
|
||||
result = libusb_control_transfer( device,
|
||||
/* bmRequestType */ LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE,
|
||||
/* bRequest */ DFU_GETSTATE,
|
||||
/* wValue */ 0,
|
||||
/* wIndex */ interface,
|
||||
/* Data */ buffer,
|
||||
/* wLength */ 1,
|
||||
dfu_timeout );
|
||||
|
||||
/* Return the error if there is one. */
|
||||
if (result < 1)
|
||||
return -1;
|
||||
|
||||
/* Return the state. */
|
||||
return buffer[0];
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* DFU_ABORT Request (DFU Spec 1.0, Section 6.1.4)
|
||||
*
|
||||
* device - the usb_dev_handle to communicate with
|
||||
* interface - the interface to communicate with
|
||||
*
|
||||
* returns 0 or < 0 on an error
|
||||
*/
|
||||
int dfu_abort( libusb_device_handle *device,
|
||||
const unsigned short interface )
|
||||
{
|
||||
return libusb_control_transfer( device,
|
||||
/* bmRequestType */ LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE,
|
||||
/* bRequest */ DFU_ABORT,
|
||||
/* wValue */ 0,
|
||||
/* wIndex */ interface,
|
||||
/* Data */ NULL,
|
||||
/* wLength */ 0,
|
||||
dfu_timeout );
|
||||
}
|
||||
|
||||
|
||||
const char* dfu_state_to_string( int state )
|
||||
{
|
||||
const char *message;
|
||||
|
||||
switch (state) {
|
||||
case STATE_APP_IDLE:
|
||||
message = "appIDLE";
|
||||
break;
|
||||
case STATE_APP_DETACH:
|
||||
message = "appDETACH";
|
||||
break;
|
||||
case STATE_DFU_IDLE:
|
||||
message = "dfuIDLE";
|
||||
break;
|
||||
case STATE_DFU_DOWNLOAD_SYNC:
|
||||
message = "dfuDNLOAD-SYNC";
|
||||
break;
|
||||
case STATE_DFU_DOWNLOAD_BUSY:
|
||||
message = "dfuDNBUSY";
|
||||
break;
|
||||
case STATE_DFU_DOWNLOAD_IDLE:
|
||||
message = "dfuDNLOAD-IDLE";
|
||||
break;
|
||||
case STATE_DFU_MANIFEST_SYNC:
|
||||
message = "dfuMANIFEST-SYNC";
|
||||
break;
|
||||
case STATE_DFU_MANIFEST:
|
||||
message = "dfuMANIFEST";
|
||||
break;
|
||||
case STATE_DFU_MANIFEST_WAIT_RESET:
|
||||
message = "dfuMANIFEST-WAIT-RESET";
|
||||
break;
|
||||
case STATE_DFU_UPLOAD_IDLE:
|
||||
message = "dfuUPLOAD-IDLE";
|
||||
break;
|
||||
case STATE_DFU_ERROR:
|
||||
message = "dfuERROR";
|
||||
break;
|
||||
default:
|
||||
message = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
/* Chapter 6.1.2 */
|
||||
static const char *dfu_status_names[] = {
|
||||
/* DFU_STATUS_OK */
|
||||
"No error condition is present",
|
||||
/* DFU_STATUS_errTARGET */
|
||||
"File is not targeted for use by this device",
|
||||
/* DFU_STATUS_errFILE */
|
||||
"File is for this device but fails some vendor-specific test",
|
||||
/* DFU_STATUS_errWRITE */
|
||||
"Device is unable to write memory",
|
||||
/* DFU_STATUS_errERASE */
|
||||
"Memory erase function failed",
|
||||
/* DFU_STATUS_errCHECK_ERASED */
|
||||
"Memory erase check failed",
|
||||
/* DFU_STATUS_errPROG */
|
||||
"Program memory function failed",
|
||||
/* DFU_STATUS_errVERIFY */
|
||||
"Programmed memory failed verification",
|
||||
/* DFU_STATUS_errADDRESS */
|
||||
"Cannot program memory due to received address that is out of range",
|
||||
/* DFU_STATUS_errNOTDONE */
|
||||
"Received DFU_DNLOAD with wLength = 0, but device does not think that it has all data yet",
|
||||
/* DFU_STATUS_errFIRMWARE */
|
||||
"Device's firmware is corrupt. It cannot return to run-time (non-DFU) operations",
|
||||
/* DFU_STATUS_errVENDOR */
|
||||
"iString indicates a vendor specific error",
|
||||
/* DFU_STATUS_errUSBR */
|
||||
"Device detected unexpected USB reset signalling",
|
||||
/* DFU_STATUS_errPOR */
|
||||
"Device detected unexpected power on reset",
|
||||
/* DFU_STATUS_errUNKNOWN */
|
||||
"Something went wrong, but the device does not know what it was",
|
||||
/* DFU_STATUS_errSTALLEDPKT */
|
||||
"Device stalled an unexpected request"
|
||||
};
|
||||
|
||||
|
||||
const char *dfu_status_to_string(int status)
|
||||
{
|
||||
if (status > DFU_STATUS_errSTALLEDPKT)
|
||||
return "INVALID";
|
||||
return dfu_status_names[status];
|
||||
}
|
||||
|
||||
int dfu_abort_to_idle(struct dfu_if *dif)
|
||||
{
|
||||
int ret;
|
||||
struct dfu_status dst;
|
||||
|
||||
ret = dfu_abort(dif->dev_handle, dif->interface);
|
||||
if (ret < 0) {
|
||||
errx(EX_IOERR, "Error sending dfu abort request");
|
||||
exit(1);
|
||||
}
|
||||
ret = dfu_get_status(dif, &dst);
|
||||
if (ret < 0) {
|
||||
errx(EX_IOERR, "Error during abort get_status");
|
||||
exit(1);
|
||||
}
|
||||
if (dst.bState != DFU_STATE_dfuIDLE) {
|
||||
errx(EX_IOERR, "Failed to enter idle state on abort");
|
||||
exit(1);
|
||||
}
|
||||
milli_sleep(dst.bwPollTimeout);
|
||||
return ret;
|
||||
}
|
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
* dfu-programmer
|
||||
*
|
||||
* $Id: dfu.h,v 1.2 2005/09/25 01:27:42 schmidtw Exp $
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef DFU_H
|
||||
#define DFU_H
|
||||
|
||||
#include <libusb.h>
|
||||
#include "usb_dfu.h"
|
||||
|
||||
/* DFU states */
|
||||
#define STATE_APP_IDLE 0x00
|
||||
#define STATE_APP_DETACH 0x01
|
||||
#define STATE_DFU_IDLE 0x02
|
||||
#define STATE_DFU_DOWNLOAD_SYNC 0x03
|
||||
#define STATE_DFU_DOWNLOAD_BUSY 0x04
|
||||
#define STATE_DFU_DOWNLOAD_IDLE 0x05
|
||||
#define STATE_DFU_MANIFEST_SYNC 0x06
|
||||
#define STATE_DFU_MANIFEST 0x07
|
||||
#define STATE_DFU_MANIFEST_WAIT_RESET 0x08
|
||||
#define STATE_DFU_UPLOAD_IDLE 0x09
|
||||
#define STATE_DFU_ERROR 0x0a
|
||||
|
||||
|
||||
/* DFU status */
|
||||
#define DFU_STATUS_OK 0x00
|
||||
#define DFU_STATUS_ERROR_TARGET 0x01
|
||||
#define DFU_STATUS_ERROR_FILE 0x02
|
||||
#define DFU_STATUS_ERROR_WRITE 0x03
|
||||
#define DFU_STATUS_ERROR_ERASE 0x04
|
||||
#define DFU_STATUS_ERROR_CHECK_ERASED 0x05
|
||||
#define DFU_STATUS_ERROR_PROG 0x06
|
||||
#define DFU_STATUS_ERROR_VERIFY 0x07
|
||||
#define DFU_STATUS_ERROR_ADDRESS 0x08
|
||||
#define DFU_STATUS_ERROR_NOTDONE 0x09
|
||||
#define DFU_STATUS_ERROR_FIRMWARE 0x0a
|
||||
#define DFU_STATUS_ERROR_VENDOR 0x0b
|
||||
#define DFU_STATUS_ERROR_USBR 0x0c
|
||||
#define DFU_STATUS_ERROR_POR 0x0d
|
||||
#define DFU_STATUS_ERROR_UNKNOWN 0x0e
|
||||
#define DFU_STATUS_ERROR_STALLEDPKT 0x0f
|
||||
|
||||
/* DFU commands */
|
||||
#define DFU_DETACH 0
|
||||
#define DFU_DNLOAD 1
|
||||
#define DFU_UPLOAD 2
|
||||
#define DFU_GETSTATUS 3
|
||||
#define DFU_CLRSTATUS 4
|
||||
#define DFU_GETSTATE 5
|
||||
#define DFU_ABORT 6
|
||||
|
||||
/* DFU interface */
|
||||
#define DFU_IFF_DFU 0x0001 /* DFU Mode, (not Runtime) */
|
||||
|
||||
/* This is based off of DFU_GETSTATUS
|
||||
*
|
||||
* 1 unsigned byte bStatus
|
||||
* 3 unsigned byte bwPollTimeout
|
||||
* 1 unsigned byte bState
|
||||
* 1 unsigned byte iString
|
||||
*/
|
||||
|
||||
struct dfu_status {
|
||||
unsigned char bStatus;
|
||||
unsigned int bwPollTimeout;
|
||||
unsigned char bState;
|
||||
unsigned char iString;
|
||||
};
|
||||
|
||||
struct dfu_if {
|
||||
struct usb_dfu_func_descriptor func_dfu;
|
||||
uint16_t quirks;
|
||||
uint16_t busnum;
|
||||
uint16_t devnum;
|
||||
uint16_t vendor;
|
||||
uint16_t product;
|
||||
uint16_t bcdDevice;
|
||||
uint8_t configuration;
|
||||
uint8_t interface;
|
||||
uint8_t altsetting;
|
||||
uint8_t flags;
|
||||
uint8_t bMaxPacketSize0;
|
||||
char *alt_name;
|
||||
char *serial_name;
|
||||
libusb_device *dev;
|
||||
libusb_device_handle *dev_handle;
|
||||
struct dfu_if *next;
|
||||
};
|
||||
|
||||
int dfu_detach( libusb_device_handle *device,
|
||||
const unsigned short interface,
|
||||
const unsigned short timeout );
|
||||
int dfu_download( libusb_device_handle *device,
|
||||
const unsigned short interface,
|
||||
const unsigned short length,
|
||||
const unsigned short transaction,
|
||||
unsigned char* data );
|
||||
int dfu_upload( libusb_device_handle *device,
|
||||
const unsigned short interface,
|
||||
const unsigned short length,
|
||||
const unsigned short transaction,
|
||||
unsigned char* data );
|
||||
int dfu_get_status( struct dfu_if *dif,
|
||||
struct dfu_status *status );
|
||||
int dfu_clear_status( libusb_device_handle *device,
|
||||
const unsigned short interface );
|
||||
int dfu_get_state( libusb_device_handle *device,
|
||||
const unsigned short interface );
|
||||
int dfu_abort( libusb_device_handle *device,
|
||||
const unsigned short interface );
|
||||
int dfu_abort_to_idle( struct dfu_if *dif);
|
||||
|
||||
const char *dfu_state_to_string( int state );
|
||||
|
||||
const char *dfu_status_to_string( int status );
|
||||
|
||||
#endif /* DFU_H */
|
|
@ -0,0 +1,444 @@
|
|||
/*
|
||||
* Load or store DFU files including suffix and prefix
|
||||
*
|
||||
* Copyright 2014 Tormod Volden <debian.tormod@gmail.com>
|
||||
* Copyright 2012 Stefan Schmidt <stefan@datenfreihafen.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "portable.h"
|
||||
#include "dfu_file.h"
|
||||
|
||||
#define DFU_SUFFIX_LENGTH 16
|
||||
#define LMDFU_PREFIX_LENGTH 8
|
||||
#define LPCDFU_PREFIX_LENGTH 16
|
||||
#define PROGRESS_BAR_WIDTH 25
|
||||
#define STDIN_CHUNK_SIZE 65536
|
||||
|
||||
static const unsigned long crc32_table[] = {
|
||||
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
|
||||
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
|
||||
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
|
||||
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
|
||||
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
|
||||
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
|
||||
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
|
||||
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
|
||||
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
|
||||
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
|
||||
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
|
||||
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
|
||||
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
|
||||
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
|
||||
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
|
||||
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
|
||||
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
|
||||
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
|
||||
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
|
||||
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
|
||||
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
|
||||
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
|
||||
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
|
||||
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
|
||||
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
|
||||
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
|
||||
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
|
||||
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
|
||||
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
|
||||
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
|
||||
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
|
||||
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
|
||||
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
|
||||
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
|
||||
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
|
||||
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
|
||||
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
|
||||
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
|
||||
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
|
||||
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
|
||||
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
|
||||
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
|
||||
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d};
|
||||
|
||||
static uint32_t crc32_byte(uint32_t accum, uint8_t delta)
|
||||
{
|
||||
return crc32_table[(accum ^ delta) & 0xff] ^ (accum >> 8);
|
||||
}
|
||||
|
||||
static int probe_prefix(struct dfu_file *file)
|
||||
{
|
||||
uint8_t *prefix = file->firmware;
|
||||
|
||||
if (file->size.total < LMDFU_PREFIX_LENGTH)
|
||||
return 1;
|
||||
if ((prefix[0] == 0x01) && (prefix[1] == 0x00)) {
|
||||
file->prefix_type = LMDFU_PREFIX;
|
||||
file->size.prefix = LMDFU_PREFIX_LENGTH;
|
||||
file->lmdfu_address = 1024 * ((prefix[3] << 8) | prefix[2]);
|
||||
}
|
||||
else if (((prefix[0] & 0x3f) == 0x1a) && ((prefix[1] & 0x3f)== 0x3f)) {
|
||||
file->prefix_type = LPCDFU_UNENCRYPTED_PREFIX;
|
||||
file->size.prefix = LPCDFU_PREFIX_LENGTH;
|
||||
}
|
||||
|
||||
if (file->size.prefix + file->size.suffix > file->size.total)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void dfu_progress_bar(const char *desc, unsigned long long curr,
|
||||
unsigned long long max)
|
||||
{
|
||||
static char buf[PROGRESS_BAR_WIDTH + 1];
|
||||
static unsigned long long last_progress = -1;
|
||||
static time_t last_time;
|
||||
time_t curr_time = time(NULL);
|
||||
unsigned long long progress;
|
||||
unsigned long long x;
|
||||
|
||||
/* check for not known maximum */
|
||||
if (max < curr)
|
||||
max = curr + 1;
|
||||
/* make none out of none give zero */
|
||||
if (max == 0 && curr == 0)
|
||||
max = 1;
|
||||
|
||||
/* compute completion */
|
||||
progress = (PROGRESS_BAR_WIDTH * curr) / max;
|
||||
if (progress > PROGRESS_BAR_WIDTH)
|
||||
progress = PROGRESS_BAR_WIDTH;
|
||||
if (progress == last_progress &&
|
||||
curr_time == last_time)
|
||||
return;
|
||||
last_progress = progress;
|
||||
last_time = curr_time;
|
||||
|
||||
for (x = 0; x != PROGRESS_BAR_WIDTH; x++) {
|
||||
if (x < progress)
|
||||
buf[x] = '=';
|
||||
else
|
||||
buf[x] = ' ';
|
||||
}
|
||||
buf[x] = 0;
|
||||
|
||||
printf("\r%s\t[%s] %3lld%% %12lld bytes", desc, buf,
|
||||
(100ULL * curr) / max, curr);
|
||||
|
||||
if (progress == PROGRESS_BAR_WIDTH)
|
||||
printf("\n%s done.\n", desc);
|
||||
}
|
||||
|
||||
void *dfu_malloc(size_t size)
|
||||
{
|
||||
void *ptr = malloc(size);
|
||||
if (ptr == NULL)
|
||||
errx(EX_SOFTWARE, "Cannot allocate memory of size %d bytes", (int)size);
|
||||
return (ptr);
|
||||
}
|
||||
|
||||
uint32_t dfu_file_write_crc(int f, uint32_t crc, const void *buf, int size)
|
||||
{
|
||||
int x;
|
||||
|
||||
/* compute CRC */
|
||||
for (x = 0; x != size; x++)
|
||||
crc = crc32_byte(crc, ((uint8_t *)buf)[x]);
|
||||
|
||||
/* write data */
|
||||
if (write(f, buf, size) != size)
|
||||
err(EX_IOERR, "Could not write %d bytes to file %d", size, f);
|
||||
|
||||
return (crc);
|
||||
}
|
||||
|
||||
void dfu_load_file(struct dfu_file *file, enum suffix_req check_suffix, enum prefix_req check_prefix)
|
||||
{
|
||||
off_t offset;
|
||||
int f;
|
||||
int i;
|
||||
int res;
|
||||
|
||||
file->size.prefix = 0;
|
||||
file->size.suffix = 0;
|
||||
|
||||
/* default values, if no valid suffix is found */
|
||||
file->bcdDFU = 0;
|
||||
file->idVendor = 0xffff; /* wildcard value */
|
||||
file->idProduct = 0xffff; /* wildcard value */
|
||||
file->bcdDevice = 0xffff; /* wildcard value */
|
||||
|
||||
/* default values, if no valid prefix is found */
|
||||
file->lmdfu_address = 0;
|
||||
|
||||
free(file->firmware);
|
||||
|
||||
if (!strcmp(file->name, "-")) {
|
||||
int read_bytes;
|
||||
|
||||
#ifdef WIN32
|
||||
_setmode( _fileno( stdin ), _O_BINARY );
|
||||
#endif
|
||||
file->firmware = (uint8_t*) dfu_malloc(STDIN_CHUNK_SIZE);
|
||||
read_bytes = fread(file->firmware, 1, STDIN_CHUNK_SIZE, stdin);
|
||||
file->size.total = read_bytes;
|
||||
while (read_bytes == STDIN_CHUNK_SIZE) {
|
||||
file->firmware = (uint8_t*) realloc(file->firmware, file->size.total + STDIN_CHUNK_SIZE);
|
||||
if (!file->firmware)
|
||||
err(EX_IOERR, "Could not allocate firmware buffer");
|
||||
read_bytes = fread(file->firmware + file->size.total, 1, STDIN_CHUNK_SIZE, stdin);
|
||||
file->size.total += read_bytes;
|
||||
}
|
||||
if (verbose)
|
||||
printf("Read %i bytes from stdin\n", file->size.total);
|
||||
/* Never require suffix when reading from stdin */
|
||||
check_suffix = MAYBE_SUFFIX;
|
||||
} else {
|
||||
f = open(file->name, O_RDONLY | O_BINARY);
|
||||
if (f < 0)
|
||||
err(EX_IOERR, "Could not open file %s for reading", file->name);
|
||||
|
||||
offset = lseek(f, 0, SEEK_END);
|
||||
|
||||
if ((int)offset < 0 || (int)offset != offset)
|
||||
err(EX_IOERR, "File size is too big");
|
||||
|
||||
if (lseek(f, 0, SEEK_SET) != 0)
|
||||
err(EX_IOERR, "Could not seek to beginning");
|
||||
|
||||
file->size.total = offset;
|
||||
file->firmware = dfu_malloc(file->size.total);
|
||||
|
||||
if (read(f, file->firmware, file->size.total) != file->size.total) {
|
||||
err(EX_IOERR, "Could not read %d bytes from %s",
|
||||
file->size.total, file->name);
|
||||
}
|
||||
close(f);
|
||||
}
|
||||
|
||||
/* Check for possible DFU file suffix by trying to parse one */
|
||||
{
|
||||
uint32_t crc = 0xffffffff;
|
||||
const uint8_t *dfusuffix;
|
||||
int missing_suffix = 0;
|
||||
const char *reason;
|
||||
|
||||
if (file->size.total < DFU_SUFFIX_LENGTH) {
|
||||
reason = "File too short for DFU suffix";
|
||||
missing_suffix = 1;
|
||||
goto checked;
|
||||
}
|
||||
|
||||
dfusuffix = file->firmware + file->size.total -
|
||||
DFU_SUFFIX_LENGTH;
|
||||
|
||||
for (i = 0; i < file->size.total - 4; i++)
|
||||
crc = crc32_byte(crc, file->firmware[i]);
|
||||
|
||||
if (dfusuffix[10] != 'D' ||
|
||||
dfusuffix[9] != 'F' ||
|
||||
dfusuffix[8] != 'U') {
|
||||
reason = "Invalid DFU suffix signature";
|
||||
missing_suffix = 1;
|
||||
goto checked;
|
||||
}
|
||||
|
||||
file->dwCRC = (dfusuffix[15] << 24) +
|
||||
(dfusuffix[14] << 16) +
|
||||
(dfusuffix[13] << 8) +
|
||||
dfusuffix[12];
|
||||
|
||||
if (file->dwCRC != crc) {
|
||||
reason = "DFU suffix CRC does not match";
|
||||
missing_suffix = 1;
|
||||
goto checked;
|
||||
}
|
||||
|
||||
/* At this point we believe we have a DFU suffix
|
||||
so we require further checks to succeed */
|
||||
|
||||
file->bcdDFU = (dfusuffix[7] << 8) + dfusuffix[6];
|
||||
|
||||
if (verbose)
|
||||
printf("DFU suffix version %x\n", file->bcdDFU);
|
||||
|
||||
file->size.suffix = dfusuffix[11];
|
||||
|
||||
if (file->size.suffix < DFU_SUFFIX_LENGTH) {
|
||||
errx(EX_IOERR, "Unsupported DFU suffix length %d",
|
||||
file->size.suffix);
|
||||
}
|
||||
|
||||
if (file->size.suffix > file->size.total) {
|
||||
errx(EX_IOERR, "Invalid DFU suffix length %d",
|
||||
file->size.suffix);
|
||||
}
|
||||
|
||||
file->idVendor = (dfusuffix[5] << 8) + dfusuffix[4];
|
||||
file->idProduct = (dfusuffix[3] << 8) + dfusuffix[2];
|
||||
file->bcdDevice = (dfusuffix[1] << 8) + dfusuffix[0];
|
||||
|
||||
checked:
|
||||
if (missing_suffix) {
|
||||
if (check_suffix == NEEDS_SUFFIX) {
|
||||
warnx("%s", reason);
|
||||
errx(EX_IOERR, "Valid DFU suffix needed");
|
||||
} else if (check_suffix == MAYBE_SUFFIX) {
|
||||
warnx("%s", reason);
|
||||
warnx("A valid DFU suffix will be required in "
|
||||
"a future dfu-util release!!!");
|
||||
}
|
||||
} else {
|
||||
if (check_suffix == NO_SUFFIX) {
|
||||
errx(EX_SOFTWARE, "Please remove existing DFU suffix before adding a new one.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
res = probe_prefix(file);
|
||||
if ((res || file->size.prefix == 0) && check_prefix == NEEDS_PREFIX)
|
||||
errx(EX_IOERR, "Valid DFU prefix needed");
|
||||
if (file->size.prefix && check_prefix == NO_PREFIX)
|
||||
errx(EX_IOERR, "A prefix already exists, please delete it first");
|
||||
if (file->size.prefix && verbose) {
|
||||
uint8_t *data = file->firmware;
|
||||
if (file->prefix_type == LMDFU_PREFIX)
|
||||
printf("Possible TI Stellaris DFU prefix with "
|
||||
"the following properties\n"
|
||||
"Address: 0x%08x\n"
|
||||
"Payload length: %d\n",
|
||||
file->lmdfu_address,
|
||||
data[4] | (data[5] << 8) |
|
||||
(data[6] << 16) | (data[7] << 14));
|
||||
else if (file->prefix_type == LPCDFU_UNENCRYPTED_PREFIX)
|
||||
printf("Possible unencrypted NXP LPC DFU prefix with "
|
||||
"the following properties\n"
|
||||
"Payload length: %d kiByte\n",
|
||||
data[2] >>1 | (data[3] << 7) );
|
||||
else
|
||||
errx(EX_IOERR, "Unknown DFU prefix type");
|
||||
}
|
||||
}
|
||||
|
||||
void dfu_store_file(struct dfu_file *file, int write_suffix, int write_prefix)
|
||||
{
|
||||
uint32_t crc = 0xffffffff;
|
||||
int f;
|
||||
|
||||
f = open(file->name, O_WRONLY | O_BINARY | O_TRUNC | O_CREAT, 0666);
|
||||
if (f < 0)
|
||||
err(EX_IOERR, "Could not open file %s for writing", file->name);
|
||||
|
||||
/* write prefix, if any */
|
||||
if (write_prefix) {
|
||||
if (file->prefix_type == LMDFU_PREFIX) {
|
||||
uint8_t lmdfu_prefix[LMDFU_PREFIX_LENGTH];
|
||||
uint32_t addr = file->lmdfu_address / 1024;
|
||||
|
||||
/* lmdfu_dfu_prefix payload length excludes prefix and suffix */
|
||||
uint32_t len = file->size.total -
|
||||
file->size.prefix - file->size.suffix;
|
||||
|
||||
lmdfu_prefix[0] = 0x01; /* STELLARIS_DFU_PROG */
|
||||
lmdfu_prefix[1] = 0x00; /* Reserved */
|
||||
lmdfu_prefix[2] = (uint8_t)(addr & 0xff);
|
||||
lmdfu_prefix[3] = (uint8_t)(addr >> 8);
|
||||
lmdfu_prefix[4] = (uint8_t)(len & 0xff);
|
||||
lmdfu_prefix[5] = (uint8_t)(len >> 8) & 0xff;
|
||||
lmdfu_prefix[6] = (uint8_t)(len >> 16) & 0xff;
|
||||
lmdfu_prefix[7] = (uint8_t)(len >> 24);
|
||||
|
||||
crc = dfu_file_write_crc(f, crc, lmdfu_prefix, LMDFU_PREFIX_LENGTH);
|
||||
}
|
||||
if (file->prefix_type == LPCDFU_UNENCRYPTED_PREFIX) {
|
||||
uint8_t lpcdfu_prefix[LPCDFU_PREFIX_LENGTH] = {0};
|
||||
int i;
|
||||
|
||||
/* Payload is firmware and prefix rounded to 512 bytes */
|
||||
uint32_t len = (file->size.total - file->size.suffix + 511) /512;
|
||||
|
||||
lpcdfu_prefix[0] = 0x1a; /* Unencypted*/
|
||||
lpcdfu_prefix[1] = 0x3f; /* Reserved */
|
||||
lpcdfu_prefix[2] = (uint8_t)(len & 0xff);
|
||||
lpcdfu_prefix[3] = (uint8_t)((len >> 8) & 0xff);
|
||||
for (i = 12; i < LPCDFU_PREFIX_LENGTH; i++)
|
||||
lpcdfu_prefix[i] = 0xff;
|
||||
|
||||
crc = dfu_file_write_crc(f, crc, lpcdfu_prefix, LPCDFU_PREFIX_LENGTH);
|
||||
}
|
||||
}
|
||||
/* write firmware binary */
|
||||
crc = dfu_file_write_crc(f, crc, file->firmware + file->size.prefix,
|
||||
file->size.total - file->size.prefix - file->size.suffix);
|
||||
|
||||
/* write suffix, if any */
|
||||
if (write_suffix) {
|
||||
uint8_t dfusuffix[DFU_SUFFIX_LENGTH];
|
||||
|
||||
dfusuffix[0] = file->bcdDevice & 0xff;
|
||||
dfusuffix[1] = file->bcdDevice >> 8;
|
||||
dfusuffix[2] = file->idProduct & 0xff;
|
||||
dfusuffix[3] = file->idProduct >> 8;
|
||||
dfusuffix[4] = file->idVendor & 0xff;
|
||||
dfusuffix[5] = file->idVendor >> 8;
|
||||
dfusuffix[6] = file->bcdDFU & 0xff;
|
||||
dfusuffix[7] = file->bcdDFU >> 8;
|
||||
dfusuffix[8] = 'U';
|
||||
dfusuffix[9] = 'F';
|
||||
dfusuffix[10] = 'D';
|
||||
dfusuffix[11] = DFU_SUFFIX_LENGTH;
|
||||
|
||||
crc = dfu_file_write_crc(f, crc, dfusuffix,
|
||||
DFU_SUFFIX_LENGTH - 4);
|
||||
|
||||
dfusuffix[12] = crc;
|
||||
dfusuffix[13] = crc >> 8;
|
||||
dfusuffix[14] = crc >> 16;
|
||||
dfusuffix[15] = crc >> 24;
|
||||
|
||||
crc = dfu_file_write_crc(f, crc, dfusuffix + 12, 4);
|
||||
}
|
||||
close(f);
|
||||
}
|
||||
|
||||
void show_suffix_and_prefix(struct dfu_file *file)
|
||||
{
|
||||
if (file->size.prefix == LMDFU_PREFIX_LENGTH) {
|
||||
printf("The file %s contains a TI Stellaris DFU prefix with the following properties:\n", file->name);
|
||||
printf("Address:\t0x%08x\n", file->lmdfu_address);
|
||||
} else if (file->size.prefix == LPCDFU_PREFIX_LENGTH) {
|
||||
uint8_t * prefix = file->firmware;
|
||||
printf("The file %s contains a NXP unencrypted LPC DFU prefix with the following properties:\n", file->name);
|
||||
printf("Size:\t%5d kiB\n", prefix[2]>>1|prefix[3]<<7);
|
||||
} else if (file->size.prefix != 0) {
|
||||
printf("The file %s contains an unknown prefix\n", file->name);
|
||||
}
|
||||
if (file->size.suffix > 0) {
|
||||
printf("The file %s contains a DFU suffix with the following properties:\n", file->name);
|
||||
printf("BCD device:\t0x%04X\n", file->bcdDevice);
|
||||
printf("Product ID:\t0x%04X\n",file->idProduct);
|
||||
printf("Vendor ID:\t0x%04X\n", file->idVendor);
|
||||
printf("BCD DFU:\t0x%04X\n", file->bcdDFU);
|
||||
printf("Length:\t\t%i\n", file->size.suffix);
|
||||
printf("CRC:\t\t0x%08X\n", file->dwCRC);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
|
||||
#ifndef DFU_FILE_H
|
||||
#define DFU_FILE_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct dfu_file {
|
||||
/* File name */
|
||||
const char *name;
|
||||
/* Pointer to file loaded into memory */
|
||||
uint8_t *firmware;
|
||||
/* Different sizes */
|
||||
struct {
|
||||
int total;
|
||||
int prefix;
|
||||
int suffix;
|
||||
} size;
|
||||
/* From prefix fields */
|
||||
uint32_t lmdfu_address;
|
||||
/* From prefix fields */
|
||||
uint32_t prefix_type;
|
||||
|
||||
/* From DFU suffix fields */
|
||||
uint32_t dwCRC;
|
||||
uint16_t bcdDFU;
|
||||
uint16_t idVendor;
|
||||
uint16_t idProduct;
|
||||
uint16_t bcdDevice;
|
||||
};
|
||||
|
||||
enum suffix_req {
|
||||
NO_SUFFIX,
|
||||
NEEDS_SUFFIX,
|
||||
MAYBE_SUFFIX
|
||||
};
|
||||
|
||||
enum prefix_req {
|
||||
NO_PREFIX,
|
||||
NEEDS_PREFIX,
|
||||
MAYBE_PREFIX
|
||||
};
|
||||
|
||||
enum prefix_type {
|
||||
ZERO_PREFIX,
|
||||
LMDFU_PREFIX,
|
||||
LPCDFU_UNENCRYPTED_PREFIX
|
||||
};
|
||||
|
||||
extern int verbose;
|
||||
|
||||
void dfu_load_file(struct dfu_file *file, enum suffix_req check_suffix, enum prefix_req check_prefix);
|
||||
void dfu_store_file(struct dfu_file *file, int write_suffix, int write_prefix);
|
||||
|
||||
void dfu_progress_bar(const char *desc, unsigned long long curr,
|
||||
unsigned long long max);
|
||||
void *dfu_malloc(size_t size);
|
||||
uint32_t dfu_file_write_crc(int f, uint32_t crc, const void *buf, int size);
|
||||
void show_suffix_and_prefix(struct dfu_file *file);
|
||||
|
||||
#endif /* DFU_FILE_H */
|
|
@ -0,0 +1,196 @@
|
|||
/*
|
||||
* DFU transfer routines
|
||||
*
|
||||
* This is supposed to be a general DFU implementation, as specified in the
|
||||
* USB DFU 1.0 and 1.1 specification.
|
||||
*
|
||||
* The code was originally intended to interface with a USB device running the
|
||||
* "sam7dfu" firmware (see http://www.openpcd.org/) on an AT91SAM7 processor.
|
||||
*
|
||||
* Copyright 2007-2008 Harald Welte <laforge@gnumonks.org>
|
||||
* Copyright 2013 Hans Petter Selasky <hps@bitfrost.no>
|
||||
* Copyright 2014 Tormod Volden <debian.tormod@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <libusb.h>
|
||||
|
||||
#include "portable.h"
|
||||
#include "dfu.h"
|
||||
#include "usb_dfu.h"
|
||||
#include "dfu_file.h"
|
||||
#include "dfu_load.h"
|
||||
#include "quirks.h"
|
||||
|
||||
int dfuload_do_upload(struct dfu_if *dif, int xfer_size,
|
||||
int expected_size, int fd)
|
||||
{
|
||||
int total_bytes = 0;
|
||||
unsigned short transaction = 0;
|
||||
unsigned char *buf;
|
||||
int ret;
|
||||
|
||||
buf = dfu_malloc(xfer_size);
|
||||
|
||||
printf("Copying data from DFU device to PC\n");
|
||||
dfu_progress_bar("Upload", 0, 1);
|
||||
|
||||
while (1) {
|
||||
int rc;
|
||||
rc = dfu_upload(dif->dev_handle, dif->interface,
|
||||
xfer_size, transaction++, buf);
|
||||
if (rc < 0) {
|
||||
warnx("Error during upload");
|
||||
ret = rc;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
dfu_file_write_crc(fd, 0, buf, rc);
|
||||
total_bytes += rc;
|
||||
|
||||
if (total_bytes < 0)
|
||||
errx(EX_SOFTWARE, "Received too many bytes (wraparound)");
|
||||
|
||||
if (rc < xfer_size) {
|
||||
/* last block, return */
|
||||
ret = total_bytes;
|
||||
break;
|
||||
}
|
||||
dfu_progress_bar("Upload", total_bytes, expected_size);
|
||||
}
|
||||
ret = 0;
|
||||
|
||||
out_free:
|
||||
dfu_progress_bar("Upload", total_bytes, total_bytes);
|
||||
if (total_bytes == 0)
|
||||
printf("\nFailed.\n");
|
||||
free(buf);
|
||||
if (verbose)
|
||||
printf("Received a total of %i bytes\n", total_bytes);
|
||||
if (expected_size != 0 && total_bytes != expected_size)
|
||||
errx(EX_SOFTWARE, "Unexpected number of bytes uploaded from device");
|
||||
return ret;
|
||||
}
|
||||
|
||||
int dfuload_do_dnload(struct dfu_if *dif, int xfer_size, struct dfu_file *file)
|
||||
{
|
||||
int bytes_sent;
|
||||
int expected_size;
|
||||
unsigned char *buf;
|
||||
unsigned short transaction = 0;
|
||||
struct dfu_status dst;
|
||||
int ret;
|
||||
|
||||
printf("Copying data from PC to DFU device\n");
|
||||
|
||||
buf = file->firmware;
|
||||
expected_size = file->size.total - file->size.suffix;
|
||||
bytes_sent = 0;
|
||||
|
||||
dfu_progress_bar("Download", 0, 1);
|
||||
while (bytes_sent < expected_size) {
|
||||
int bytes_left;
|
||||
int chunk_size;
|
||||
|
||||
bytes_left = expected_size - bytes_sent;
|
||||
if (bytes_left < xfer_size)
|
||||
chunk_size = bytes_left;
|
||||
else
|
||||
chunk_size = xfer_size;
|
||||
|
||||
ret = dfu_download(dif->dev_handle, dif->interface,
|
||||
chunk_size, transaction++, chunk_size ? buf : NULL);
|
||||
if (ret < 0) {
|
||||
warnx("Error during download");
|
||||
goto out;
|
||||
}
|
||||
bytes_sent += chunk_size;
|
||||
buf += chunk_size;
|
||||
|
||||
do {
|
||||
ret = dfu_get_status(dif, &dst);
|
||||
if (ret < 0) {
|
||||
errx(EX_IOERR, "Error during download get_status");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (dst.bState == DFU_STATE_dfuDNLOAD_IDLE ||
|
||||
dst.bState == DFU_STATE_dfuERROR)
|
||||
break;
|
||||
|
||||
/* Wait while device executes flashing */
|
||||
milli_sleep(dst.bwPollTimeout);
|
||||
|
||||
} while (1);
|
||||
if (dst.bStatus != DFU_STATUS_OK) {
|
||||
printf(" failed!\n");
|
||||
printf("state(%u) = %s, status(%u) = %s\n", dst.bState,
|
||||
dfu_state_to_string(dst.bState), dst.bStatus,
|
||||
dfu_status_to_string(dst.bStatus));
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
dfu_progress_bar("Download", bytes_sent, bytes_sent + bytes_left);
|
||||
}
|
||||
|
||||
/* send one zero sized download request to signalize end */
|
||||
ret = dfu_download(dif->dev_handle, dif->interface,
|
||||
0, transaction, NULL);
|
||||
if (ret < 0) {
|
||||
errx(EX_IOERR, "Error sending completion packet");
|
||||
goto out;
|
||||
}
|
||||
|
||||
dfu_progress_bar("Download", bytes_sent, bytes_sent);
|
||||
|
||||
if (verbose)
|
||||
printf("Sent a total of %i bytes\n", bytes_sent);
|
||||
|
||||
get_status:
|
||||
/* Transition to MANIFEST_SYNC state */
|
||||
ret = dfu_get_status(dif, &dst);
|
||||
if (ret < 0) {
|
||||
warnx("unable to read DFU status after completion");
|
||||
goto out;
|
||||
}
|
||||
printf("state(%u) = %s, status(%u) = %s\n", dst.bState,
|
||||
dfu_state_to_string(dst.bState), dst.bStatus,
|
||||
dfu_status_to_string(dst.bStatus));
|
||||
|
||||
milli_sleep(dst.bwPollTimeout);
|
||||
|
||||
/* FIXME: deal correctly with ManifestationTolerant=0 / WillDetach bits */
|
||||
switch (dst.bState) {
|
||||
case DFU_STATE_dfuMANIFEST_SYNC:
|
||||
case DFU_STATE_dfuMANIFEST:
|
||||
/* some devices (e.g. TAS1020b) need some time before we
|
||||
* can obtain the status */
|
||||
milli_sleep(1000);
|
||||
goto get_status;
|
||||
break;
|
||||
case DFU_STATE_dfuIDLE:
|
||||
break;
|
||||
}
|
||||
printf("Done!\n");
|
||||
|
||||
out:
|
||||
return bytes_sent;
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
#ifndef DFU_LOAD_H
|
||||
#define DFU_LOAD_H
|
||||
|
||||
int dfuload_do_upload(struct dfu_if *dif, int xfer_size, int expected_size, int fd);
|
||||
int dfuload_do_dnload(struct dfu_if *dif, int xfer_size, struct dfu_file *file);
|
||||
|
||||
#endif /* DFU_LOAD_H */
|
|
@ -0,0 +1,346 @@
|
|||
/*
|
||||
* Functions for detecting DFU USB entities
|
||||
*
|
||||
* Written by Harald Welte <laforge@openmoko.org>
|
||||
* Copyright 2007-2008 by OpenMoko, Inc.
|
||||
* Copyright 2013 Hans Petter Selasky <hps@bitfrost.no>
|
||||
*
|
||||
* Based on existing code of dfu-programmer-0.4
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <libusb.h>
|
||||
|
||||
#include "portable.h"
|
||||
#include "dfu.h"
|
||||
#include "usb_dfu.h"
|
||||
#include "dfu_file.h"
|
||||
#include "dfu_load.h"
|
||||
#include "dfu_util.h"
|
||||
#include "dfuse.h"
|
||||
#include "quirks.h"
|
||||
|
||||
#ifdef HAVE_USBPATH_H
|
||||
#include <usbpath.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Look for a descriptor in a concatenated descriptor list. Will
|
||||
* return upon the first match of the given descriptor type. Returns length of
|
||||
* found descriptor, limited to res_size
|
||||
*/
|
||||
static int find_descriptor(const uint8_t *desc_list, int list_len,
|
||||
uint8_t desc_type, void *res_buf, int res_size)
|
||||
{
|
||||
int p = 0;
|
||||
|
||||
if (list_len < 2)
|
||||
return (-1);
|
||||
|
||||
while (p + 1 < list_len) {
|
||||
int desclen;
|
||||
|
||||
desclen = (int) desc_list[p];
|
||||
if (desclen == 0) {
|
||||
warnx("Invalid descriptor list");
|
||||
return -1;
|
||||
}
|
||||
if (desc_list[p + 1] == desc_type) {
|
||||
if (desclen > res_size)
|
||||
desclen = res_size;
|
||||
if (p + desclen > list_len)
|
||||
desclen = list_len - p;
|
||||
memcpy(res_buf, &desc_list[p], desclen);
|
||||
return desclen;
|
||||
}
|
||||
p += (int) desc_list[p];
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void probe_configuration(libusb_device *dev, struct libusb_device_descriptor *desc)
|
||||
{
|
||||
struct usb_dfu_func_descriptor func_dfu;
|
||||
libusb_device_handle *devh;
|
||||
struct dfu_if *pdfu;
|
||||
struct libusb_config_descriptor *cfg;
|
||||
const struct libusb_interface_descriptor *intf;
|
||||
const struct libusb_interface *uif;
|
||||
char alt_name[MAX_DESC_STR_LEN + 1];
|
||||
char serial_name[MAX_DESC_STR_LEN + 1];
|
||||
int cfg_idx;
|
||||
int intf_idx;
|
||||
int alt_idx;
|
||||
int ret;
|
||||
int has_dfu;
|
||||
|
||||
for (cfg_idx = 0; cfg_idx != desc->bNumConfigurations; cfg_idx++) {
|
||||
memset(&func_dfu, 0, sizeof(func_dfu));
|
||||
has_dfu = 0;
|
||||
|
||||
ret = libusb_get_config_descriptor(dev, cfg_idx, &cfg);
|
||||
if (ret != 0)
|
||||
return;
|
||||
if (match_config_index > -1 && match_config_index != cfg->bConfigurationValue) {
|
||||
libusb_free_config_descriptor(cfg);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* In some cases, noticably FreeBSD if uid != 0,
|
||||
* the configuration descriptors are empty
|
||||
*/
|
||||
if (!cfg)
|
||||
return;
|
||||
|
||||
ret = find_descriptor(cfg->extra, cfg->extra_length,
|
||||
USB_DT_DFU, &func_dfu, sizeof(func_dfu));
|
||||
if (ret > -1)
|
||||
goto found_dfu;
|
||||
|
||||
for (intf_idx = 0; intf_idx < cfg->bNumInterfaces;
|
||||
intf_idx++) {
|
||||
uif = &cfg->interface[intf_idx];
|
||||
if (!uif)
|
||||
break;
|
||||
|
||||
for (alt_idx = 0; alt_idx < cfg->interface[intf_idx].num_altsetting;
|
||||
alt_idx++) {
|
||||
intf = &uif->altsetting[alt_idx];
|
||||
|
||||
ret = find_descriptor(intf->extra, intf->extra_length, USB_DT_DFU,
|
||||
&func_dfu, sizeof(func_dfu));
|
||||
if (ret > -1)
|
||||
goto found_dfu;
|
||||
|
||||
if (intf->bInterfaceClass != 0xfe ||
|
||||
intf->bInterfaceSubClass != 1)
|
||||
continue;
|
||||
|
||||
has_dfu = 1;
|
||||
}
|
||||
}
|
||||
if (has_dfu) {
|
||||
/*
|
||||
* Finally try to retrieve it requesting the
|
||||
* device directly This is not supported on
|
||||
* all devices for non-standard types
|
||||
*/
|
||||
if (libusb_open(dev, &devh) == 0) {
|
||||
ret = libusb_get_descriptor(devh, USB_DT_DFU, 0,
|
||||
(void *)&func_dfu, sizeof(func_dfu));
|
||||
libusb_close(devh);
|
||||
if (ret > -1)
|
||||
goto found_dfu;
|
||||
}
|
||||
warnx("Device has DFU interface, "
|
||||
"but has no DFU functional descriptor");
|
||||
|
||||
/* fake version 1.0 */
|
||||
func_dfu.bLength = 7;
|
||||
func_dfu.bcdDFUVersion = libusb_cpu_to_le16(0x0100);
|
||||
goto found_dfu;
|
||||
}
|
||||
libusb_free_config_descriptor(cfg);
|
||||
continue;
|
||||
|
||||
found_dfu:
|
||||
if (func_dfu.bLength == 7) {
|
||||
printf("Deducing device DFU version from functional descriptor "
|
||||
"length\n");
|
||||
func_dfu.bcdDFUVersion = libusb_cpu_to_le16(0x0100);
|
||||
} else if (func_dfu.bLength < 9) {
|
||||
printf("Error obtaining DFU functional descriptor\n");
|
||||
printf("Please report this as a bug!\n");
|
||||
printf("Warning: Assuming DFU version 1.0\n");
|
||||
func_dfu.bcdDFUVersion = libusb_cpu_to_le16(0x0100);
|
||||
printf("Warning: Transfer size can not be detected\n");
|
||||
func_dfu.wTransferSize = 0;
|
||||
}
|
||||
|
||||
for (intf_idx = 0; intf_idx < cfg->bNumInterfaces;
|
||||
intf_idx++) {
|
||||
if (match_iface_index > -1 && match_iface_index != intf_idx)
|
||||
continue;
|
||||
|
||||
uif = &cfg->interface[intf_idx];
|
||||
if (!uif)
|
||||
break;
|
||||
|
||||
for (alt_idx = 0;
|
||||
alt_idx < uif->num_altsetting; alt_idx++) {
|
||||
int dfu_mode;
|
||||
|
||||
intf = &uif->altsetting[alt_idx];
|
||||
|
||||
if (intf->bInterfaceClass != 0xfe ||
|
||||
intf->bInterfaceSubClass != 1)
|
||||
continue;
|
||||
|
||||
dfu_mode = (intf->bInterfaceProtocol == 2);
|
||||
/* e.g. DSO Nano has bInterfaceProtocol 0 instead of 2 */
|
||||
if (func_dfu.bcdDFUVersion == 0x011a && intf->bInterfaceProtocol == 0)
|
||||
dfu_mode = 1;
|
||||
|
||||
if (dfu_mode &&
|
||||
match_iface_alt_index > -1 && match_iface_alt_index != alt_idx)
|
||||
continue;
|
||||
|
||||
if (dfu_mode) {
|
||||
if ((match_vendor_dfu >= 0 && match_vendor_dfu != desc->idVendor) ||
|
||||
(match_product_dfu >= 0 && match_product_dfu != desc->idProduct)) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if ((match_vendor >= 0 && match_vendor != desc->idVendor) ||
|
||||
(match_product >= 0 && match_product != desc->idProduct)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (libusb_open(dev, &devh)) {
|
||||
warnx("Cannot open DFU device %04x:%04x", desc->idVendor, desc->idProduct);
|
||||
break;
|
||||
}
|
||||
if (intf->iInterface != 0)
|
||||
ret = libusb_get_string_descriptor_ascii(devh,
|
||||
intf->iInterface, (void *)alt_name, MAX_DESC_STR_LEN);
|
||||
else
|
||||
ret = -1;
|
||||
if (ret < 1)
|
||||
strcpy(alt_name, "UNKNOWN");
|
||||
if (desc->iSerialNumber != 0)
|
||||
ret = libusb_get_string_descriptor_ascii(devh,
|
||||
desc->iSerialNumber, (void *)serial_name, MAX_DESC_STR_LEN);
|
||||
else
|
||||
ret = -1;
|
||||
if (ret < 1)
|
||||
strcpy(serial_name, "UNKNOWN");
|
||||
libusb_close(devh);
|
||||
|
||||
if (dfu_mode &&
|
||||
match_iface_alt_name != NULL && strcmp(alt_name, match_iface_alt_name))
|
||||
continue;
|
||||
|
||||
if (dfu_mode) {
|
||||
if (match_serial_dfu != NULL && strcmp(match_serial_dfu, serial_name))
|
||||
continue;
|
||||
} else {
|
||||
if (match_serial != NULL && strcmp(match_serial, serial_name))
|
||||
continue;
|
||||
}
|
||||
|
||||
pdfu = dfu_malloc(sizeof(*pdfu));
|
||||
|
||||
memset(pdfu, 0, sizeof(*pdfu));
|
||||
|
||||
pdfu->func_dfu = func_dfu;
|
||||
pdfu->dev = libusb_ref_device(dev);
|
||||
pdfu->quirks = get_quirks(desc->idVendor,
|
||||
desc->idProduct, desc->bcdDevice);
|
||||
pdfu->vendor = desc->idVendor;
|
||||
pdfu->product = desc->idProduct;
|
||||
pdfu->bcdDevice = desc->bcdDevice;
|
||||
pdfu->configuration = cfg->bConfigurationValue;
|
||||
pdfu->interface = intf->bInterfaceNumber;
|
||||
pdfu->altsetting = intf->bAlternateSetting;
|
||||
pdfu->devnum = libusb_get_device_address(dev);
|
||||
pdfu->busnum = libusb_get_bus_number(dev);
|
||||
pdfu->alt_name = strdup(alt_name);
|
||||
if (pdfu->alt_name == NULL)
|
||||
errx(EX_SOFTWARE, "Out of memory");
|
||||
pdfu->serial_name = strdup(serial_name);
|
||||
if (pdfu->serial_name == NULL)
|
||||
errx(EX_SOFTWARE, "Out of memory");
|
||||
if (dfu_mode)
|
||||
pdfu->flags |= DFU_IFF_DFU;
|
||||
if (pdfu->quirks & QUIRK_FORCE_DFU11) {
|
||||
pdfu->func_dfu.bcdDFUVersion =
|
||||
libusb_cpu_to_le16(0x0110);
|
||||
}
|
||||
pdfu->bMaxPacketSize0 = desc->bMaxPacketSize0;
|
||||
|
||||
/* queue into list */
|
||||
pdfu->next = dfu_root;
|
||||
dfu_root = pdfu;
|
||||
}
|
||||
}
|
||||
libusb_free_config_descriptor(cfg);
|
||||
}
|
||||
}
|
||||
|
||||
void probe_devices(libusb_context *ctx)
|
||||
{
|
||||
libusb_device **list;
|
||||
ssize_t num_devs;
|
||||
ssize_t i;
|
||||
|
||||
num_devs = libusb_get_device_list(ctx, &list);
|
||||
for (i = 0; i < num_devs; ++i) {
|
||||
struct libusb_device_descriptor desc;
|
||||
struct libusb_device *dev = list[i];
|
||||
|
||||
if (match_bus > -1 && match_bus != libusb_get_bus_number(dev))
|
||||
continue;
|
||||
if (match_device > -1 && match_device != libusb_get_device_address(dev))
|
||||
continue;
|
||||
if (libusb_get_device_descriptor(dev, &desc))
|
||||
continue;
|
||||
probe_configuration(dev, &desc);
|
||||
}
|
||||
libusb_free_device_list(list, 0);
|
||||
}
|
||||
|
||||
void disconnect_devices(void)
|
||||
{
|
||||
struct dfu_if *pdfu;
|
||||
struct dfu_if *prev = NULL;
|
||||
|
||||
for (pdfu = dfu_root; pdfu != NULL; pdfu = pdfu->next) {
|
||||
free(prev);
|
||||
libusb_unref_device(pdfu->dev);
|
||||
free(pdfu->alt_name);
|
||||
free(pdfu->serial_name);
|
||||
prev = pdfu;
|
||||
}
|
||||
free(prev);
|
||||
dfu_root = NULL;
|
||||
}
|
||||
|
||||
void print_dfu_if(struct dfu_if *dfu_if)
|
||||
{
|
||||
printf("Found %s: [%04x:%04x] ver=%04x, devnum=%u, cfg=%u, intf=%u, "
|
||||
"alt=%u, name=\"%s\", serial=\"%s\"\n",
|
||||
dfu_if->flags & DFU_IFF_DFU ? "DFU" : "Runtime",
|
||||
dfu_if->vendor, dfu_if->product,
|
||||
dfu_if->bcdDevice, dfu_if->devnum,
|
||||
dfu_if->configuration, dfu_if->interface,
|
||||
dfu_if->altsetting, dfu_if->alt_name,
|
||||
dfu_if->serial_name);
|
||||
}
|
||||
|
||||
/* Walk the device tree and print out DFU devices */
|
||||
void list_dfu_interfaces(void)
|
||||
{
|
||||
struct dfu_if *pdfu;
|
||||
|
||||
for (pdfu = dfu_root; pdfu != NULL; pdfu = pdfu->next)
|
||||
print_dfu_if(pdfu);
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
#ifndef DFU_UTIL_H
|
||||
#define DFU_UTIL_H
|
||||
|
||||
/* USB string descriptor should contain max 126 UTF-16 characters
|
||||
* but 253 would even accomodate any UTF-8 encoding */
|
||||
#define MAX_DESC_STR_LEN 253
|
||||
|
||||
enum mode {
|
||||
MODE_NONE,
|
||||
MODE_VERSION,
|
||||
MODE_LIST,
|
||||
MODE_DETACH,
|
||||
MODE_UPLOAD,
|
||||
MODE_DOWNLOAD
|
||||
};
|
||||
|
||||
extern struct dfu_if *dfu_root;
|
||||
extern int match_bus;
|
||||
extern int match_device;
|
||||
extern int match_vendor;
|
||||
extern int match_product;
|
||||
extern int match_vendor_dfu;
|
||||
extern int match_product_dfu;
|
||||
extern int match_config_index;
|
||||
extern int match_iface_index;
|
||||
extern int match_iface_alt_index;
|
||||
extern const char *match_iface_alt_name;
|
||||
extern const char *match_serial;
|
||||
extern const char *match_serial_dfu;
|
||||
|
||||
void probe_devices(libusb_context *);
|
||||
void disconnect_devices(void);
|
||||
void print_dfu_if(struct dfu_if *);
|
||||
void list_dfu_interfaces(void);
|
||||
|
||||
#endif /* DFU_UTIL_H */
|
|
@ -0,0 +1,652 @@
|
|||
/*
|
||||
* DfuSe specific functions
|
||||
*
|
||||
* This implements the ST Microsystems DFU extensions (DfuSe)
|
||||
* as per the DfuSe 1.1a specification (ST documents AN3156, AN2606)
|
||||
* The DfuSe file format is described in ST document UM0391.
|
||||
*
|
||||
* Copyright 2010-2014 Tormod Volden <debian.tormod@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "portable.h"
|
||||
#include "dfu.h"
|
||||
#include "usb_dfu.h"
|
||||
#include "dfu_file.h"
|
||||
#include "dfuse.h"
|
||||
#include "dfuse_mem.h"
|
||||
|
||||
#define DFU_TIMEOUT 5000
|
||||
|
||||
extern int verbose;
|
||||
static unsigned int last_erased_page = 1; /* non-aligned value, won't match */
|
||||
static struct memsegment *mem_layout;
|
||||
static unsigned int dfuse_address = 0;
|
||||
static unsigned int dfuse_length = 0;
|
||||
static int dfuse_force = 0;
|
||||
static int dfuse_leave = 0;
|
||||
static int dfuse_unprotect = 0;
|
||||
static int dfuse_mass_erase = 0;
|
||||
|
||||
unsigned int quad2uint(unsigned char *p)
|
||||
{
|
||||
return (*p + (*(p + 1) << 8) + (*(p + 2) << 16) + (*(p + 3) << 24));
|
||||
}
|
||||
|
||||
void dfuse_parse_options(const char *options)
|
||||
{
|
||||
char *end;
|
||||
const char *endword;
|
||||
unsigned int number;
|
||||
|
||||
/* address, possibly empty, must be first */
|
||||
if (*options != ':') {
|
||||
endword = strchr(options, ':');
|
||||
if (!endword)
|
||||
endword = options + strlen(options); /* GNU strchrnul */
|
||||
|
||||
number = strtoul(options, &end, 0);
|
||||
if (end == endword) {
|
||||
dfuse_address = number;
|
||||
} else {
|
||||
errx(EX_IOERR, "Invalid dfuse address: %s", options);
|
||||
}
|
||||
options = endword;
|
||||
}
|
||||
|
||||
while (*options) {
|
||||
if (*options == ':') {
|
||||
options++;
|
||||
continue;
|
||||
}
|
||||
endword = strchr(options, ':');
|
||||
if (!endword)
|
||||
endword = options + strlen(options);
|
||||
|
||||
if (!strncmp(options, "force", endword - options)) {
|
||||
dfuse_force++;
|
||||
options += 5;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(options, "leave", endword - options)) {
|
||||
dfuse_leave = 1;
|
||||
options += 5;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(options, "unprotect", endword - options)) {
|
||||
dfuse_unprotect = 1;
|
||||
options += 9;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(options, "mass-erase", endword - options)) {
|
||||
dfuse_mass_erase = 1;
|
||||
options += 10;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* any valid number is interpreted as upload length */
|
||||
number = strtoul(options, &end, 0);
|
||||
if (end == endword) {
|
||||
dfuse_length = number;
|
||||
} else {
|
||||
errx(EX_IOERR, "Invalid dfuse modifier: %s", options);
|
||||
}
|
||||
options = endword;
|
||||
}
|
||||
}
|
||||
|
||||
/* DFU_UPLOAD request for DfuSe 1.1a */
|
||||
int dfuse_upload(struct dfu_if *dif, const unsigned short length,
|
||||
unsigned char *data, unsigned short transaction)
|
||||
{
|
||||
int status;
|
||||
|
||||
status = libusb_control_transfer(dif->dev_handle,
|
||||
/* bmRequestType */ LIBUSB_ENDPOINT_IN |
|
||||
LIBUSB_REQUEST_TYPE_CLASS |
|
||||
LIBUSB_RECIPIENT_INTERFACE,
|
||||
/* bRequest */ DFU_UPLOAD,
|
||||
/* wValue */ transaction,
|
||||
/* wIndex */ dif->interface,
|
||||
/* Data */ data,
|
||||
/* wLength */ length,
|
||||
DFU_TIMEOUT);
|
||||
if (status < 0) {
|
||||
errx(EX_IOERR, "%s: libusb_control_msg returned %d",
|
||||
__FUNCTION__, status);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/* DFU_DNLOAD request for DfuSe 1.1a */
|
||||
int dfuse_download(struct dfu_if *dif, const unsigned short length,
|
||||
unsigned char *data, unsigned short transaction)
|
||||
{
|
||||
int status;
|
||||
|
||||
status = libusb_control_transfer(dif->dev_handle,
|
||||
/* bmRequestType */ LIBUSB_ENDPOINT_OUT |
|
||||
LIBUSB_REQUEST_TYPE_CLASS |
|
||||
LIBUSB_RECIPIENT_INTERFACE,
|
||||
/* bRequest */ DFU_DNLOAD,
|
||||
/* wValue */ transaction,
|
||||
/* wIndex */ dif->interface,
|
||||
/* Data */ data,
|
||||
/* wLength */ length,
|
||||
DFU_TIMEOUT);
|
||||
if (status < 0) {
|
||||
errx(EX_IOERR, "%s: libusb_control_transfer returned %d",
|
||||
__FUNCTION__, status);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/* DfuSe only commands */
|
||||
/* Leaves the device in dfuDNLOAD-IDLE state */
|
||||
int dfuse_special_command(struct dfu_if *dif, unsigned int address,
|
||||
enum dfuse_command command)
|
||||
{
|
||||
const char* dfuse_command_name[] = { "SET_ADDRESS" , "ERASE_PAGE",
|
||||
"MASS_ERASE", "READ_UNPROTECT"};
|
||||
unsigned char buf[5];
|
||||
int length;
|
||||
int ret;
|
||||
struct dfu_status dst;
|
||||
int firstpoll = 1;
|
||||
|
||||
if (command == ERASE_PAGE) {
|
||||
struct memsegment *segment;
|
||||
int page_size;
|
||||
|
||||
segment = find_segment(mem_layout, address);
|
||||
if (!segment || !(segment->memtype & DFUSE_ERASABLE)) {
|
||||
errx(EX_IOERR, "Page at 0x%08x can not be erased",
|
||||
address);
|
||||
}
|
||||
page_size = segment->pagesize;
|
||||
if (verbose > 1)
|
||||
printf("Erasing page size %i at address 0x%08x, page "
|
||||
"starting at 0x%08x\n", page_size, address,
|
||||
address & ~(page_size - 1));
|
||||
buf[0] = 0x41; /* Erase command */
|
||||
length = 5;
|
||||
last_erased_page = address & ~(page_size - 1);
|
||||
} else if (command == SET_ADDRESS) {
|
||||
if (verbose > 2)
|
||||
printf(" Setting address pointer to 0x%08x\n",
|
||||
address);
|
||||
buf[0] = 0x21; /* Set Address Pointer command */
|
||||
length = 5;
|
||||
} else if (command == MASS_ERASE) {
|
||||
buf[0] = 0x41; /* Mass erase command when length = 1 */
|
||||
length = 1;
|
||||
} else if (command == READ_UNPROTECT) {
|
||||
buf[0] = 0x92;
|
||||
length = 1;
|
||||
} else {
|
||||
errx(EX_IOERR, "Non-supported special command %d", command);
|
||||
}
|
||||
buf[1] = address & 0xff;
|
||||
buf[2] = (address >> 8) & 0xff;
|
||||
buf[3] = (address >> 16) & 0xff;
|
||||
buf[4] = (address >> 24) & 0xff;
|
||||
|
||||
ret = dfuse_download(dif, length, buf, 0);
|
||||
if (ret < 0) {
|
||||
errx(EX_IOERR, "Error during special command \"%s\" download",
|
||||
dfuse_command_name[command]);
|
||||
}
|
||||
do {
|
||||
ret = dfu_get_status(dif, &dst);
|
||||
if (ret < 0) {
|
||||
errx(EX_IOERR, "Error during special command \"%s\" get_status",
|
||||
dfuse_command_name[command]);
|
||||
}
|
||||
if (firstpoll) {
|
||||
firstpoll = 0;
|
||||
if (dst.bState != DFU_STATE_dfuDNBUSY) {
|
||||
printf("state(%u) = %s, status(%u) = %s\n", dst.bState,
|
||||
dfu_state_to_string(dst.bState), dst.bStatus,
|
||||
dfu_status_to_string(dst.bStatus));
|
||||
errx(EX_IOERR, "Wrong state after command \"%s\" download",
|
||||
dfuse_command_name[command]);
|
||||
}
|
||||
}
|
||||
/* wait while command is executed */
|
||||
if (verbose)
|
||||
printf(" Poll timeout %i ms\n", dst.bwPollTimeout);
|
||||
milli_sleep(dst.bwPollTimeout);
|
||||
if (command == READ_UNPROTECT)
|
||||
return ret;
|
||||
} while (dst.bState == DFU_STATE_dfuDNBUSY);
|
||||
|
||||
if (dst.bStatus != DFU_STATUS_OK) {
|
||||
errx(EX_IOERR, "%s not correctly executed",
|
||||
dfuse_command_name[command]);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int dfuse_dnload_chunk(struct dfu_if *dif, unsigned char *data, int size,
|
||||
int transaction)
|
||||
{
|
||||
int bytes_sent;
|
||||
struct dfu_status dst;
|
||||
int ret;
|
||||
|
||||
ret = dfuse_download(dif, size, size ? data : NULL, transaction);
|
||||
if (ret < 0) {
|
||||
errx(EX_IOERR, "Error during download");
|
||||
return ret;
|
||||
}
|
||||
bytes_sent = ret;
|
||||
|
||||
do {
|
||||
ret = dfu_get_status(dif, &dst);
|
||||
if (ret < 0) {
|
||||
errx(EX_IOERR, "Error during download get_status");
|
||||
return ret;
|
||||
}
|
||||
milli_sleep(dst.bwPollTimeout);
|
||||
} while (dst.bState != DFU_STATE_dfuDNLOAD_IDLE &&
|
||||
dst.bState != DFU_STATE_dfuERROR &&
|
||||
dst.bState != DFU_STATE_dfuMANIFEST);
|
||||
|
||||
if (dst.bState == DFU_STATE_dfuMANIFEST)
|
||||
printf("Transitioning to dfuMANIFEST state\n");
|
||||
|
||||
if (dst.bStatus != DFU_STATUS_OK) {
|
||||
printf(" failed!\n");
|
||||
printf("state(%u) = %s, status(%u) = %s\n", dst.bState,
|
||||
dfu_state_to_string(dst.bState), dst.bStatus,
|
||||
dfu_status_to_string(dst.bStatus));
|
||||
return -1;
|
||||
}
|
||||
return bytes_sent;
|
||||
}
|
||||
|
||||
int dfuse_do_upload(struct dfu_if *dif, int xfer_size, int fd,
|
||||
const char *dfuse_options)
|
||||
{
|
||||
int total_bytes = 0;
|
||||
int upload_limit = 0;
|
||||
unsigned char *buf;
|
||||
int transaction;
|
||||
int ret;
|
||||
|
||||
buf = dfu_malloc(xfer_size);
|
||||
|
||||
if (dfuse_options)
|
||||
dfuse_parse_options(dfuse_options);
|
||||
if (dfuse_length)
|
||||
upload_limit = dfuse_length;
|
||||
if (dfuse_address) {
|
||||
struct memsegment *segment;
|
||||
|
||||
mem_layout = parse_memory_layout((char *)dif->alt_name);
|
||||
if (!mem_layout)
|
||||
errx(EX_IOERR, "Failed to parse memory layout");
|
||||
|
||||
segment = find_segment(mem_layout, dfuse_address);
|
||||
if (!dfuse_force &&
|
||||
(!segment || !(segment->memtype & DFUSE_READABLE)))
|
||||
errx(EX_IOERR, "Page at 0x%08x is not readable",
|
||||
dfuse_address);
|
||||
|
||||
if (!upload_limit) {
|
||||
upload_limit = segment->end - dfuse_address + 1;
|
||||
printf("Limiting upload to end of memory segment, "
|
||||
"%i bytes\n", upload_limit);
|
||||
}
|
||||
dfuse_special_command(dif, dfuse_address, SET_ADDRESS);
|
||||
dfu_abort_to_idle(dif);
|
||||
} else {
|
||||
/* Boot loader decides the start address, unknown to us */
|
||||
/* Use a short length to lower risk of running out of bounds */
|
||||
if (!upload_limit)
|
||||
upload_limit = 0x4000;
|
||||
printf("Limiting default upload to %i bytes\n", upload_limit);
|
||||
}
|
||||
|
||||
dfu_progress_bar("Upload", 0, 1);
|
||||
|
||||
transaction = 2;
|
||||
while (1) {
|
||||
int rc;
|
||||
|
||||
/* last chunk can be smaller than original xfer_size */
|
||||
if (upload_limit - total_bytes < xfer_size)
|
||||
xfer_size = upload_limit - total_bytes;
|
||||
rc = dfuse_upload(dif, xfer_size, buf, transaction++);
|
||||
if (rc < 0) {
|
||||
ret = rc;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
dfu_file_write_crc(fd, 0, buf, rc);
|
||||
total_bytes += rc;
|
||||
|
||||
if (total_bytes < 0)
|
||||
errx(EX_SOFTWARE, "Received too many bytes");
|
||||
|
||||
if (rc < xfer_size || total_bytes >= upload_limit) {
|
||||
/* last block, return successfully */
|
||||
ret = total_bytes;
|
||||
break;
|
||||
}
|
||||
dfu_progress_bar("Upload", total_bytes, upload_limit);
|
||||
}
|
||||
|
||||
dfu_progress_bar("Upload", total_bytes, total_bytes);
|
||||
|
||||
dfu_abort_to_idle(dif);
|
||||
if (dfuse_leave) {
|
||||
dfuse_special_command(dif, dfuse_address, SET_ADDRESS);
|
||||
dfuse_dnload_chunk(dif, NULL, 0, 2); /* Zero-size */
|
||||
}
|
||||
|
||||
out_free:
|
||||
free(buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Writes an element of any size to the device, taking care of page erases */
|
||||
/* returns 0 on success, otherwise -EINVAL */
|
||||
int dfuse_dnload_element(struct dfu_if *dif, unsigned int dwElementAddress,
|
||||
unsigned int dwElementSize, unsigned char *data,
|
||||
int xfer_size)
|
||||
{
|
||||
int p;
|
||||
int ret;
|
||||
struct memsegment *segment;
|
||||
|
||||
/* Check at least that we can write to the last address */
|
||||
segment =
|
||||
find_segment(mem_layout, dwElementAddress + dwElementSize - 1);
|
||||
if (!segment || !(segment->memtype & DFUSE_WRITEABLE)) {
|
||||
errx(EX_IOERR, "Last page at 0x%08x is not writeable",
|
||||
dwElementAddress + dwElementSize - 1);
|
||||
}
|
||||
|
||||
dfu_progress_bar("Download", 0, 1);
|
||||
|
||||
for (p = 0; p < (int)dwElementSize; p += xfer_size) {
|
||||
int page_size;
|
||||
unsigned int erase_address;
|
||||
unsigned int address = dwElementAddress + p;
|
||||
int chunk_size = xfer_size;
|
||||
|
||||
segment = find_segment(mem_layout, address);
|
||||
if (!segment || !(segment->memtype & DFUSE_WRITEABLE)) {
|
||||
errx(EX_IOERR, "Page at 0x%08x is not writeable",
|
||||
address);
|
||||
}
|
||||
page_size = segment->pagesize;
|
||||
|
||||
/* check if this is the last chunk */
|
||||
if (p + chunk_size > (int)dwElementSize)
|
||||
chunk_size = dwElementSize - p;
|
||||
|
||||
/* Erase only for flash memory downloads */
|
||||
if ((segment->memtype & DFUSE_ERASABLE) && !dfuse_mass_erase) {
|
||||
/* erase all involved pages */
|
||||
for (erase_address = address;
|
||||
erase_address < address + chunk_size;
|
||||
erase_address += page_size)
|
||||
if ((erase_address & ~(page_size - 1)) !=
|
||||
last_erased_page)
|
||||
dfuse_special_command(dif,
|
||||
erase_address,
|
||||
ERASE_PAGE);
|
||||
|
||||
if (((address + chunk_size - 1) & ~(page_size - 1)) !=
|
||||
last_erased_page) {
|
||||
if (verbose > 2)
|
||||
printf(" Chunk extends into next page,"
|
||||
" erase it as well\n");
|
||||
dfuse_special_command(dif,
|
||||
address + chunk_size - 1,
|
||||
ERASE_PAGE);
|
||||
}
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
printf(" Download from image offset "
|
||||
"%08x to memory %08x-%08x, size %i\n",
|
||||
p, address, address + chunk_size - 1,
|
||||
chunk_size);
|
||||
} else {
|
||||
dfu_progress_bar("Download", p, dwElementSize);
|
||||
}
|
||||
|
||||
dfuse_special_command(dif, address, SET_ADDRESS);
|
||||
|
||||
/* transaction = 2 for no address offset */
|
||||
ret = dfuse_dnload_chunk(dif, data + p, chunk_size, 2);
|
||||
if (ret != chunk_size) {
|
||||
errx(EX_IOERR, "Failed to write whole chunk: "
|
||||
"%i of %i bytes", ret, chunk_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
if (!verbose)
|
||||
dfu_progress_bar("Download", dwElementSize, dwElementSize);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
dfuse_memcpy(unsigned char *dst, unsigned char **src, int *rem, int size)
|
||||
{
|
||||
if (size > *rem) {
|
||||
errx(EX_IOERR, "Corrupt DfuSe file: "
|
||||
"Cannot read %d bytes from %d bytes", size, *rem);
|
||||
}
|
||||
if (dst != NULL)
|
||||
memcpy(dst, *src, size);
|
||||
(*src) += size;
|
||||
(*rem) -= size;
|
||||
}
|
||||
|
||||
/* Download raw binary file to DfuSe device */
|
||||
int dfuse_do_bin_dnload(struct dfu_if *dif, int xfer_size,
|
||||
struct dfu_file *file, unsigned int start_address)
|
||||
{
|
||||
unsigned int dwElementAddress;
|
||||
unsigned int dwElementSize;
|
||||
unsigned char *data;
|
||||
int ret;
|
||||
|
||||
dwElementAddress = start_address;
|
||||
dwElementSize = file->size.total -
|
||||
file->size.suffix - file->size.prefix;
|
||||
|
||||
printf("Downloading to address = 0x%08x, size = %i\n",
|
||||
dwElementAddress, dwElementSize);
|
||||
|
||||
data = file->firmware + file->size.prefix;
|
||||
|
||||
ret = dfuse_dnload_element(dif, dwElementAddress, dwElementSize, data,
|
||||
xfer_size);
|
||||
if (ret != 0)
|
||||
goto out_free;
|
||||
|
||||
printf("File downloaded successfully\n");
|
||||
ret = dwElementSize;
|
||||
|
||||
out_free:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Parse a DfuSe file and download contents to device */
|
||||
int dfuse_do_dfuse_dnload(struct dfu_if *dif, int xfer_size,
|
||||
struct dfu_file *file)
|
||||
{
|
||||
uint8_t dfuprefix[11];
|
||||
uint8_t targetprefix[274];
|
||||
uint8_t elementheader[8];
|
||||
int image;
|
||||
int element;
|
||||
int bTargets;
|
||||
int bAlternateSetting;
|
||||
int dwNbElements;
|
||||
unsigned int dwElementAddress;
|
||||
unsigned int dwElementSize;
|
||||
uint8_t *data;
|
||||
int ret;
|
||||
int rem;
|
||||
int bFirstAddressSaved = 0;
|
||||
|
||||
rem = file->size.total - file->size.prefix - file->size.suffix;
|
||||
data = file->firmware + file->size.prefix;
|
||||
|
||||
/* Must be larger than a minimal DfuSe header and suffix */
|
||||
if (rem < (int)(sizeof(dfuprefix) +
|
||||
sizeof(targetprefix) + sizeof(elementheader))) {
|
||||
errx(EX_SOFTWARE, "File too small for a DfuSe file");
|
||||
}
|
||||
|
||||
dfuse_memcpy(dfuprefix, &data, &rem, sizeof(dfuprefix));
|
||||
|
||||
if (strncmp((char *)dfuprefix, "DfuSe", 5)) {
|
||||
errx(EX_IOERR, "No valid DfuSe signature");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (dfuprefix[5] != 0x01) {
|
||||
errx(EX_IOERR, "DFU format revision %i not supported",
|
||||
dfuprefix[5]);
|
||||
return -EINVAL;
|
||||
}
|
||||
bTargets = dfuprefix[10];
|
||||
printf("file contains %i DFU images\n", bTargets);
|
||||
|
||||
for (image = 1; image <= bTargets; image++) {
|
||||
printf("parsing DFU image %i\n", image);
|
||||
dfuse_memcpy(targetprefix, &data, &rem, sizeof(targetprefix));
|
||||
if (strncmp((char *)targetprefix, "Target", 6)) {
|
||||
errx(EX_IOERR, "No valid target signature");
|
||||
return -EINVAL;
|
||||
}
|
||||
bAlternateSetting = targetprefix[6];
|
||||
dwNbElements = quad2uint((unsigned char *)targetprefix + 270);
|
||||
printf("image for alternate setting %i, ", bAlternateSetting);
|
||||
printf("(%i elements, ", dwNbElements);
|
||||
printf("total size = %i)\n",
|
||||
quad2uint((unsigned char *)targetprefix + 266));
|
||||
if (bAlternateSetting != dif->altsetting)
|
||||
printf("Warning: Image does not match current alternate"
|
||||
" setting.\n"
|
||||
"Please rerun with the correct -a option setting"
|
||||
" to download this image!\n");
|
||||
for (element = 1; element <= dwNbElements; element++) {
|
||||
printf("parsing element %i, ", element);
|
||||
dfuse_memcpy(elementheader, &data, &rem, sizeof(elementheader));
|
||||
dwElementAddress =
|
||||
quad2uint((unsigned char *)elementheader);
|
||||
dwElementSize =
|
||||
quad2uint((unsigned char *)elementheader + 4);
|
||||
printf("address = 0x%08x, ", dwElementAddress);
|
||||
printf("size = %i\n", dwElementSize);
|
||||
|
||||
if (!bFirstAddressSaved) {
|
||||
bFirstAddressSaved = 1;
|
||||
dfuse_address = dwElementAddress;
|
||||
}
|
||||
/* sanity check */
|
||||
if ((int)dwElementSize > rem)
|
||||
errx(EX_SOFTWARE, "File too small for element size");
|
||||
|
||||
if (bAlternateSetting == dif->altsetting) {
|
||||
ret = dfuse_dnload_element(dif, dwElementAddress,
|
||||
dwElementSize, data, xfer_size);
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
/* advance read pointer */
|
||||
dfuse_memcpy(NULL, &data, &rem, dwElementSize);
|
||||
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (rem != 0)
|
||||
warnx("%d bytes leftover", rem);
|
||||
|
||||
printf("done parsing DfuSe file\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dfuse_do_dnload(struct dfu_if *dif, int xfer_size, struct dfu_file *file,
|
||||
const char *dfuse_options)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (dfuse_options)
|
||||
dfuse_parse_options(dfuse_options);
|
||||
mem_layout = parse_memory_layout((char *)dif->alt_name);
|
||||
if (!mem_layout) {
|
||||
errx(EX_IOERR, "Failed to parse memory layout");
|
||||
}
|
||||
if (dfuse_unprotect) {
|
||||
if (!dfuse_force) {
|
||||
errx(EX_IOERR, "The read unprotect command "
|
||||
"will erase the flash memory"
|
||||
"and can only be used with force\n");
|
||||
}
|
||||
dfuse_special_command(dif, 0, READ_UNPROTECT);
|
||||
printf("Device disconnects, erases flash and resets now\n");
|
||||
exit(0);
|
||||
}
|
||||
if (dfuse_mass_erase) {
|
||||
if (!dfuse_force) {
|
||||
errx(EX_IOERR, "The mass erase command "
|
||||
"can only be used with force");
|
||||
}
|
||||
printf("Performing mass erase, this can take a moment\n");
|
||||
dfuse_special_command(dif, 0, MASS_ERASE);
|
||||
}
|
||||
if (dfuse_address) {
|
||||
if (file->bcdDFU == 0x11a) {
|
||||
errx(EX_IOERR, "This is a DfuSe file, not "
|
||||
"meant for raw download");
|
||||
}
|
||||
ret = dfuse_do_bin_dnload(dif, xfer_size, file, dfuse_address);
|
||||
} else {
|
||||
if (file->bcdDFU != 0x11a) {
|
||||
warnx("Only DfuSe file version 1.1a is supported");
|
||||
errx(EX_IOERR, "(for raw binary download, use the "
|
||||
"--dfuse-address option)");
|
||||
}
|
||||
ret = dfuse_do_dfuse_dnload(dif, xfer_size, file);
|
||||
}
|
||||
free_segment_list(mem_layout);
|
||||
|
||||
dfu_abort_to_idle(dif);
|
||||
|
||||
if (dfuse_leave) {
|
||||
dfuse_special_command(dif, dfuse_address, SET_ADDRESS);
|
||||
dfuse_dnload_chunk(dif, NULL, 0, 2); /* Zero-size */
|
||||
}
|
||||
return ret;
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/* This implements the ST Microsystems DFU extensions (DfuSe)
|
||||
* as per the DfuSe 1.1a specification (Document UM0391)
|
||||
*
|
||||
* (C) 2010-2012 Tormod Volden <debian.tormod@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef DFUSE_H
|
||||
#define DFUSE_H
|
||||
|
||||
#include "dfu.h"
|
||||
|
||||
enum dfuse_command { SET_ADDRESS, ERASE_PAGE, MASS_ERASE, READ_UNPROTECT };
|
||||
|
||||
int dfuse_special_command(struct dfu_if *dif, unsigned int address,
|
||||
enum dfuse_command command);
|
||||
int dfuse_do_upload(struct dfu_if *dif, int xfer_size, int fd,
|
||||
const char *dfuse_options);
|
||||
int dfuse_do_dnload(struct dfu_if *dif, int xfer_size, struct dfu_file *file,
|
||||
const char *dfuse_options);
|
||||
|
||||
#endif /* DFUSE_H */
|
|
@ -0,0 +1,198 @@
|
|||
/*
|
||||
* Helper functions for reading the memory map of a device
|
||||
* following the ST DfuSe 1.1a specification.
|
||||
*
|
||||
* Copyright 2011-2014 Tormod Volden <debian.tormod@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "portable.h"
|
||||
#include "dfu_file.h"
|
||||
#include "dfuse_mem.h"
|
||||
|
||||
int add_segment(struct memsegment **segment_list, struct memsegment segment)
|
||||
{
|
||||
struct memsegment *new_element;
|
||||
|
||||
new_element = dfu_malloc(sizeof(struct memsegment));
|
||||
*new_element = segment;
|
||||
new_element->next = NULL;
|
||||
|
||||
if (*segment_list == NULL)
|
||||
/* list can be empty on first call */
|
||||
*segment_list = new_element;
|
||||
else {
|
||||
struct memsegment *next_element;
|
||||
|
||||
/* find last element in list */
|
||||
next_element = *segment_list;
|
||||
while (next_element->next != NULL)
|
||||
next_element = next_element->next;
|
||||
next_element->next = new_element;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct memsegment *find_segment(struct memsegment *segment_list,
|
||||
unsigned int address)
|
||||
{
|
||||
while (segment_list != NULL) {
|
||||
if (segment_list->start <= address &&
|
||||
segment_list->end >= address)
|
||||
return segment_list;
|
||||
segment_list = segment_list->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void free_segment_list(struct memsegment *segment_list)
|
||||
{
|
||||
struct memsegment *next_element;
|
||||
|
||||
while (segment_list->next != NULL) {
|
||||
next_element = segment_list->next;
|
||||
free(segment_list);
|
||||
segment_list = next_element;
|
||||
}
|
||||
free(segment_list);
|
||||
}
|
||||
|
||||
/* Parse memory map from interface descriptor string
|
||||
* encoded as per ST document UM0424 section 4.3.2.
|
||||
*/
|
||||
struct memsegment *parse_memory_layout(char *intf_desc)
|
||||
{
|
||||
|
||||
char multiplier, memtype;
|
||||
unsigned int address;
|
||||
int sectors, size;
|
||||
char *name, *typestring;
|
||||
int ret;
|
||||
int count = 0;
|
||||
char separator;
|
||||
int scanned;
|
||||
struct memsegment *segment_list = NULL;
|
||||
struct memsegment segment;
|
||||
|
||||
name = dfu_malloc(strlen(intf_desc));
|
||||
|
||||
ret = sscanf(intf_desc, "@%[^/]%n", name, &scanned);
|
||||
if (ret < 1) {
|
||||
free(name);
|
||||
warnx("Could not read name, sscanf returned %d", ret);
|
||||
return NULL;
|
||||
}
|
||||
printf("DfuSe interface name: \"%s\"\n", name);
|
||||
|
||||
intf_desc += scanned;
|
||||
typestring = dfu_malloc(strlen(intf_desc));
|
||||
|
||||
while (ret = sscanf(intf_desc, "/0x%x/%n", &address, &scanned),
|
||||
ret > 0) {
|
||||
|
||||
intf_desc += scanned;
|
||||
while (ret = sscanf(intf_desc, "%d*%d%c%[^,/]%n",
|
||||
§ors, &size, &multiplier, typestring,
|
||||
&scanned), ret > 2) {
|
||||
intf_desc += scanned;
|
||||
|
||||
count++;
|
||||
memtype = 0;
|
||||
if (ret == 4) {
|
||||
if (strlen(typestring) == 1
|
||||
&& typestring[0] != '/')
|
||||
memtype = typestring[0];
|
||||
else {
|
||||
warnx("Parsing type identifier '%s' "
|
||||
"failed for segment %i",
|
||||
typestring, count);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Quirk for STM32F4 devices */
|
||||
if (strcmp(name, "Device Feature") == 0)
|
||||
memtype = 'e';
|
||||
|
||||
switch (multiplier) {
|
||||
case 'B':
|
||||
break;
|
||||
case 'K':
|
||||
size *= 1024;
|
||||
break;
|
||||
case 'M':
|
||||
size *= 1024 * 1024;
|
||||
break;
|
||||
case 'a':
|
||||
case 'b':
|
||||
case 'c':
|
||||
case 'd':
|
||||
case 'e':
|
||||
case 'f':
|
||||
case 'g':
|
||||
if (!memtype) {
|
||||
warnx("Non-valid multiplier '%c', "
|
||||
"interpreted as type "
|
||||
"identifier instead",
|
||||
multiplier);
|
||||
memtype = multiplier;
|
||||
break;
|
||||
}
|
||||
/* fallthrough if memtype was already set */
|
||||
default:
|
||||
warnx("Non-valid multiplier '%c', "
|
||||
"assuming bytes", multiplier);
|
||||
}
|
||||
|
||||
if (!memtype) {
|
||||
warnx("No valid type for segment %d\n", count);
|
||||
continue;
|
||||
}
|
||||
|
||||
segment.start = address;
|
||||
segment.end = address + sectors * size - 1;
|
||||
segment.pagesize = size;
|
||||
segment.memtype = memtype & 7;
|
||||
add_segment(&segment_list, segment);
|
||||
|
||||
if (verbose)
|
||||
printf("Memory segment at 0x%08x %3d x %4d = "
|
||||
"%5d (%s%s%s)\n",
|
||||
address, sectors, size, sectors * size,
|
||||
memtype & DFUSE_READABLE ? "r" : "",
|
||||
memtype & DFUSE_ERASABLE ? "e" : "",
|
||||
memtype & DFUSE_WRITEABLE ? "w" : "");
|
||||
|
||||
address += sectors * size;
|
||||
|
||||
separator = *intf_desc;
|
||||
if (separator == ',')
|
||||
intf_desc += 1;
|
||||
else
|
||||
break;
|
||||
} /* while per segment */
|
||||
|
||||
} /* while per address */
|
||||
free(name);
|
||||
free(typestring);
|
||||
|
||||
return segment_list;
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/* Helper functions for reading the memory map in a device
|
||||
* following the ST DfuSe 1.1a specification.
|
||||
*
|
||||
* (C) 2011 Tormod Volden <debian.tormod@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef DFUSE_MEM_H
|
||||
#define DFUSE_MEM_H
|
||||
|
||||
#define DFUSE_READABLE 1
|
||||
#define DFUSE_ERASABLE 2
|
||||
#define DFUSE_WRITEABLE 4
|
||||
|
||||
struct memsegment {
|
||||
unsigned int start;
|
||||
unsigned int end;
|
||||
int pagesize;
|
||||
int memtype;
|
||||
struct memsegment *next;
|
||||
};
|
||||
|
||||
int add_segment(struct memsegment **list, struct memsegment new_element);
|
||||
|
||||
struct memsegment *find_segment(struct memsegment *list, unsigned int address);
|
||||
|
||||
void free_segment_list(struct memsegment *list);
|
||||
|
||||
struct memsegment *parse_memory_layout(char *intf_desc_str);
|
||||
|
||||
#endif /* DFUSE_MEM_H */
|
|
@ -0,0 +1,699 @@
|
|||
/*
|
||||
* dfu-util
|
||||
*
|
||||
* Copyright 2007-2008 by OpenMoko, Inc.
|
||||
* Copyright 2013-2014 Hans Petter Selasky <hps@bitfrost.no>
|
||||
*
|
||||
* Written by Harald Welte <laforge@openmoko.org>
|
||||
*
|
||||
* Based on existing code of dfu-programmer-0.4
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <getopt.h>
|
||||
#include <libusb.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "portable.h"
|
||||
#include "dfu.h"
|
||||
#include "usb_dfu.h"
|
||||
#include "dfu_file.h"
|
||||
#include "dfu_load.h"
|
||||
#include "dfu_util.h"
|
||||
#include "dfuse.h"
|
||||
#include "quirks.h"
|
||||
|
||||
#ifdef HAVE_USBPATH_H
|
||||
#include <usbpath.h>
|
||||
#endif
|
||||
|
||||
int verbose = 0;
|
||||
|
||||
struct dfu_if *dfu_root = NULL;
|
||||
|
||||
int match_bus = -1;
|
||||
int match_device = -1;
|
||||
int match_vendor = -1;
|
||||
int match_product = -1;
|
||||
int match_vendor_dfu = -1;
|
||||
int match_product_dfu = -1;
|
||||
int match_config_index = -1;
|
||||
int match_iface_index = -1;
|
||||
int match_iface_alt_index = -1;
|
||||
const char *match_iface_alt_name = NULL;
|
||||
const char *match_serial = NULL;
|
||||
const char *match_serial_dfu = NULL;
|
||||
|
||||
static int parse_match_value(const char *str, int default_value)
|
||||
{
|
||||
char *remainder;
|
||||
int value;
|
||||
|
||||
if (str == NULL) {
|
||||
value = default_value;
|
||||
} else if (*str == '*') {
|
||||
value = -1; /* Match anything */
|
||||
} else if (*str == '-') {
|
||||
value = 0x10000; /* Impossible vendor/product ID */
|
||||
} else {
|
||||
value = strtoul(str, &remainder, 16);
|
||||
if (remainder == str) {
|
||||
value = default_value;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
static void parse_vendprod(const char *str)
|
||||
{
|
||||
const char *comma;
|
||||
const char *colon;
|
||||
|
||||
/* Default to match any DFU device in runtime or DFU mode */
|
||||
match_vendor = -1;
|
||||
match_product = -1;
|
||||
match_vendor_dfu = -1;
|
||||
match_product_dfu = -1;
|
||||
|
||||
comma = strchr(str, ',');
|
||||
if (comma == str) {
|
||||
/* DFU mode vendor/product being specified without any runtime
|
||||
* vendor/product specification, so don't match any runtime device */
|
||||
match_vendor = match_product = 0x10000;
|
||||
} else {
|
||||
colon = strchr(str, ':');
|
||||
if (colon != NULL) {
|
||||
++colon;
|
||||
if ((comma != NULL) && (colon > comma)) {
|
||||
colon = NULL;
|
||||
}
|
||||
}
|
||||
match_vendor = parse_match_value(str, match_vendor);
|
||||
match_product = parse_match_value(colon, match_product);
|
||||
if (comma != NULL) {
|
||||
/* Both runtime and DFU mode vendor/product specifications are
|
||||
* available, so default DFU mode match components to the given
|
||||
* runtime match components */
|
||||
match_vendor_dfu = match_vendor;
|
||||
match_product_dfu = match_product;
|
||||
}
|
||||
}
|
||||
if (comma != NULL) {
|
||||
++comma;
|
||||
colon = strchr(comma, ':');
|
||||
if (colon != NULL) {
|
||||
++colon;
|
||||
}
|
||||
match_vendor_dfu = parse_match_value(comma, match_vendor_dfu);
|
||||
match_product_dfu = parse_match_value(colon, match_product_dfu);
|
||||
}
|
||||
}
|
||||
|
||||
static void parse_serial(char *str)
|
||||
{
|
||||
char *comma;
|
||||
|
||||
match_serial = str;
|
||||
comma = strchr(str, ',');
|
||||
if (comma == NULL) {
|
||||
match_serial_dfu = match_serial;
|
||||
} else {
|
||||
*comma++ = 0;
|
||||
match_serial_dfu = comma;
|
||||
}
|
||||
if (*match_serial == 0) match_serial = NULL;
|
||||
if (*match_serial_dfu == 0) match_serial_dfu = NULL;
|
||||
}
|
||||
|
||||
#ifdef HAVE_USBPATH_H
|
||||
|
||||
static int resolve_device_path(char *path)
|
||||
{
|
||||
int res;
|
||||
|
||||
res = usb_path2devnum(path);
|
||||
if (res < 0)
|
||||
return -EINVAL;
|
||||
if (!res)
|
||||
return 0;
|
||||
|
||||
match_bus = atoi(path);
|
||||
match_device = res;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else /* HAVE_USBPATH_H */
|
||||
|
||||
static int resolve_device_path(char *path)
|
||||
{
|
||||
(void)path; /* Eliminate unused variable warning */
|
||||
errx(EX_SOFTWARE, "USB device paths are not supported by this dfu-util.\n");
|
||||
}
|
||||
|
||||
#endif /* !HAVE_USBPATH_H */
|
||||
|
||||
static void help(void)
|
||||
{
|
||||
fprintf(stderr, "Usage: dfu-util [options] ...\n"
|
||||
" -h --help\t\t\tPrint this help message\n"
|
||||
" -V --version\t\t\tPrint the version number\n"
|
||||
" -v --verbose\t\t\tPrint verbose debug statements\n"
|
||||
" -l --list\t\t\tList currently attached DFU capable devices\n");
|
||||
fprintf(stderr, " -e --detach\t\t\tDetach currently attached DFU capable devices\n"
|
||||
" -E --detach-delay seconds\tTime to wait before reopening a device after detach\n"
|
||||
" -d --device <vendor>:<product>[,<vendor_dfu>:<product_dfu>]\n"
|
||||
"\t\t\t\tSpecify Vendor/Product ID(s) of DFU device\n"
|
||||
" -p --path <bus-port. ... .port>\tSpecify path to DFU device\n"
|
||||
" -c --cfg <config_nr>\t\tSpecify the Configuration of DFU device\n"
|
||||
" -i --intf <intf_nr>\t\tSpecify the DFU Interface number\n"
|
||||
" -S --serial <serial_string>[,<serial_string_dfu>]\n"
|
||||
"\t\t\t\tSpecify Serial String of DFU device\n"
|
||||
" -a --alt <alt>\t\tSpecify the Altsetting of the DFU Interface\n"
|
||||
"\t\t\t\tby name or by number\n");
|
||||
fprintf(stderr, " -t --transfer-size <size>\tSpecify the number of bytes per USB Transfer\n"
|
||||
" -U --upload <file>\t\tRead firmware from device into <file>\n"
|
||||
" -Z --upload-size <bytes>\tSpecify the expected upload size in bytes\n"
|
||||
" -D --download <file>\t\tWrite firmware from <file> into device\n"
|
||||
" -R --reset\t\t\tIssue USB Reset signalling once we're finished\n"
|
||||
" -s --dfuse-address <address>\tST DfuSe mode, specify target address for\n"
|
||||
"\t\t\t\traw file download or upload. Not applicable for\n"
|
||||
"\t\t\t\tDfuSe file (.dfu) downloads\n"
|
||||
);
|
||||
exit(EX_USAGE);
|
||||
}
|
||||
|
||||
static void print_version(void)
|
||||
{
|
||||
printf(PACKAGE_STRING "\n\n");
|
||||
printf("Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.\n"
|
||||
"Copyright 2010-2014 Tormod Volden and Stefan Schmidt\n"
|
||||
"This program is Free Software and has ABSOLUTELY NO WARRANTY\n"
|
||||
"Please report bugs to " PACKAGE_BUGREPORT "\n\n");
|
||||
}
|
||||
|
||||
static struct option opts[] = {
|
||||
{ "help", 0, 0, 'h' },
|
||||
{ "version", 0, 0, 'V' },
|
||||
{ "verbose", 0, 0, 'v' },
|
||||
{ "list", 0, 0, 'l' },
|
||||
{ "detach", 0, 0, 'e' },
|
||||
{ "detach-delay", 1, 0, 'E' },
|
||||
{ "device", 1, 0, 'd' },
|
||||
{ "path", 1, 0, 'p' },
|
||||
{ "configuration", 1, 0, 'c' },
|
||||
{ "cfg", 1, 0, 'c' },
|
||||
{ "interface", 1, 0, 'i' },
|
||||
{ "intf", 1, 0, 'i' },
|
||||
{ "altsetting", 1, 0, 'a' },
|
||||
{ "alt", 1, 0, 'a' },
|
||||
{ "serial", 1, 0, 'S' },
|
||||
{ "transfer-size", 1, 0, 't' },
|
||||
{ "upload", 1, 0, 'U' },
|
||||
{ "upload-size", 1, 0, 'Z' },
|
||||
{ "download", 1, 0, 'D' },
|
||||
{ "reset", 0, 0, 'R' },
|
||||
{ "dfuse-address", 1, 0, 's' },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int expected_size = 0;
|
||||
unsigned int transfer_size = 0;
|
||||
enum mode mode = MODE_NONE;
|
||||
struct dfu_status status;
|
||||
libusb_context *ctx;
|
||||
struct dfu_file file;
|
||||
char *end;
|
||||
int final_reset = 0;
|
||||
int ret;
|
||||
int dfuse_device = 0;
|
||||
int fd;
|
||||
const char *dfuse_options = NULL;
|
||||
int detach_delay = 5;
|
||||
uint16_t runtime_vendor;
|
||||
uint16_t runtime_product;
|
||||
|
||||
memset(&file, 0, sizeof(file));
|
||||
|
||||
/* make sure all prints are flushed */
|
||||
setvbuf(stdout, NULL, _IONBF, 0);
|
||||
|
||||
while (1) {
|
||||
int c, option_index = 0;
|
||||
c = getopt_long(argc, argv, "hVvleE:d:p:c:i:a:S:t:U:D:Rs:Z:", opts,
|
||||
&option_index);
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch (c) {
|
||||
case 'h':
|
||||
help();
|
||||
break;
|
||||
case 'V':
|
||||
mode = MODE_VERSION;
|
||||
break;
|
||||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
case 'l':
|
||||
mode = MODE_LIST;
|
||||
break;
|
||||
case 'e':
|
||||
mode = MODE_DETACH;
|
||||
match_iface_alt_index = 0;
|
||||
match_iface_index = 0;
|
||||
break;
|
||||
case 'E':
|
||||
detach_delay = atoi(optarg);
|
||||
break;
|
||||
case 'd':
|
||||
parse_vendprod(optarg);
|
||||
break;
|
||||
case 'p':
|
||||
/* Parse device path */
|
||||
ret = resolve_device_path(optarg);
|
||||
if (ret < 0)
|
||||
errx(EX_SOFTWARE, "Unable to parse '%s'", optarg);
|
||||
if (!ret)
|
||||
errx(EX_SOFTWARE, "Cannot find '%s'", optarg);
|
||||
break;
|
||||
case 'c':
|
||||
/* Configuration */
|
||||
match_config_index = atoi(optarg);
|
||||
break;
|
||||
case 'i':
|
||||
/* Interface */
|
||||
match_iface_index = atoi(optarg);
|
||||
break;
|
||||
case 'a':
|
||||
/* Interface Alternate Setting */
|
||||
match_iface_alt_index = strtoul(optarg, &end, 0);
|
||||
if (*end) {
|
||||
match_iface_alt_name = optarg;
|
||||
match_iface_alt_index = -1;
|
||||
}
|
||||
break;
|
||||
case 'S':
|
||||
parse_serial(optarg);
|
||||
break;
|
||||
case 't':
|
||||
transfer_size = atoi(optarg);
|
||||
break;
|
||||
case 'U':
|
||||
mode = MODE_UPLOAD;
|
||||
file.name = optarg;
|
||||
break;
|
||||
case 'Z':
|
||||
expected_size = atoi(optarg);
|
||||
break;
|
||||
case 'D':
|
||||
mode = MODE_DOWNLOAD;
|
||||
file.name = optarg;
|
||||
break;
|
||||
case 'R':
|
||||
final_reset = 1;
|
||||
break;
|
||||
case 's':
|
||||
dfuse_options = optarg;
|
||||
break;
|
||||
default:
|
||||
help();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
print_version();
|
||||
if (mode == MODE_VERSION) {
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (mode == MODE_NONE) {
|
||||
fprintf(stderr, "You need to specify one of -D or -U\n");
|
||||
help();
|
||||
}
|
||||
|
||||
if (match_config_index == 0) {
|
||||
/* Handle "-c 0" (unconfigured device) as don't care */
|
||||
match_config_index = -1;
|
||||
}
|
||||
|
||||
if (mode == MODE_DOWNLOAD) {
|
||||
dfu_load_file(&file, MAYBE_SUFFIX, MAYBE_PREFIX);
|
||||
/* If the user didn't specify product and/or vendor IDs to match,
|
||||
* use any IDs from the file suffix for device matching */
|
||||
if (match_vendor < 0 && file.idVendor != 0xffff) {
|
||||
match_vendor = file.idVendor;
|
||||
printf("Match vendor ID from file: %04x\n", match_vendor);
|
||||
}
|
||||
if (match_product < 0 && file.idProduct != 0xffff) {
|
||||
match_product = file.idProduct;
|
||||
printf("Match product ID from file: %04x\n", match_product);
|
||||
}
|
||||
}
|
||||
|
||||
ret = libusb_init(&ctx);
|
||||
if (ret)
|
||||
errx(EX_IOERR, "unable to initialize libusb: %i", ret);
|
||||
|
||||
if (verbose > 2) {
|
||||
libusb_set_debug(ctx, 255);
|
||||
}
|
||||
|
||||
probe_devices(ctx);
|
||||
|
||||
if (mode == MODE_LIST) {
|
||||
list_dfu_interfaces();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (dfu_root == NULL) {
|
||||
errx(EX_IOERR, "No DFU capable USB device available");
|
||||
} else if (dfu_root->next != NULL) {
|
||||
/* We cannot safely support more than one DFU capable device
|
||||
* with same vendor/product ID, since during DFU we need to do
|
||||
* a USB bus reset, after which the target device will get a
|
||||
* new address */
|
||||
errx(EX_IOERR, "More than one DFU capable USB device found! "
|
||||
"Try `--list' and specify the serial number "
|
||||
"or disconnect all but one device\n");
|
||||
}
|
||||
|
||||
/* We have exactly one device. Its libusb_device is now in dfu_root->dev */
|
||||
|
||||
printf("Opening DFU capable USB device...\n");
|
||||
ret = libusb_open(dfu_root->dev, &dfu_root->dev_handle);
|
||||
if (ret || !dfu_root->dev_handle)
|
||||
errx(EX_IOERR, "Cannot open device");
|
||||
|
||||
printf("ID %04x:%04x\n", dfu_root->vendor, dfu_root->product);
|
||||
|
||||
printf("Run-time device DFU version %04x\n",
|
||||
libusb_le16_to_cpu(dfu_root->func_dfu.bcdDFUVersion));
|
||||
|
||||
/* Transition from run-Time mode to DFU mode */
|
||||
if (!(dfu_root->flags & DFU_IFF_DFU)) {
|
||||
int err;
|
||||
/* In the 'first round' during runtime mode, there can only be one
|
||||
* DFU Interface descriptor according to the DFU Spec. */
|
||||
|
||||
/* FIXME: check if the selected device really has only one */
|
||||
|
||||
runtime_vendor = dfu_root->vendor;
|
||||
runtime_product = dfu_root->product;
|
||||
|
||||
printf("Claiming USB DFU Runtime Interface...\n");
|
||||
if (libusb_claim_interface(dfu_root->dev_handle, dfu_root->interface) < 0) {
|
||||
errx(EX_IOERR, "Cannot claim interface %d",
|
||||
dfu_root->interface);
|
||||
}
|
||||
|
||||
if (libusb_set_interface_alt_setting(dfu_root->dev_handle, dfu_root->interface, 0) < 0) {
|
||||
errx(EX_IOERR, "Cannot set alt interface zero");
|
||||
}
|
||||
|
||||
printf("Determining device status: ");
|
||||
|
||||
err = dfu_get_status(dfu_root, &status);
|
||||
if (err == LIBUSB_ERROR_PIPE) {
|
||||
printf("Device does not implement get_status, assuming appIDLE\n");
|
||||
status.bStatus = DFU_STATUS_OK;
|
||||
status.bwPollTimeout = 0;
|
||||
status.bState = DFU_STATE_appIDLE;
|
||||
status.iString = 0;
|
||||
} else if (err < 0) {
|
||||
errx(EX_IOERR, "error get_status");
|
||||
} else {
|
||||
printf("state = %s, status = %d\n",
|
||||
dfu_state_to_string(status.bState), status.bStatus);
|
||||
}
|
||||
milli_sleep(status.bwPollTimeout);
|
||||
|
||||
switch (status.bState) {
|
||||
case DFU_STATE_appIDLE:
|
||||
case DFU_STATE_appDETACH:
|
||||
printf("Device really in Runtime Mode, send DFU "
|
||||
"detach request...\n");
|
||||
if (dfu_detach(dfu_root->dev_handle,
|
||||
dfu_root->interface, 1000) < 0) {
|
||||
warnx("error detaching");
|
||||
}
|
||||
if (dfu_root->func_dfu.bmAttributes & USB_DFU_WILL_DETACH) {
|
||||
printf("Device will detach and reattach...\n");
|
||||
} else {
|
||||
printf("Resetting USB...\n");
|
||||
ret = libusb_reset_device(dfu_root->dev_handle);
|
||||
if (ret < 0 && ret != LIBUSB_ERROR_NOT_FOUND)
|
||||
errx(EX_IOERR, "error resetting "
|
||||
"after detach");
|
||||
}
|
||||
break;
|
||||
case DFU_STATE_dfuERROR:
|
||||
printf("dfuERROR, clearing status\n");
|
||||
if (dfu_clear_status(dfu_root->dev_handle,
|
||||
dfu_root->interface) < 0) {
|
||||
errx(EX_IOERR, "error clear_status");
|
||||
}
|
||||
/* fall through */
|
||||
default:
|
||||
warnx("WARNING: Runtime device already in DFU state ?!?");
|
||||
libusb_release_interface(dfu_root->dev_handle,
|
||||
dfu_root->interface);
|
||||
goto dfustate;
|
||||
}
|
||||
libusb_release_interface(dfu_root->dev_handle,
|
||||
dfu_root->interface);
|
||||
libusb_close(dfu_root->dev_handle);
|
||||
dfu_root->dev_handle = NULL;
|
||||
|
||||
if (mode == MODE_DETACH) {
|
||||
libusb_exit(ctx);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* keeping handles open might prevent re-enumeration */
|
||||
disconnect_devices();
|
||||
|
||||
milli_sleep(detach_delay * 1000);
|
||||
|
||||
/* Change match vendor and product to impossible values to force
|
||||
* only DFU mode matches in the following probe */
|
||||
match_vendor = match_product = 0x10000;
|
||||
|
||||
probe_devices(ctx);
|
||||
|
||||
if (dfu_root == NULL) {
|
||||
errx(EX_IOERR, "Lost device after RESET?");
|
||||
} else if (dfu_root->next != NULL) {
|
||||
errx(EX_IOERR, "More than one DFU capable USB device found! "
|
||||
"Try `--list' and specify the serial number "
|
||||
"or disconnect all but one device");
|
||||
}
|
||||
|
||||
/* Check for DFU mode device */
|
||||
if (!(dfu_root->flags | DFU_IFF_DFU))
|
||||
errx(EX_SOFTWARE, "Device is not in DFU mode");
|
||||
|
||||
printf("Opening DFU USB Device...\n");
|
||||
ret = libusb_open(dfu_root->dev, &dfu_root->dev_handle);
|
||||
if (ret || !dfu_root->dev_handle) {
|
||||
errx(EX_IOERR, "Cannot open device");
|
||||
}
|
||||
} else {
|
||||
/* we're already in DFU mode, so we can skip the detach/reset
|
||||
* procedure */
|
||||
/* If a match vendor/product was specified, use that as the runtime
|
||||
* vendor/product, otherwise use the DFU mode vendor/product */
|
||||
runtime_vendor = match_vendor < 0 ? dfu_root->vendor : match_vendor;
|
||||
runtime_product = match_product < 0 ? dfu_root->product : match_product;
|
||||
}
|
||||
|
||||
dfustate:
|
||||
#if 0
|
||||
printf("Setting Configuration %u...\n", dfu_root->configuration);
|
||||
if (libusb_set_configuration(dfu_root->dev_handle, dfu_root->configuration) < 0) {
|
||||
errx(EX_IOERR, "Cannot set configuration");
|
||||
}
|
||||
#endif
|
||||
printf("Claiming USB DFU Interface...\n");
|
||||
if (libusb_claim_interface(dfu_root->dev_handle, dfu_root->interface) < 0) {
|
||||
errx(EX_IOERR, "Cannot claim interface");
|
||||
}
|
||||
|
||||
printf("Setting Alternate Setting #%d ...\n", dfu_root->altsetting);
|
||||
if (libusb_set_interface_alt_setting(dfu_root->dev_handle, dfu_root->interface, dfu_root->altsetting) < 0) {
|
||||
errx(EX_IOERR, "Cannot set alternate interface");
|
||||
}
|
||||
|
||||
status_again:
|
||||
printf("Determining device status: ");
|
||||
if (dfu_get_status(dfu_root, &status ) < 0) {
|
||||
errx(EX_IOERR, "error get_status");
|
||||
}
|
||||
printf("state = %s, status = %d\n",
|
||||
dfu_state_to_string(status.bState), status.bStatus);
|
||||
|
||||
milli_sleep(status.bwPollTimeout);
|
||||
|
||||
switch (status.bState) {
|
||||
case DFU_STATE_appIDLE:
|
||||
case DFU_STATE_appDETACH:
|
||||
errx(EX_IOERR, "Device still in Runtime Mode!");
|
||||
break;
|
||||
case DFU_STATE_dfuERROR:
|
||||
printf("dfuERROR, clearing status\n");
|
||||
if (dfu_clear_status(dfu_root->dev_handle, dfu_root->interface) < 0) {
|
||||
errx(EX_IOERR, "error clear_status");
|
||||
}
|
||||
goto status_again;
|
||||
break;
|
||||
case DFU_STATE_dfuDNLOAD_IDLE:
|
||||
case DFU_STATE_dfuUPLOAD_IDLE:
|
||||
printf("aborting previous incomplete transfer\n");
|
||||
if (dfu_abort(dfu_root->dev_handle, dfu_root->interface) < 0) {
|
||||
errx(EX_IOERR, "can't send DFU_ABORT");
|
||||
}
|
||||
goto status_again;
|
||||
break;
|
||||
case DFU_STATE_dfuIDLE:
|
||||
printf("dfuIDLE, continuing\n");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (DFU_STATUS_OK != status.bStatus ) {
|
||||
printf("WARNING: DFU Status: '%s'\n",
|
||||
dfu_status_to_string(status.bStatus));
|
||||
/* Clear our status & try again. */
|
||||
if (dfu_clear_status(dfu_root->dev_handle, dfu_root->interface) < 0)
|
||||
errx(EX_IOERR, "USB communication error");
|
||||
if (dfu_get_status(dfu_root, &status) < 0)
|
||||
errx(EX_IOERR, "USB communication error");
|
||||
if (DFU_STATUS_OK != status.bStatus)
|
||||
errx(EX_SOFTWARE, "Status is not OK: %d", status.bStatus);
|
||||
|
||||
milli_sleep(status.bwPollTimeout);
|
||||
}
|
||||
|
||||
printf("DFU mode device DFU version %04x\n",
|
||||
libusb_le16_to_cpu(dfu_root->func_dfu.bcdDFUVersion));
|
||||
|
||||
if (dfu_root->func_dfu.bcdDFUVersion == libusb_cpu_to_le16(0x11a))
|
||||
dfuse_device = 1;
|
||||
|
||||
/* If not overridden by the user */
|
||||
if (!transfer_size) {
|
||||
transfer_size = libusb_le16_to_cpu(
|
||||
dfu_root->func_dfu.wTransferSize);
|
||||
if (transfer_size) {
|
||||
printf("Device returned transfer size %i\n",
|
||||
transfer_size);
|
||||
} else {
|
||||
errx(EX_IOERR, "Transfer size must be specified");
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_GETPAGESIZE
|
||||
/* autotools lie when cross-compiling for Windows using mingw32/64 */
|
||||
#ifndef __MINGW32__
|
||||
/* limitation of Linux usbdevio */
|
||||
if ((int)transfer_size > getpagesize()) {
|
||||
transfer_size = getpagesize();
|
||||
printf("Limited transfer size to %i\n", transfer_size);
|
||||
}
|
||||
#endif /* __MINGW32__ */
|
||||
#endif /* HAVE_GETPAGESIZE */
|
||||
|
||||
if (transfer_size < dfu_root->bMaxPacketSize0) {
|
||||
transfer_size = dfu_root->bMaxPacketSize0;
|
||||
printf("Adjusted transfer size to %i\n", transfer_size);
|
||||
}
|
||||
|
||||
switch (mode) {
|
||||
case MODE_UPLOAD:
|
||||
/* open for "exclusive" writing */
|
||||
fd = open(file.name, O_WRONLY | O_BINARY | O_CREAT | O_EXCL | O_TRUNC, 0666);
|
||||
if (fd < 0)
|
||||
err(EX_IOERR, "Cannot open file %s for writing", file.name);
|
||||
|
||||
if (dfuse_device || dfuse_options) {
|
||||
if (dfuse_do_upload(dfu_root, transfer_size, fd,
|
||||
dfuse_options) < 0)
|
||||
exit(1);
|
||||
} else {
|
||||
if (dfuload_do_upload(dfu_root, transfer_size,
|
||||
expected_size, fd) < 0) {
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
close(fd);
|
||||
break;
|
||||
|
||||
case MODE_DOWNLOAD:
|
||||
if (((file.idVendor != 0xffff && file.idVendor != runtime_vendor) ||
|
||||
(file.idProduct != 0xffff && file.idProduct != runtime_product)) &&
|
||||
((file.idVendor != 0xffff && file.idVendor != dfu_root->vendor) ||
|
||||
(file.idProduct != 0xffff && file.idProduct != dfu_root->product))) {
|
||||
errx(EX_IOERR, "Error: File ID %04x:%04x does "
|
||||
"not match device (%04x:%04x or %04x:%04x)",
|
||||
file.idVendor, file.idProduct,
|
||||
runtime_vendor, runtime_product,
|
||||
dfu_root->vendor, dfu_root->product);
|
||||
}
|
||||
if (dfuse_device || dfuse_options || file.bcdDFU == 0x11a) {
|
||||
if (dfuse_do_dnload(dfu_root, transfer_size, &file,
|
||||
dfuse_options) < 0)
|
||||
exit(1);
|
||||
} else {
|
||||
if (dfuload_do_dnload(dfu_root, transfer_size, &file) < 0)
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case MODE_DETACH:
|
||||
if (dfu_detach(dfu_root->dev_handle, dfu_root->interface, 1000) < 0) {
|
||||
warnx("can't detach");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
errx(EX_IOERR, "Unsupported mode: %u", mode);
|
||||
break;
|
||||
}
|
||||
|
||||
if (final_reset) {
|
||||
if (dfu_detach(dfu_root->dev_handle, dfu_root->interface, 1000) < 0) {
|
||||
/* Even if detach failed, just carry on to leave the
|
||||
device in a known state */
|
||||
warnx("can't detach");
|
||||
}
|
||||
printf("Resetting USB to switch back to runtime mode\n");
|
||||
ret = libusb_reset_device(dfu_root->dev_handle);
|
||||
if (ret < 0 && ret != LIBUSB_ERROR_NOT_FOUND) {
|
||||
errx(EX_IOERR, "error resetting after download");
|
||||
}
|
||||
}
|
||||
|
||||
libusb_close(dfu_root->dev_handle);
|
||||
dfu_root->dev_handle = NULL;
|
||||
libusb_exit(ctx);
|
||||
|
||||
return (0);
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
|
||||
#ifndef PORTABLE_H
|
||||
#define PORTABLE_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#else
|
||||
# define PACKAGE "dfu-util"
|
||||
# define PACKAGE_VERSION "0.8-msvc"
|
||||
# define PACKAGE_STRING "dfu-util 0.8-msvc"
|
||||
# define PACKAGE_BUGREPORT "dfu-util@lists.gnumonks.org"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#ifdef HAVE_FTRUNCATE
|
||||
# include <unistd.h>
|
||||
#else
|
||||
# include <io.h>
|
||||
#endif /* HAVE_FTRUNCATE */
|
||||
|
||||
#ifdef HAVE_NANOSLEEP
|
||||
# include <time.h>
|
||||
# define milli_sleep(msec) do {\
|
||||
if (msec) {\
|
||||
struct timespec nanosleepDelay = { (msec) / 1000, ((msec) % 1000) * 1000000 };\
|
||||
nanosleep(&nanosleepDelay, NULL);\
|
||||
} } while (0)
|
||||
#elif defined HAVE_WINDOWS_H
|
||||
# define milli_sleep(msec) do {\
|
||||
if (msec) {\
|
||||
Sleep(msec);\
|
||||
} } while (0)
|
||||
#else
|
||||
# error "Can't get no sleep! Please report"
|
||||
#endif /* HAVE_NANOSLEEP */
|
||||
|
||||
#ifdef HAVE_ERR
|
||||
# include <err.h>
|
||||
#else
|
||||
# include <errno.h>
|
||||
# include <string.h>
|
||||
# define warnx(...) do {\
|
||||
fprintf(stderr, __VA_ARGS__);\
|
||||
fprintf(stderr, "\n"); } while (0)
|
||||
# define errx(eval, ...) do {\
|
||||
warnx(__VA_ARGS__);\
|
||||
exit(eval); } while (0)
|
||||
# define warn(...) do {\
|
||||
fprintf(stderr, "%s: ", strerror(errno));\
|
||||
warnx(__VA_ARGS__); } while (0)
|
||||
# define err(eval, ...) do {\
|
||||
warn(__VA_ARGS__);\
|
||||
exit(eval); } while (0)
|
||||
#endif /* HAVE_ERR */
|
||||
|
||||
#ifdef HAVE_SYSEXITS_H
|
||||
# include <sysexits.h>
|
||||
#else
|
||||
# define EX_OK 0 /* successful termination */
|
||||
# define EX_USAGE 64 /* command line usage error */
|
||||
# define EX_SOFTWARE 70 /* internal software error */
|
||||
# define EX_IOERR 74 /* input/output error */
|
||||
#endif /* HAVE_SYSEXITS_H */
|
||||
|
||||
#ifndef O_BINARY
|
||||
# define O_BINARY 0
|
||||
#endif
|
||||
|
||||
#ifndef off_t
|
||||
# define off_t long int
|
||||
#endif
|
||||
|
||||
#endif /* PORTABLE_H */
|
|
@ -0,0 +1,176 @@
|
|||
/*
|
||||
* dfu-prefix
|
||||
*
|
||||
* Copyright 2011-2012 Stefan Schmidt <stefan@datenfreihafen.org>
|
||||
* Copyright 2013 Hans Petter Selasky <hps@bitfrost.no>
|
||||
* Copyright 2014 Uwe Bonnes <bon@elektron.ikp.physik.tu-darmstadt.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <getopt.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "portable.h"
|
||||
#include "dfu_file.h"
|
||||
|
||||
enum mode {
|
||||
MODE_NONE,
|
||||
MODE_ADD,
|
||||
MODE_DEL,
|
||||
MODE_CHECK
|
||||
};
|
||||
|
||||
int verbose;
|
||||
|
||||
static void help(void)
|
||||
{
|
||||
fprintf(stderr, "Usage: dfu-prefix [options] ...\n"
|
||||
" -h --help\t\t\tPrint this help message\n"
|
||||
" -V --version\t\t\tPrint the version number\n"
|
||||
" -c --check <file>\t\tCheck DFU prefix of <file>\n"
|
||||
" -D --delete <file>\t\tDelete DFU prefix from <file>\n"
|
||||
" -a --add <file>\t\tAdd DFU prefix to <file>\n"
|
||||
"In combination with -a:\n"
|
||||
);
|
||||
fprintf(stderr, " -s --stellaris-address <address> Add TI Stellaris address prefix to <file>\n"
|
||||
"In combination with -D or -c:\n"
|
||||
" -T --stellaris\t\tAct on TI Stellaris address prefix of <file>\n"
|
||||
"In combination with -a or -D or -c:\n"
|
||||
" -L --lpc-prefix\t\tUse NXP LPC DFU prefix format\n"
|
||||
);
|
||||
exit(EX_USAGE);
|
||||
}
|
||||
|
||||
static void print_version(void)
|
||||
{
|
||||
printf("dfu-prefix (%s) %s\n\n", PACKAGE, PACKAGE_VERSION);
|
||||
printf("Copyright 2011-2012 Stefan Schmidt, 2014 Uwe Bonnes\n"
|
||||
"This program is Free Software and has ABSOLUTELY NO WARRANTY\n"
|
||||
"Please report bugs to %s\n\n", PACKAGE_BUGREPORT);
|
||||
|
||||
}
|
||||
|
||||
static struct option opts[] = {
|
||||
{ "help", 0, 0, 'h' },
|
||||
{ "version", 0, 0, 'V' },
|
||||
{ "check", 1, 0, 'c' },
|
||||
{ "add", 1, 0, 'a' },
|
||||
{ "delete", 1, 0, 'D' },
|
||||
{ "stellaris-address", 1, 0, 's' },
|
||||
{ "stellaris", 0, 0, 'T' },
|
||||
{ "LPC", 0, 0, 'L' },
|
||||
};
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct dfu_file file;
|
||||
enum mode mode = MODE_NONE;
|
||||
enum prefix_type type = ZERO_PREFIX;
|
||||
uint32_t lmdfu_flash_address = 0;
|
||||
char *end;
|
||||
|
||||
/* make sure all prints are flushed */
|
||||
setvbuf(stdout, NULL, _IONBF, 0);
|
||||
|
||||
print_version();
|
||||
|
||||
memset(&file, 0, sizeof(file));
|
||||
|
||||
while (1) {
|
||||
int c, option_index = 0;
|
||||
c = getopt_long(argc, argv, "hVc:a:D:p:v:d:s:TL", opts,
|
||||
&option_index);
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch (c) {
|
||||
case 'h':
|
||||
help();
|
||||
break;
|
||||
case 'V':
|
||||
exit(0);
|
||||
break;
|
||||
case 'D':
|
||||
file.name = optarg;
|
||||
mode = MODE_DEL;
|
||||
break;
|
||||
case 'c':
|
||||
file.name = optarg;
|
||||
mode = MODE_CHECK;
|
||||
break;
|
||||
case 'a':
|
||||
file.name = optarg;
|
||||
mode = MODE_ADD;
|
||||
break;
|
||||
case 's':
|
||||
lmdfu_flash_address = strtoul(optarg, &end, 0);
|
||||
if (*end) {
|
||||
errx(EX_IOERR, "Invalid lmdfu "
|
||||
"address: %s", optarg);
|
||||
}
|
||||
/* fall-through */
|
||||
case 'T':
|
||||
type = LMDFU_PREFIX;
|
||||
break;
|
||||
case 'L':
|
||||
type = LPCDFU_UNENCRYPTED_PREFIX;
|
||||
break;
|
||||
default:
|
||||
help();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!file.name) {
|
||||
fprintf(stderr, "You need to specify a filename\n");
|
||||
help();
|
||||
}
|
||||
|
||||
switch(mode) {
|
||||
case MODE_ADD:
|
||||
if (type == ZERO_PREFIX)
|
||||
errx(EX_IOERR, "Prefix type must be specified");
|
||||
dfu_load_file(&file, MAYBE_SUFFIX, NO_PREFIX);
|
||||
file.lmdfu_address = lmdfu_flash_address;
|
||||
file.prefix_type = type;
|
||||
printf("Adding prefix to file\n");
|
||||
dfu_store_file(&file, file.size.suffix != 0, 1);
|
||||
break;
|
||||
|
||||
case MODE_CHECK:
|
||||
dfu_load_file(&file, MAYBE_SUFFIX, MAYBE_PREFIX);
|
||||
show_suffix_and_prefix(&file);
|
||||
if (type > ZERO_PREFIX && file.prefix_type != type)
|
||||
errx(EX_IOERR, "No prefix of requested type");
|
||||
break;
|
||||
|
||||
case MODE_DEL:
|
||||
dfu_load_file(&file, MAYBE_SUFFIX, NEEDS_PREFIX);
|
||||
if (type > ZERO_PREFIX && file.prefix_type != type)
|
||||
errx(EX_IOERR, "No prefix of requested type");
|
||||
printf("Removing prefix from file\n");
|
||||
/* if there was a suffix, rewrite it */
|
||||
dfu_store_file(&file, file.size.suffix != 0, 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
help();
|
||||
break;
|
||||
}
|
||||
return (0);
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Simple quirk system for dfu-util
|
||||
*
|
||||
* Copyright 2010-2014 Tormod Volden
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "quirks.h"
|
||||
|
||||
uint16_t get_quirks(uint16_t vendor, uint16_t product, uint16_t bcdDevice)
|
||||
{
|
||||
uint16_t quirks = 0;
|
||||
|
||||
/* Device returns bogus bwPollTimeout values */
|
||||
if ((vendor == VENDOR_OPENMOKO || vendor == VENDOR_FIC) &&
|
||||
product >= PRODUCT_FREERUNNER_FIRST &&
|
||||
product <= PRODUCT_FREERUNNER_LAST)
|
||||
quirks |= QUIRK_POLLTIMEOUT;
|
||||
|
||||
if (vendor == VENDOR_VOTI &&
|
||||
product == PRODUCT_OPENPCD)
|
||||
quirks |= QUIRK_POLLTIMEOUT;
|
||||
|
||||
/* Reports wrong DFU version in DFU descriptor */
|
||||
if (vendor == VENDOR_LEAFLABS &&
|
||||
product == PRODUCT_MAPLE3 &&
|
||||
bcdDevice == 0x0200)
|
||||
quirks |= QUIRK_FORCE_DFU11;
|
||||
|
||||
/* old devices(bcdDevice == 0) return bogus bwPollTimeout values */
|
||||
if (vendor == VENDOR_SIEMENS &&
|
||||
(product == PRODUCT_PXM40 || product == PRODUCT_PXM50) &&
|
||||
bcdDevice == 0)
|
||||
quirks |= QUIRK_POLLTIMEOUT;
|
||||
|
||||
/* M-Audio Transit returns bogus bwPollTimeout values */
|
||||
if (vendor == VENDOR_MIDIMAN &&
|
||||
product == PRODUCT_TRANSIT)
|
||||
quirks |= QUIRK_POLLTIMEOUT;
|
||||
|
||||
return (quirks);
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
#ifndef DFU_QUIRKS_H
|
||||
#define DFU_QUIRKS_H
|
||||
|
||||
#define VENDOR_OPENMOKO 0x1d50 /* Openmoko Freerunner / GTA02 */
|
||||
#define VENDOR_FIC 0x1457 /* Openmoko Freerunner / GTA02 */
|
||||
#define VENDOR_VOTI 0x16c0 /* OpenPCD Reader */
|
||||
#define VENDOR_LEAFLABS 0x1eaf /* Maple */
|
||||
#define VENDOR_SIEMENS 0x0908 /* Siemens AG */
|
||||
#define VENDOR_MIDIMAN 0x0763 /* Midiman */
|
||||
|
||||
#define PRODUCT_FREERUNNER_FIRST 0x5117
|
||||
#define PRODUCT_FREERUNNER_LAST 0x5126
|
||||
#define PRODUCT_OPENPCD 0x076b
|
||||
#define PRODUCT_MAPLE3 0x0003 /* rev 3 and 5 */
|
||||
#define PRODUCT_PXM40 0x02c4 /* Siemens AG, PXM 40 */
|
||||
#define PRODUCT_PXM50 0x02c5 /* Siemens AG, PXM 50 */
|
||||
#define PRODUCT_TRANSIT 0x2806 /* M-Audio Transit (Midiman) */
|
||||
|
||||
#define QUIRK_POLLTIMEOUT (1<<0)
|
||||
#define QUIRK_FORCE_DFU11 (1<<1)
|
||||
|
||||
/* Fallback value, works for OpenMoko */
|
||||
#define DEFAULT_POLLTIMEOUT 5
|
||||
|
||||
uint16_t get_quirks(uint16_t vendor, uint16_t product, uint16_t bcdDevice);
|
||||
|
||||
#endif /* DFU_QUIRKS_H */
|
|
@ -0,0 +1,176 @@
|
|||
/*
|
||||
* dfu-suffix
|
||||
*
|
||||
* Copyright 2011-2012 Stefan Schmidt <stefan@datenfreihafen.org>
|
||||
* Copyright 2013 Hans Petter Selasky <hps@bitfrost.no>
|
||||
* Copyright 2014 Tormod Volden <debian.tormod@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <getopt.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "portable.h"
|
||||
#include "dfu_file.h"
|
||||
|
||||
enum mode {
|
||||
MODE_NONE,
|
||||
MODE_ADD,
|
||||
MODE_DEL,
|
||||
MODE_CHECK
|
||||
};
|
||||
|
||||
int verbose;
|
||||
|
||||
static void help(void)
|
||||
{
|
||||
fprintf(stderr, "Usage: dfu-suffix [options] ...\n"
|
||||
" -h --help\t\t\tPrint this help message\n"
|
||||
" -V --version\t\t\tPrint the version number\n"
|
||||
" -c --check <file>\t\tCheck DFU suffix of <file>\n"
|
||||
" -a --add <file>\t\tAdd DFU suffix to <file>\n"
|
||||
" -D --delete <file>\t\tDelete DFU suffix from <file>\n"
|
||||
" -p --pid <productID>\t\tAdd product ID into DFU suffix in <file>\n"
|
||||
" -v --vid <vendorID>\t\tAdd vendor ID into DFU suffix in <file>\n"
|
||||
" -d --did <deviceID>\t\tAdd device ID into DFU suffix in <file>\n"
|
||||
" -S --spec <specID>\t\tAdd DFU specification ID into DFU suffix in <file>\n"
|
||||
);
|
||||
exit(EX_USAGE);
|
||||
}
|
||||
|
||||
static void print_version(void)
|
||||
{
|
||||
printf("dfu-suffix (%s) %s\n\n", PACKAGE, PACKAGE_VERSION);
|
||||
printf("Copyright 2011-2012 Stefan Schmidt, 2013-2014 Tormod Volden\n"
|
||||
"This program is Free Software and has ABSOLUTELY NO WARRANTY\n"
|
||||
"Please report bugs to %s\n\n", PACKAGE_BUGREPORT);
|
||||
|
||||
}
|
||||
|
||||
static struct option opts[] = {
|
||||
{ "help", 0, 0, 'h' },
|
||||
{ "version", 0, 0, 'V' },
|
||||
{ "check", 1, 0, 'c' },
|
||||
{ "add", 1, 0, 'a' },
|
||||
{ "delete", 1, 0, 'D' },
|
||||
{ "pid", 1, 0, 'p' },
|
||||
{ "vid", 1, 0, 'v' },
|
||||
{ "did", 1, 0, 'd' },
|
||||
{ "spec", 1, 0, 'S' },
|
||||
};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct dfu_file file;
|
||||
int pid, vid, did, spec;
|
||||
enum mode mode = MODE_NONE;
|
||||
|
||||
/* make sure all prints are flushed */
|
||||
setvbuf(stdout, NULL, _IONBF, 0);
|
||||
|
||||
print_version();
|
||||
|
||||
pid = vid = did = 0xffff;
|
||||
spec = 0x0100; /* Default to bcdDFU version 1.0 */
|
||||
memset(&file, 0, sizeof(file));
|
||||
|
||||
while (1) {
|
||||
int c, option_index = 0;
|
||||
c = getopt_long(argc, argv, "hVc:a:D:p:v:d:S:s:T", opts,
|
||||
&option_index);
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch (c) {
|
||||
case 'h':
|
||||
help();
|
||||
break;
|
||||
case 'V':
|
||||
exit(0);
|
||||
break;
|
||||
case 'D':
|
||||
file.name = optarg;
|
||||
mode = MODE_DEL;
|
||||
break;
|
||||
case 'p':
|
||||
pid = strtol(optarg, NULL, 16);
|
||||
break;
|
||||
case 'v':
|
||||
vid = strtol(optarg, NULL, 16);
|
||||
break;
|
||||
case 'd':
|
||||
did = strtol(optarg, NULL, 16);
|
||||
break;
|
||||
case 'S':
|
||||
spec = strtol(optarg, NULL, 16);
|
||||
break;
|
||||
case 'c':
|
||||
file.name = optarg;
|
||||
mode = MODE_CHECK;
|
||||
break;
|
||||
case 'a':
|
||||
file.name = optarg;
|
||||
mode = MODE_ADD;
|
||||
break;
|
||||
default:
|
||||
help();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!file.name) {
|
||||
fprintf(stderr, "You need to specify a filename\n");
|
||||
help();
|
||||
}
|
||||
|
||||
if (spec != 0x0100 && spec != 0x011a) {
|
||||
fprintf(stderr, "Only DFU specification 0x0100 and 0x011a supported\n");
|
||||
help();
|
||||
}
|
||||
|
||||
switch(mode) {
|
||||
case MODE_ADD:
|
||||
dfu_load_file(&file, NO_SUFFIX, MAYBE_PREFIX);
|
||||
file.idVendor = vid;
|
||||
file.idProduct = pid;
|
||||
file.bcdDevice = did;
|
||||
file.bcdDFU = spec;
|
||||
/* always write suffix, rewrite prefix if there was one */
|
||||
dfu_store_file(&file, 1, file.size.prefix != 0);
|
||||
printf("Suffix successfully added to file\n");
|
||||
break;
|
||||
|
||||
case MODE_CHECK:
|
||||
dfu_load_file(&file, NEEDS_SUFFIX, MAYBE_PREFIX);
|
||||
show_suffix_and_prefix(&file);
|
||||
break;
|
||||
|
||||
case MODE_DEL:
|
||||
dfu_load_file(&file, NEEDS_SUFFIX, MAYBE_PREFIX);
|
||||
dfu_store_file(&file, 0, file.size.prefix != 0);
|
||||
if (file.size.suffix) /* had a suffix */
|
||||
printf("Suffix successfully removed from file\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
help();
|
||||
break;
|
||||
}
|
||||
return (0);
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
#ifndef USB_DFU_H
|
||||
#define USB_DFU_H
|
||||
/* USB Device Firmware Update Implementation for OpenPCD
|
||||
* (C) 2006 by Harald Welte <hwelte@hmw-consulting.de>
|
||||
*
|
||||
* Protocol definitions for USB DFU
|
||||
*
|
||||
* This ought to be compliant to the USB DFU Spec 1.0 as available from
|
||||
* http://www.usb.org/developers/devclass_docs/usbdfu10.pdf
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define USB_DT_DFU 0x21
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma pack(push)
|
||||
# pragma pack(1)
|
||||
#endif /* _MSC_VER */
|
||||
struct usb_dfu_func_descriptor {
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bmAttributes;
|
||||
#define USB_DFU_CAN_DOWNLOAD (1 << 0)
|
||||
#define USB_DFU_CAN_UPLOAD (1 << 1)
|
||||
#define USB_DFU_MANIFEST_TOL (1 << 2)
|
||||
#define USB_DFU_WILL_DETACH (1 << 3)
|
||||
uint16_t wDetachTimeOut;
|
||||
uint16_t wTransferSize;
|
||||
uint16_t bcdDFUVersion;
|
||||
#ifdef _MSC_VER
|
||||
};
|
||||
# pragma pack(pop)
|
||||
#elif defined __GNUC__
|
||||
} __attribute__ ((packed));
|
||||
#else
|
||||
#warning "No way to pack struct on this compiler? This will break!"
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
#define USB_DT_DFU_SIZE 9
|
||||
|
||||
#define USB_TYPE_DFU (LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE)
|
||||
|
||||
/* DFU class-specific requests (Section 3, DFU Rev 1.1) */
|
||||
#define USB_REQ_DFU_DETACH 0x00
|
||||
#define USB_REQ_DFU_DNLOAD 0x01
|
||||
#define USB_REQ_DFU_UPLOAD 0x02
|
||||
#define USB_REQ_DFU_GETSTATUS 0x03
|
||||
#define USB_REQ_DFU_CLRSTATUS 0x04
|
||||
#define USB_REQ_DFU_GETSTATE 0x05
|
||||
#define USB_REQ_DFU_ABORT 0x06
|
||||
|
||||
/* DFU_GETSTATUS bStatus values (Section 6.1.2, DFU Rev 1.1) */
|
||||
#define DFU_STATUS_OK 0x00
|
||||
#define DFU_STATUS_errTARGET 0x01
|
||||
#define DFU_STATUS_errFILE 0x02
|
||||
#define DFU_STATUS_errWRITE 0x03
|
||||
#define DFU_STATUS_errERASE 0x04
|
||||
#define DFU_STATUS_errCHECK_ERASED 0x05
|
||||
#define DFU_STATUS_errPROG 0x06
|
||||
#define DFU_STATUS_errVERIFY 0x07
|
||||
#define DFU_STATUS_errADDRESS 0x08
|
||||
#define DFU_STATUS_errNOTDONE 0x09
|
||||
#define DFU_STATUS_errFIRMWARE 0x0a
|
||||
#define DFU_STATUS_errVENDOR 0x0b
|
||||
#define DFU_STATUS_errUSBR 0x0c
|
||||
#define DFU_STATUS_errPOR 0x0d
|
||||
#define DFU_STATUS_errUNKNOWN 0x0e
|
||||
#define DFU_STATUS_errSTALLEDPKT 0x0f
|
||||
|
||||
enum dfu_state {
|
||||
DFU_STATE_appIDLE = 0,
|
||||
DFU_STATE_appDETACH = 1,
|
||||
DFU_STATE_dfuIDLE = 2,
|
||||
DFU_STATE_dfuDNLOAD_SYNC = 3,
|
||||
DFU_STATE_dfuDNBUSY = 4,
|
||||
DFU_STATE_dfuDNLOAD_IDLE = 5,
|
||||
DFU_STATE_dfuMANIFEST_SYNC = 6,
|
||||
DFU_STATE_dfuMANIFEST = 7,
|
||||
DFU_STATE_dfuMANIFEST_WAIT_RST = 8,
|
||||
DFU_STATE_dfuUPLOAD_IDLE = 9,
|
||||
DFU_STATE_dfuERROR = 10
|
||||
};
|
||||
|
||||
#endif /* USB_DFU_H */
|
|
@ -0,0 +1,147 @@
|
|||
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en-US">
|
||||
|
||||
<head>
|
||||
<title>Building dfu-util from source</title>
|
||||
<meta http-equiv="content-type" content="application/xhtml+xml; charset=iso-8859-1" />
|
||||
<meta name="author" content="Tormod Volden" />
|
||||
<meta name="keywords" content="dfu-util, build, compile" />
|
||||
<meta name="description" content="How to build dfu-util from source" />
|
||||
<link rel="icon" type="image/png" href="favicon.ico" />
|
||||
<link rel="stylesheet" type="text/css" href="simple.css" media="screen, print" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="middlebox">
|
||||
<h1>How to build dfu-util from source</h1>
|
||||
|
||||
<h2>Prerequisites for building from git</h2>
|
||||
<h3>Mac OS X</h3>
|
||||
<p>
|
||||
First install MacPorts (and if you are on 10.6 or older, the Java Developer Package) and then run:
|
||||
</p>
|
||||
<pre>
|
||||
sudo port install libusb-devel git-core
|
||||
</pre>
|
||||
|
||||
<h3>FreeBSD</h3>
|
||||
<pre>
|
||||
sudo pkg_add -r git pkgconf
|
||||
</pre>
|
||||
|
||||
<h3>Ubuntu and Debian and derivatives</h3>
|
||||
<pre>
|
||||
sudo apt-get build-dep dfu-util
|
||||
sudo apt-get install libusb-1.0-0-dev
|
||||
</pre>
|
||||
|
||||
<h2>Get the source code and build it</h2>
|
||||
<p>
|
||||
The first time you will have to clone the git repository:
|
||||
</p>
|
||||
<pre>
|
||||
git clone git://gitorious.org/dfu-util/dfu-util.git
|
||||
cd dfu-util
|
||||
</pre>
|
||||
<p>
|
||||
If you later want to update to latest git version, just run this:
|
||||
</p>
|
||||
<pre>
|
||||
make maintainer-clean
|
||||
git pull
|
||||
</pre>
|
||||
<p>
|
||||
To build the source:
|
||||
</p>
|
||||
<pre>
|
||||
./autogen.sh
|
||||
./configure # on most systems
|
||||
make
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
If you are building on Mac OS X, replace the ./configure command with:
|
||||
</p>
|
||||
<pre>
|
||||
./configure --libdir=/opt/local/lib --includedir=/opt/local/include # on MacOSX only
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
Your dfu-util binary will be inside the src folder. Use it from there, or install it to /usr/local/bin by running "sudo make install".
|
||||
</p>
|
||||
|
||||
<h2>Cross-building for Windows</h2>
|
||||
|
||||
<p>
|
||||
Windows binaries can be built in a <a href="http://mingw.org/">MinGW</a>
|
||||
environment, on a Windows computer or cross-hosted in another OS.
|
||||
To build it on a Debian or Ubuntu host, first install build dependencies:
|
||||
</p>
|
||||
<pre>
|
||||
sudo apt-get build-dep libusb-1.0-0 dfu-util
|
||||
sudo apt-get install mingw32
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
The below example builds dfu-util 0.8 and libusb 1.0.19 from unpacked release
|
||||
tarballs. If you instead build from git, you will have to run "./autogen.sh"
|
||||
before running the "./configure" steps.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
mkdir -p build
|
||||
cd libusb-1.0.19
|
||||
PKG_CONFIG_PATH=$PWD/../build/lib/pkgconfig ./configure \
|
||||
--host=i586-mingw32msvc --prefix=$PWD/../build
|
||||
# WINVER workaround needed for 1.0.19 only
|
||||
make CFLAGS="-DWINVER=0x0501"
|
||||
make install
|
||||
cd ..
|
||||
|
||||
cd dfu-util-0.8
|
||||
PKG_CONFIG_PATH=$PWD/../build/lib/pkgconfig ./configure \
|
||||
--host=i586-mingw32msvc --prefix=$PWD/../build
|
||||
make
|
||||
make install
|
||||
cd ..
|
||||
</pre>
|
||||
The build files will now be in build/bin.
|
||||
<p>
|
||||
|
||||
<h2>Building on Windows using MinGW</h2>
|
||||
This assumes using release tarballs or having run ./autogen.sh on
|
||||
the git sources.
|
||||
<pre>
|
||||
cd libusb-1.0.19
|
||||
./configure --prefix=$HOME
|
||||
# WINVER workaround needed for 1.0.19 only
|
||||
# MKDIR_P setting should not really be needed...
|
||||
make CFLAGS="-DWINVER=0x0501" MKDIR_P="mkdir -p"
|
||||
make install
|
||||
cd ..
|
||||
|
||||
cd dfu-util-0.8
|
||||
./configure USB_CFLAGS="-I$HOME/include/libusb-1.0" \
|
||||
USB_LIBS="-L $HOME/lib -lusb-1.0" PKG_CONFIG=true
|
||||
make
|
||||
make install
|
||||
cd ..
|
||||
</pre>
|
||||
To link libusb statically into dfu-util.exe use instead of "make":
|
||||
<pre>
|
||||
make LDFLAGS=-static
|
||||
</pre>
|
||||
The built executables (and DLL) will now be under $HOME/bin.
|
||||
|
||||
<p>
|
||||
[<a href="index.html">Back to dfu-util main page</a>]
|
||||
</p>
|
||||
<p id="footer">
|
||||
©2014 Tormod Volden — Valid <a href="http://validator.w3.org/check?uri=referer" title="validate XHTML">XHTML</a> & <a href="http://jigsaw.w3.org/css-validator" title="validate CSS">CSS</a>
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,411 @@
|
|||
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<HTML><HEAD><TITLE>Man page of DFU-UTIL</TITLE>
|
||||
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
|
||||
</HEAD><BODY>
|
||||
<H1>DFU-UTIL(1)</H1>
|
||||
|
||||
<A NAME="lbAB"> </A>
|
||||
<H2>NAME</H2>
|
||||
|
||||
dfu-util - Device firmware update (DFU) USB programmer
|
||||
<A NAME="lbAC"> </A>
|
||||
<H2>SYNOPSIS</H2>
|
||||
|
||||
|
||||
<DL COMPACT>
|
||||
<DT>
|
||||
<B>dfu-util</B>
|
||||
|
||||
<B>-l </B>
|
||||
|
||||
[<B>-v</B>]
|
||||
|
||||
[<B>-d</B>
|
||||
|
||||
<I>vid:pid</I>[,<I>vid:pid</I>]]
|
||||
|
||||
[<B>-p</B>
|
||||
|
||||
<I>path</I>]
|
||||
|
||||
[<B>-c</B>
|
||||
|
||||
<I>configuration</I>]
|
||||
|
||||
[<B>-i</B>
|
||||
|
||||
<I>interface</I>]
|
||||
|
||||
[<B>-a</B>
|
||||
|
||||
<I>alt-intf</I>]
|
||||
|
||||
[<B>-S</B>
|
||||
|
||||
<I>serial</I>[,<I>serial</I>]]
|
||||
|
||||
|
||||
<DT>
|
||||
<B>dfu-util</B>
|
||||
|
||||
[<B>-v</B>]
|
||||
|
||||
[<B>-d</B>
|
||||
|
||||
<I>vid:pid</I>[,<I>vid:pid</I>]]
|
||||
|
||||
[<B>-p</B>
|
||||
|
||||
<I>path</I>]
|
||||
|
||||
[<B>-c</B>
|
||||
|
||||
<I>configuration</I>]
|
||||
|
||||
[<B>-i</B>
|
||||
|
||||
<I>interface</I>]
|
||||
|
||||
[<B>-a</B>
|
||||
|
||||
<I>alt-intf</I>]
|
||||
|
||||
[<B>-S</B>
|
||||
|
||||
<I>serial</I>[,<I>serial</I>]]
|
||||
|
||||
[<B>-t</B>
|
||||
|
||||
<I>size</I>]
|
||||
|
||||
[<B>-Z</B>
|
||||
|
||||
<I>size</I>]
|
||||
|
||||
[<B>-s</B>
|
||||
|
||||
<I>address</I>]
|
||||
|
||||
[<B>-R</B>]
|
||||
|
||||
[<B>-D</B>|<B>-U</B>
|
||||
|
||||
<I>file</I>]
|
||||
|
||||
|
||||
<DT>
|
||||
<B>dfu-util</B>
|
||||
|
||||
[<B>-hV</B>]
|
||||
|
||||
</DL>
|
||||
<A NAME="lbAD"> </A>
|
||||
<H2>DESCRIPTION</H2>
|
||||
|
||||
<B>dfu-util</B>
|
||||
|
||||
is a program that implements the host (computer) side of the USB DFU
|
||||
(Universal Serial Bus Device Firmware Upgrade) protocol.
|
||||
<P>
|
||||
dfu-util communicates with devices that implement the device side of the
|
||||
USB DFU protocol, and is often used to upgrade the firmware of such
|
||||
devices.
|
||||
<A NAME="lbAE"> </A>
|
||||
<H2>OPTIONS</H2>
|
||||
|
||||
<DL COMPACT>
|
||||
<DT><B>-l, --list</B>
|
||||
|
||||
<DD>
|
||||
List the currently attached DFU capable USB devices.
|
||||
<DT><B>-d, --device</B> [<I>Run-Time VENDOR</I>]:[<I>Run-Time PRODUCT</I>][,[<I>DFU Mode VENDOR</I>]:[<I>DFU Mode PRODUCT</I>]]
|
||||
|
||||
<DD>
|
||||
<DL COMPACT><DT><DD>
|
||||
Specify run-time and/or DFU mode vendor and/or product IDs of the DFU device
|
||||
to work with. <B>VENDOR</B> and <B>PRODUCT</B> are hexadecimal numbers (no prefix
|
||||
needed), "*" (match any), or "-" (match nothing). By default, any DFU capable
|
||||
device in either run-time or DFU mode will be considered.
|
||||
<P>
|
||||
If you only have one standards-compliant DFU device attached to your computer,
|
||||
this parameter is optional. However, as soon as you have multiple DFU devices
|
||||
connected, dfu-util will detect this and abort, asking you to specify which
|
||||
device to use.
|
||||
<P>
|
||||
If only run-time IDs are specified (e.g. "<B>--device 1457:51ab</B>"), then in
|
||||
addition to the specified run-time IDs, any DFU mode devices will also be
|
||||
considered. This is beneficial to allow a DFU capable device to be found
|
||||
again after a switch to DFU mode, since the vendor and/or product ID of a
|
||||
device usually changes in DFU mode.
|
||||
<P>
|
||||
If only DFU mode IDs are specified (e.g. "<B>--device ,951:26</B>"), then all
|
||||
run-time devices will be ignored, making it easy to target a specific device in
|
||||
DFU mode.
|
||||
<P>
|
||||
If both run-time and DFU mode IDs are specified (e.g. "<B>--device
|
||||
1457:51ab,:2bc</B>"), then unspecified DFU mode components will use the run-time
|
||||
value specified.
|
||||
<P>
|
||||
Examples:
|
||||
<DL COMPACT>
|
||||
<DT><B>--device 1457:51ab,951:26</B>
|
||||
|
||||
<DD>
|
||||
<BR>
|
||||
|
||||
Work with a device in run-time mode with
|
||||
vendor ID 0x1457 and product ID 0x51ab, or in DFU mode with vendor ID 0x0951
|
||||
and product ID 0x0026
|
||||
<P>
|
||||
<DT><B>--device 1457:51ab,:2bc</B>
|
||||
|
||||
<DD>
|
||||
<BR>
|
||||
|
||||
Work with a device in run-time mode with vendor ID 0x1457 and product ID
|
||||
0x51ab, or in DFU mode with vendor ID 0x1457 and product ID 0x02bc
|
||||
<P>
|
||||
<DT><B>--device 1457:51ab</B>
|
||||
|
||||
<DD>
|
||||
<BR>
|
||||
|
||||
Work with a device in run-time mode with vendor ID 0x1457 and product ID
|
||||
0x51ab, or in DFU mode with any vendor and product ID
|
||||
<P>
|
||||
<DT><B>--device ,951:26</B>
|
||||
|
||||
<DD>
|
||||
<BR>
|
||||
|
||||
Work with a device in DFU mode with vendor ID 0x0951 and product ID 0x0026
|
||||
<P>
|
||||
<DT><B>--device *,-</B>
|
||||
|
||||
<DD>
|
||||
<BR>
|
||||
|
||||
Work with any device in run-time mode, and ignore any device in DFU mode
|
||||
<P>
|
||||
<DT><B>--device ,</B>
|
||||
|
||||
<DD>
|
||||
<BR>
|
||||
|
||||
Ignore any device in run-time mode, and Work with any device in DFU mode
|
||||
</DL>
|
||||
</DL>
|
||||
|
||||
<DT><B>-p, --path</B> BUS-PORT. ... .PORT
|
||||
|
||||
<DD>
|
||||
Specify the path to the DFU device.
|
||||
<DT><B>-c, --cfg</B> CONFIG-NR
|
||||
|
||||
<DD>
|
||||
Specify the configuration of the DFU device. Note that this is only used for matching, the configuration is not set by dfu-util.
|
||||
<DT><B>-i, --intf</B> INTF-NR
|
||||
|
||||
<DD>
|
||||
Specify the DFU interface number.
|
||||
<DT><B>-a, --alt</B> ALT
|
||||
|
||||
<DD>
|
||||
Specify the altsetting of the DFU interface by name or by number.
|
||||
<DT><B>-S, --serial</B> [<I>Run-Time SERIAL</I>][,[<I>DFU Mode SERIAL</I>]]
|
||||
|
||||
<DD>
|
||||
Specify the run-time and DFU mode serial numbers used to further restrict
|
||||
device matches. If multiple, identical DFU devices are simultaneously
|
||||
connected to a system then vendor and product ID will be insufficient for
|
||||
targeting a single device. In this situation, it may be possible to use this
|
||||
parameter to specify a serial number which also must match.
|
||||
<P>
|
||||
If only a single serial number is specified, then the same serial number is
|
||||
used in both run-time and DFU mode. An empty serial number will match any
|
||||
serial number in the corresponding mode.
|
||||
<DT><B>-t, --transfer-size SIZE</B>
|
||||
|
||||
<DD>
|
||||
Specify the number of bytes per USB transfer. The optimal value is
|
||||
usually determined automatically so this option is rarely useful. If
|
||||
you need to use this option for a device, please report it as a bug.
|
||||
<DT><B>-Z, --upload-size SIZE</B>
|
||||
|
||||
<DD>
|
||||
Specify the expected upload size, in bytes.
|
||||
<DT><B>-U, --upload</B> FILE
|
||||
|
||||
<DD>
|
||||
Read firmware from device into
|
||||
<B>FILE</B>.
|
||||
|
||||
<DT><B>-D, --download</B> FILE
|
||||
|
||||
<DD>
|
||||
Write firmware from
|
||||
<B>FILE</B>
|
||||
|
||||
into device.
|
||||
<DT><B>-R, --reset</B>
|
||||
|
||||
<DD>
|
||||
Issue USB reset signalling after upload or download has finished.
|
||||
<DT><B>-s, --dfuse-address</B> address
|
||||
|
||||
<DD>
|
||||
Specify target address for raw binary download/upload on DfuSe devices. Do
|
||||
<B>not</B>
|
||||
|
||||
use this for downloading DfuSe (.dfu) files. Modifiers can be added
|
||||
to the address, separated by a colon, to perform special DfuSE commands such
|
||||
as "leave" DFU mode, "unprotect" and "mass-erase" flash memory.
|
||||
<DT><B>-v, --verbose</B>
|
||||
|
||||
<DD>
|
||||
Print more information about dfu-util's operation. A second
|
||||
<B>-v</B>
|
||||
|
||||
will turn on verbose logging of USB requests. Repeat this option to further
|
||||
increase verbosity.
|
||||
<DT><B>-h, --help</B>
|
||||
|
||||
<DD>
|
||||
Show a help text and exit.
|
||||
<DT><B>-V, --version</B>
|
||||
|
||||
<DD>
|
||||
Show version information and exit.
|
||||
</DL>
|
||||
<A NAME="lbAF"> </A>
|
||||
<H2>EXAMPLES</H2>
|
||||
|
||||
<A NAME="lbAG"> </A>
|
||||
<H3>Using dfu-util in the OpenMoko project</H3>
|
||||
|
||||
(with the Neo1973 hardware)
|
||||
<P>
|
||||
|
||||
Flashing the rootfs:
|
||||
<BR>
|
||||
|
||||
<B> $ dfu-util -a rootfs -R -D /path/to/openmoko-devel-image.jffs2</B>
|
||||
|
||||
<P>
|
||||
|
||||
Flashing the kernel:
|
||||
<BR>
|
||||
|
||||
<B> $ dfu-util -a kernel -R -D /path/to/uImage</B>
|
||||
|
||||
<P>
|
||||
|
||||
Flashing the bootloader:
|
||||
<BR>
|
||||
|
||||
<B> $ dfu-util -a u-boot -R -D /path/to/u-boot.bin</B>
|
||||
|
||||
<P>
|
||||
|
||||
Copying a kernel into RAM:
|
||||
<BR>
|
||||
|
||||
<B> $ dfu-util -a 0 -R -D /path/to/uImage</B>
|
||||
|
||||
<P>
|
||||
Once this has finished, the kernel will be available at the default load
|
||||
address of 0x32000000 in Neo1973 RAM.
|
||||
<B>Note:</B>
|
||||
|
||||
You cannot transfer more than 2MB of data into RAM using this method.
|
||||
<P>
|
||||
<A NAME="lbAH"> </A>
|
||||
<H3>Using dfu-util with a DfuSe device</H3>
|
||||
|
||||
<P>
|
||||
|
||||
Flashing a
|
||||
<B>.dfu</B>
|
||||
|
||||
(special DfuSe format) file to the device:
|
||||
<BR>
|
||||
|
||||
<B> $ dfu-util -a 0 -D /path/to/dfuse-image.dfu</B>
|
||||
|
||||
<P>
|
||||
|
||||
Reading out 1 KB of flash starting at address 0x8000000:
|
||||
<BR>
|
||||
|
||||
<B> $ dfu-util -a 0 -s 0x08000000:1024 -U newfile.bin</B>
|
||||
|
||||
<P>
|
||||
|
||||
Flashing a binary file to address 0x8004000 of device memory and
|
||||
ask the device to leave DFU mode:
|
||||
<BR>
|
||||
|
||||
<B> $ dfu-util -a 0 -s 0x08004000:leave -D /path/to/image.bin</B>
|
||||
|
||||
|
||||
<A NAME="lbAI"> </A>
|
||||
<H2>BUGS</H2>
|
||||
|
||||
Please report any bugs to the dfu-util mailing list at
|
||||
<B><A HREF="mailto:dfu-util@lists.gnumonks.org">dfu-util@lists.gnumonks.org</A></B>.
|
||||
|
||||
Please use the
|
||||
<I>--verbose</I> option (repeated as necessary) to provide more
|
||||
|
||||
information in your bug report.
|
||||
<A NAME="lbAJ"> </A>
|
||||
<H2>SEE ALSO</H2>
|
||||
|
||||
The dfu-util home page is
|
||||
<B><A HREF="http://dfu-util.gnumonks.org">http://dfu-util.gnumonks.org</A></B>
|
||||
|
||||
<A NAME="lbAK"> </A>
|
||||
<H2>HISTORY</H2>
|
||||
|
||||
dfu-util was originally written for the OpenMoko project by
|
||||
Weston Schmidt <<A HREF="mailto:weston_schmidt@yahoo.com">weston_schmidt@yahoo.com</A>> and
|
||||
Harald Welte <<A HREF="mailto:hwelte@hmw-consulting.de">hwelte@hmw-consulting.de</A>>. Over time, nearly complete
|
||||
support of DFU 1.0, DFU 1.1 and DfuSe ("1.1a") has been added.
|
||||
<A NAME="lbAL"> </A>
|
||||
<H2>LICENCE</H2>
|
||||
|
||||
<B>dfu-util</B>
|
||||
|
||||
is covered by the GNU General Public License (GPL), version 2 or later.
|
||||
<A NAME="lbAM"> </A>
|
||||
<H2>COPYRIGHT</H2>
|
||||
|
||||
This manual page was originally written by Uwe Hermann <<A HREF="mailto:uwe@hermann-uwe.de">uwe@hermann-uwe.de</A>>,
|
||||
and is now part of the dfu-util project.
|
||||
<P>
|
||||
|
||||
<HR>
|
||||
<A NAME="index"> </A><H2>Index</H2>
|
||||
<DL>
|
||||
<DT><A HREF="#lbAB">NAME</A><DD>
|
||||
<DT><A HREF="#lbAC">SYNOPSIS</A><DD>
|
||||
<DT><A HREF="#lbAD">DESCRIPTION</A><DD>
|
||||
<DT><A HREF="#lbAE">OPTIONS</A><DD>
|
||||
<DT><A HREF="#lbAF">EXAMPLES</A><DD>
|
||||
<DL>
|
||||
<DT><A HREF="#lbAG">Using dfu-util in the OpenMoko project</A><DD>
|
||||
<DT><A HREF="#lbAH">Using dfu-util with a DfuSe device</A><DD>
|
||||
</DL>
|
||||
<DT><A HREF="#lbAI">BUGS</A><DD>
|
||||
<DT><A HREF="#lbAJ">SEE ALSO</A><DD>
|
||||
<DT><A HREF="#lbAK">HISTORY</A><DD>
|
||||
<DT><A HREF="#lbAL">LICENCE</A><DD>
|
||||
<DT><A HREF="#lbAM">COPYRIGHT</A><DD>
|
||||
</DL>
|
||||
<HR>
|
||||
This document was created by man2html,
|
||||
using the doc/dfu-util.1 manual page from dfu-util 0.8.<BR>
|
||||
Time: 14:40:57 GMT, September 13, 2014
|
||||
</BODY>
|
||||
</HTML>
|
|
@ -0,0 +1,135 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en-US">
|
||||
|
||||
<head>
|
||||
<title>DfuSe and dfu-util</title>
|
||||
<meta http-equiv="content-type" content="application/xhtml+xml; charset=iso-8859-1" />
|
||||
<meta name="author" content="Tormod Volden" />
|
||||
<meta name="keywords" content="dfu-util, DfuSe, ST DFU extensions" />
|
||||
<meta name="description" content="How to use dfu-util with DfuSe devices" />
|
||||
<link rel="icon" type="image/png" href="favicon.ico" />
|
||||
<link rel="stylesheet" type="text/css" href="simple.css" media="screen, print" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="middlebox">
|
||||
<h1>Using dfu-util with DfuSe devices</h1>
|
||||
<h2>DfuSe</h2>
|
||||
<p>
|
||||
DfuSe (DFU with ST Microsystems extensions) is a protocol based on
|
||||
DFU 1.1. However, in expanding the functionality of the DFU protocol,
|
||||
ST Microsystems broke all compatibility with the DFU 1.1 standard.
|
||||
DfuSe devices report the DFU version as "1.1a".
|
||||
</p>
|
||||
<p>
|
||||
DfuSe can be used to download firmware and other data
|
||||
from a host computer to a conforming device (or upload in the
|
||||
opposite direction) over USB similar to standard DFU.
|
||||
</p>
|
||||
<p>
|
||||
The main difference from standard DFU is that the target address in
|
||||
the device (flash) memory is specified by the host, so that a
|
||||
download can be performed to parts of the device memory. The host
|
||||
program is also responsible for erasing flash pages before they
|
||||
are written to.
|
||||
</p>
|
||||
<h2>.dfu files</h2>
|
||||
<p>
|
||||
A special file format is defined by ST Microsystems to carry firmware
|
||||
for DfuSe devices. The file contains target information such as address
|
||||
and alternate interface information in addition to the binary data.
|
||||
Several blocks of binary data can be combined in one .dfu file.
|
||||
</p>
|
||||
<h2>Alternate interfaces</h2>
|
||||
<p>
|
||||
Different memory locations of the device may have different
|
||||
characteristics that the host program (dfu-util) has to take
|
||||
into considerations, such as flash memory page size, read-only
|
||||
versus read-write segments, the need to erase, and so on.
|
||||
These parameters are reported by the device in the string
|
||||
descriptors meant for describing the USB interfaces.
|
||||
The host program decodes these strings to build a memory map of
|
||||
the device. Different memory units or address spaces are listed
|
||||
in separate alternate interface settings that must be selected
|
||||
according to the memory unit to access.
|
||||
</p>
|
||||
<p>
|
||||
Note that dfu-util leaves it to the user to select alternate
|
||||
interface. When parsing a .dfu file it will skip file segments
|
||||
not matching the selected alternate interface. Also, some
|
||||
DfuSe device firmware implementations ignore the setting of
|
||||
alternate interface and deduct the memory unit from the
|
||||
address, since they have no address space overlap.
|
||||
</p>
|
||||
<h2>DfuSe special commands</h2>
|
||||
<p>
|
||||
DfuSe special commands are used by the host program during normal
|
||||
downloads or uploads, such as SET_ADDRESS and ERASE_PAGE. Also
|
||||
the normal DFU_DNLOAD and DFU_UPLOAD commands have special
|
||||
implementations in DfuSe.
|
||||
Many DfuSe devices also support commands to leave DFU mode,
|
||||
read unprotect the flash memory or mass erase the flash memory.
|
||||
dfu-util (from version 0.7)
|
||||
supports adding "leave", "unprotect", or "mass-erase"
|
||||
to the -s option argument to send such requests in combination
|
||||
with a download request. These modifiers are separated with a colon.
|
||||
</p>
|
||||
<p>
|
||||
Some DfuSe devices have their DfuSe bootloader running from flash
|
||||
memory. Erasing the whole flash memory would therefore destroy
|
||||
the DfuSe bootloader itself and practically brick the device
|
||||
for most users. Any use of modifiers such as "unprotect"
|
||||
and "mass-erase" therefore needs to be combined with the "force"
|
||||
modifer. This is not included in the examples, to not encourage
|
||||
ignorant users to copy and paste such instructions and shoot
|
||||
themselves in the foot.
|
||||
</p>
|
||||
<p>
|
||||
Devices based on for instance STM32F103 all run the bootloader
|
||||
from flash, since there is no USB bootloader in ROM.
|
||||
</p>
|
||||
<p>
|
||||
For instance STM32F107, STM32F2xx and STM32F4xx devices have a
|
||||
DfuSe bootloader in ROM, so the flash can be erased while
|
||||
keeping the device available for USB DFU transfers as long
|
||||
as the device designers use this built-in bootloader and have
|
||||
not implemented another DfuSe bootloader in flash that the user is
|
||||
dependent upon.
|
||||
</p>
|
||||
<p>
|
||||
Well-written bootloaders running from flash will report their
|
||||
own memory region as read-only and not eraseable, but this does
|
||||
not prevent dfu-util from sending a "unprotect" or "mass-erase"
|
||||
request which overrides this, if the user insists.
|
||||
</p>
|
||||
<h2>Example usage</h2>
|
||||
<p>
|
||||
Flashing a .dfu (special DfuSe format) file to the device:
|
||||
</p>
|
||||
<pre>
|
||||
$ dfu-util -a 0 -D /path/to/dfuse-image.dfu
|
||||
</pre>
|
||||
<p>
|
||||
Reading out 1 KB of flash starting at address 0x8000000:
|
||||
</p>
|
||||
<pre>
|
||||
$ dfu-util -a 0 -s 0x08000000:1024 -U newfile.bin
|
||||
</pre>
|
||||
<p>
|
||||
Flashing a binary file to address 0x8004000 of device memory and ask
|
||||
the device to leave DFU mode:
|
||||
</p>
|
||||
<pre>
|
||||
$ dfu-util -a 0 -s 0x08004000:leave -D /path/to/image.bin
|
||||
</pre>
|
||||
<p>
|
||||
[<a href="index.html">Back to dfu-util main page</a>]
|
||||
</p>
|
||||
<p id="footer">
|
||||
©2012 Tormod Volden — Valid <a href="http://validator.w3.org/check?uri=referer" title="validate XHTML">XHTML</a> & <a href="http://jigsaw.w3.org/css-validator" title="validate CSS">CSS</a>
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,119 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en-US">
|
||||
|
||||
<head>
|
||||
<title>dfu-util Homepage</title>
|
||||
<meta http-equiv="content-type" content="application/xhtml+xml; charset=iso-8859-1" />
|
||||
<meta name="author" content="Stefan Schmidt" />
|
||||
<meta name="keywords" content="dfu-util, DFU, Device Firmware Upgrade, linux" />
|
||||
<meta name="description" content="dfu-util Project Homepage" />
|
||||
<link rel="icon" type="image/png" href="favicon.ico" />
|
||||
<link rel="stylesheet" type="text/css" href="simple.css" media="screen, print" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="middlebox">
|
||||
<h1>dfu-util - Device Firmware Upgrade Utilities</h1>
|
||||
<h2>Description</h2>
|
||||
<p>
|
||||
dfu-util is a host side implementation of the <a
|
||||
href="http://www.usb.org/developers/devclass_docs/usbdfu10.pdf"
|
||||
title="DFU revision 1.0"> DFU 1.0</a> and <a
|
||||
href="http://www.usb.org/developers/devclass_docs/DFU_1.1.pdf"
|
||||
title="DFU revision 1.1">DFU 1.1</a> specifications of the USB forum.
|
||||
|
||||
DFU is intended to download and upload firmware to/from devices connected
|
||||
over USB. It ranges from small devices like micro-controller boards
|
||||
to mobile phones. Using dfu-util you can download firmware to your
|
||||
DFU-enabled device or upload firmware from it. dfu-util has been
|
||||
tested with the Openmoko Neo1973 and Freerunner and many other devices.
|
||||
</p>
|
||||
<p>
|
||||
See the <a href="dfu-util.1.html">manual page</a> for examples of use.
|
||||
</p>
|
||||
<h2>Supported Devices</h2>
|
||||
<ul>
|
||||
<li><a href="http://wiki.openmoko.org/wiki/Neo_1973">Openmoko Neo1973</a></li>
|
||||
<li><a href="http://wiki.openmoko.org/wiki/Neo_FreeRunner">Openmoko Freerunner</a></li>
|
||||
<li><a href="http://leaflabs.com/Maple">Leaflabs Maple</a></li>
|
||||
<li><a href="http://www.openpcd.org/">OpenPCD and OpenPICC</a></li>
|
||||
<li><a href="http://downloads.qi-hardware.com/people/werner/wpan/web/">Qi Hardware ATUSB</a> (use dfu-util 0.7)</li>
|
||||
<li><a href="http://bb.osmocom.org/trac/wiki/SIMtrace">Osmocom SIMtrace</a></li>
|
||||
<li>Many devices using the <a href="dfuse.html">DfuSe DFU extension</a> from ST, for instance:
|
||||
<ul>
|
||||
<li><a
|
||||
href="http://www.seeedstudio.com/depot/micro-digital-storage-oscilloscopedso-nano-p-512.html">DSO nano</a></li>
|
||||
<li><a href="https://www.spark.io/">Spark Core</a></li>
|
||||
<li>STM32F2/F3/F4 built-in bootloader</li>
|
||||
<li>Some STR750-based devices, e.g. USB2CAN</li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
<h2>Releases</h2>
|
||||
<p>
|
||||
Releases of the dfu-util software can be found in the <a
|
||||
href="http://dfu-util.gnumonks.org/releases/" title="Releases">
|
||||
releases</a> folder.
|
||||
The current release is 0.8.
|
||||
</p>
|
||||
<p>
|
||||
We offer binaries for Microsoft Windows and some other platforms.
|
||||
dfu-util uses libusb 1.0 to access your device, so
|
||||
on Windows you have to register the device with the WinUSB driver
|
||||
(alternatively libusb-win32 or libusbK), please see the <a
|
||||
href="https://github.com/libusbx/libusbx/wiki/Windows-Backend">libusbx wiki</a>
|
||||
for more details.
|
||||
</p>
|
||||
<p>
|
||||
Mac OS X users can also get dfu-util from <a href="http://brew.sh/">Homebrew</a> with "brew install dfu-util" or from <a href="http://www.macports.org/">MacPorts</a>.
|
||||
</p>
|
||||
<p>
|
||||
Most Linux distributions ship dfu-util in binary packages for those
|
||||
who do not want to compile dfu-util from source.
|
||||
On Debian, Ubuntu, Fedora and Gentoo you can install it through the
|
||||
normal software package tools. For other distributions
|
||||
(namely OpenSuSe, Mandriva, and CentOS) Holger Freyther was kind enough to
|
||||
provide binary packages through the <a
|
||||
href="https://build.opensuse.org/package/show?package=dfu-util&project=home%3Azecke23">Open Build Service</a>.
|
||||
</p>
|
||||
<h2>Development</h2>
|
||||
<p>
|
||||
Development happens in a GIT repository. Browse it via the <a
|
||||
href="https://gitorious.org/dfu-util" title="Git repository">web
|
||||
interface</a> or clone it with:
|
||||
</p>
|
||||
<pre>
|
||||
git clone git://gitorious.org/dfu-util/dfu-util.git
|
||||
</pre>
|
||||
<p>
|
||||
See our <a href="build.html">build instructions</a> for how to
|
||||
build the source on different platforms.
|
||||
</p>
|
||||
<h2>License</h2>
|
||||
<p>
|
||||
This software is licensed under the <a
|
||||
href="http://www.gnu.org/licenses/gpl-2.0.html"> GPL version 2</a>.
|
||||
</p>
|
||||
<h2>Contact</h2>
|
||||
<p>
|
||||
If you have questions about the development or use of dfu-util please
|
||||
send an e-mail to our dedicated <a
|
||||
href="https://lists.gnumonks.org/mailman/listinfo/dfu-util">
|
||||
mailing list for dfu-util</a>.
|
||||
</p>
|
||||
<h2>People</h2>
|
||||
<p>
|
||||
dfu-util was originally written by <a href="http://gnumonks.org/users/laforge/">
|
||||
Harald Welte</a> partially based on code from <a
|
||||
href="http://dfu-programmer.sourceforge.net/">
|
||||
dfu-programmer 0.4</a> and is currently maintained by <a
|
||||
href="http://www.datenfreihafen.org/">Stefan Schmidt</a> and
|
||||
Tormod Volden.
|
||||
</p>
|
||||
<p id="footer">
|
||||
©2010-2012 Stefan Schmidt — Valid <a href="http://validator.w3.org/check?uri=referer" title="validate XHTML">XHTML</a> & <a href="http://jigsaw.w3.org/css-validator" title="validate CSS">CSS</a>
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,56 @@
|
|||
body {
|
||||
margin: 10px;
|
||||
font-size: 0.82em;
|
||||
background-color: #EEE;
|
||||
}
|
||||
|
||||
h1 {
|
||||
clear: both;
|
||||
padding: 0 0 12px 0;
|
||||
margin: 0;
|
||||
font-size: 2em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h2 {
|
||||
clear: both;
|
||||
margin: 0;
|
||||
font-size: 1.5em;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
h3 {
|
||||
clear: both;
|
||||
margin: 15px 0 0 0;
|
||||
font-size: 1.0em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
p {
|
||||
line-height: 20px;
|
||||
padding: 8px 0 8px 0;
|
||||
margin: 0;
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
background-color: #CCC;
|
||||
padding: 3px;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
background-color: #DDD;
|
||||
}
|
||||
|
||||
#middlebox {
|
||||
width: 600px;
|
||||
margin: 0px auto;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
#footer {
|
||||
height: 100px;
|
||||
padding: 28px 3px 0 0;
|
||||
margin: 20px 0 20px 0;
|
||||
}
|
Loading…
Reference in New Issue