summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorDamien <damien.p.george@gmail.com>2013-12-20 12:07:50 +0000
committerDamien <damien.p.george@gmail.com>2013-12-20 12:07:50 +0000
commitf0d09406381eea6d3fe1764eb63978d7a6974b21 (patch)
treeee7e822ef3455ea775b2aa8c3e34f4611308345c
parent5e6ebd77d268ed064c96d0f4bdb6ba5d57228844 (diff)
downloadmicropython-f0d09406381eea6d3fe1764eb63978d7a6974b21.tar.gz
micropython-f0d09406381eea6d3fe1764eb63978d7a6974b21.zip
Add tools/dfu.py, and use it in stm/Makefile.
-rw-r--r--stm/Makefile3
-rwxr-xr-xtools/dfu.py121
2 files changed, 123 insertions, 1 deletions
diff --git a/stm/Makefile b/stm/Makefile
index 3d2dc42302..a5d0aad8a0 100644
--- a/stm/Makefile
+++ b/stm/Makefile
@@ -3,6 +3,7 @@ FATFSSRC=fatfs
CC3KSRC=cc3k
PYSRC=../py
BUILD=build
+DFU=../tools/dfu.py
AS = arm-none-eabi-as
CC = arm-none-eabi-gcc
@@ -116,7 +117,7 @@ OBJ = $(addprefix $(BUILD)/, $(SRC_C:.c=.o) $(SRC_S:.s=.o) $(PY_O) $(SRC_FATFS:.
all: $(BUILD) $(BUILD)/flash.dfu
$(BUILD)/flash.dfu: $(BUILD)/flash0.bin $(BUILD)/flash1.bin
- python2 ~/stm/dfu/dfu.py -b 0x08000000:$(BUILD)/flash0.bin -b 0x08020000:$(BUILD)/flash1.bin $@
+ python2 $(DFU) -b 0x08000000:$(BUILD)/flash0.bin -b 0x08020000:$(BUILD)/flash1.bin $@
$(BUILD)/flash0.bin: $(BUILD)/flash.elf
arm-none-eabi-objcopy -O binary -j .isr_vector $^ $@
diff --git a/tools/dfu.py b/tools/dfu.py
new file mode 100755
index 0000000000..875cc5c6e9
--- /dev/null
+++ b/tools/dfu.py
@@ -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)