Skip to content

Commit f42cf4b

Browse files
committed
fix uf2conv.py
1 parent 3c27998 commit f42cf4b

File tree

1 file changed

+92
-70
lines changed

1 file changed

+92
-70
lines changed

tools/uf2conv/uf2conv.py

Lines changed: 92 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
#!/usr/bin/python
2-
1+
#!/usr/bin/env python3
32
import sys
43
import struct
54
import subprocess
@@ -8,6 +7,7 @@
87
import os.path
98
import argparse
109

10+
1111
UF2_MAGIC_START0 = 0x0A324655 # "UF2\n"
1212
UF2_MAGIC_START1 = 0x9E5D5157 # Randomly selected
1313
UF2_MAGIC_END = 0x0AB16F30 # Ditto
@@ -26,27 +26,31 @@
2626
appstartaddr = 0x2000
2727
familyid = 0x0
2828

29-
def isUF2(buf):
29+
30+
def is_uf2(buf):
3031
w = struct.unpack("<II", buf[0:8])
3132
return w[0] == UF2_MAGIC_START0 and w[1] == UF2_MAGIC_START1
3233

33-
def isHEX(buf):
34-
w = buf[0:30]
35-
if w[0] == ':' and re.match("^[:0-9a-fA-F\r\n]+$", buf):
34+
def is_hex(buf):
35+
try:
36+
w = buf[0:30].decode("utf-8")
37+
except UnicodeDecodeError:
38+
return False
39+
if w[0] == ':' and re.match(b"^[:0-9a-fA-F\r\n]+$", buf):
3640
return True
3741
return False
3842

39-
def convertFromUF2(buf):
43+
def convert_from_uf2(buf):
4044
global appstartaddr
41-
numblocks = len(buf) / 512
45+
numblocks = len(buf) // 512
4246
curraddr = None
43-
outp = ""
44-
for blockno in range(0, numblocks):
47+
outp = b""
48+
for blockno in range(numblocks):
4549
ptr = blockno * 512
4650
block = buf[ptr:ptr + 512]
47-
hd = struct.unpack("<IIIIIIII", block[0:32])
51+
hd = struct.unpack(b"<IIIIIIII", block[0:32])
4852
if hd[0] != UF2_MAGIC_START0 or hd[1] != UF2_MAGIC_START1:
49-
print "Skipping block at " + ptr + "; bad magic"
53+
print("Skipping block at " + ptr + "; bad magic")
5054
continue
5155
if hd[2] & 1:
5256
# NO-flash flag set; skip block
@@ -67,57 +71,63 @@ def convertFromUF2(buf):
6771
assert False, "Non-word padding size at " + ptr
6872
while padding > 0:
6973
padding -= 4
70-
outp += "\x00\x00\x00\x00"
74+
outp += b"\x00\x00\x00\x00"
7175
outp += block[32 : 32 + datalen]
7276
curraddr = newaddr + datalen
7377
return outp
7478

75-
def convertToUF2(fileContent):
79+
def convert_to_carray(file_content):
80+
outp = "const unsigned char bindata[] __attribute__((aligned(16))) = {"
81+
for i in range(len(file_content)):
82+
if i % 16 == 0:
83+
outp += "\n"
84+
outp += "0x%02x, " % ord(file_content[i])
85+
outp += "\n};\n"
86+
return outp
87+
88+
def convert_to_uf2(file_content):
7689
global familyid
77-
datapadding = ""
90+
datapadding = b""
7891
while len(datapadding) < 512 - 256 - 32 - 4:
79-
datapadding += "\x00\x00\x00\x00"
80-
numblocks = (len(fileContent) + 255) / 256
81-
outp = ""
82-
for blockno in range(0, numblocks):
92+
datapadding += b"\x00\x00\x00\x00"
93+
numblocks = (len(file_content) + 255) // 256
94+
outp = b""
95+
for blockno in range(numblocks):
8396
ptr = 256 * blockno
84-
chunk = fileContent[ptr:ptr + 256]
97+
chunk = file_content[ptr:ptr + 256]
8598
flags = 0x0
8699
if familyid:
87100
flags |= 0x2000
88-
hd = struct.pack("<IIIIIIII",
89-
UF2_MAGIC_START0, UF2_MAGIC_START1,
101+
hd = struct.pack(b"<IIIIIIII",
102+
UF2_MAGIC_START0, UF2_MAGIC_START1,
90103
flags, ptr + appstartaddr, 256, blockno, numblocks, familyid)
91104
while len(chunk) < 256:
92-
chunk += "\x00"
93-
block = hd + chunk + datapadding + struct.pack("<I", UF2_MAGIC_END)
105+
chunk += b"\x00"
106+
block = hd + chunk + datapadding + struct.pack(b"<I", UF2_MAGIC_END)
94107
assert len(block) == 512
95108
outp += block
96109
return outp
97110

98111
class Block:
99112
def __init__(self, addr):
100113
self.addr = addr
101-
self.bytes = []
102-
for i in range(0, 256):
103-
self.bytes.append(0)
114+
self.bytes = bytearray(256)
104115

105116
def encode(self, blockno, numblocks):
106117
global familyid
107118
flags = 0x0
108119
if familyid:
109120
flags |= 0x2000
110-
hd = struct.pack("<IIIIIIII",
111-
UF2_MAGIC_START0, UF2_MAGIC_START1,
121+
hd = struct.pack("<IIIIIIII",
122+
UF2_MAGIC_START0, UF2_MAGIC_START1,
112123
flags, self.addr, 256, blockno, numblocks, familyid)
113-
for i in range(0, 256):
114-
hd += chr(self.bytes[i])
124+
hd += self.bytes[0:256]
115125
while len(hd) < 512 - 4:
116-
hd += "\x00"
126+
hd += b"\x00"
117127
hd += struct.pack("<I", UF2_MAGIC_END)
118128
return hd
119-
120-
def convertFromHexToUF2(buf):
129+
130+
def convert_from_hex_to_uf2(buf):
121131
global appstartaddr
122132
appstartaddr = None
123133
upper = 0
@@ -152,16 +162,17 @@ def convertFromHexToUF2(buf):
152162
addr += 1
153163
i += 1
154164
numblocks = len(blocks)
155-
resfile = ""
165+
resfile = b""
156166
for i in range(0, numblocks):
157167
resfile += blocks[i].encode(i, numblocks)
158168
return resfile
159169

160-
161-
def getdrives():
170+
def get_drives():
162171
drives = []
163172
if sys.platform == "win32":
164-
r = subprocess.check_output(["wmic", "PATH", "Win32_LogicalDisk", "get", "DeviceID,", "VolumeName,", "FileSystem,", "DriveType"])
173+
r = subprocess.check_output(["wmic", "PATH", "Win32_LogicalDisk",
174+
"get", "DeviceID,", "VolumeName,",
175+
"FileSystem,", "DriveType"])
165176
for line in r.split('\n'):
166177
words = re.split('\s+', line)
167178
if len(words) >= 3 and words[1] == "2" and words[2] == "FAT":
@@ -176,36 +187,41 @@ def getdrives():
176187
rootpath = tmp
177188
for d in os.listdir(rootpath):
178189
drives.append(os.path.join(rootpath, d))
179-
180-
def hasInfo(d):
190+
191+
192+
def has_info(d):
181193
try:
182194
return os.path.isfile(d + INFO_FILE)
183195
except:
184196
return False
185-
186-
return filter(hasInfo, drives)
187197

188-
def boardID(path):
198+
return list(filter(has_info, drives))
199+
200+
201+
def board_id(path):
189202
with open(path + INFO_FILE, mode='r') as file:
190-
fileContent = file.read()
191-
return re.search("Board-ID: ([^\r\n]*)", fileContent).group(1)
192-
193-
def listdrives():
194-
for d in getdrives():
195-
print d, boardID(d)
203+
file_content = file.read()
204+
return re.search("Board-ID: ([^\r\n]*)", file_content).group(1)
205+
206+
207+
def list_drives():
208+
for d in get_drives():
209+
print(d, board_id(d))
210+
196211

197-
def writeFile(name, buf):
212+
def write_file(name, buf):
198213
with open(name, "wb") as f:
199214
f.write(buf)
200-
print "Wrote %d bytes to %s." % (len(buf), name)
215+
print("Wrote %d bytes to %s." % (len(buf), name))
216+
201217

202218
def main():
203219
global appstartaddr, familyid
204220
def error(msg):
205-
print msg
221+
print(msg)
206222
sys.exit(1)
207223
parser = argparse.ArgumentParser(description='Convert to UF2 or flash directly.')
208-
parser.add_argument('input', metavar='INPUT', type=str, nargs='?',
224+
parser.add_argument('input', metavar='INPUT', type=str, nargs='?',
209225
help='input file (HEX, BIN or UF2)')
210226
parser.add_argument('-b' , '--base', dest='base', type=str,
211227
default="0x2000",
@@ -221,6 +237,8 @@ def error(msg):
221237
parser.add_argument('-f' , '--family', dest='family', type=str,
222238
default="0x0",
223239
help='specify familyID - number or name (default: 0x0)')
240+
parser.add_argument('-C' , '--carray', action='store_true',
241+
help='convert binary file to a C array, not UF2')
224242
args = parser.parse_args()
225243
appstartaddr = int(args.base, 0)
226244

@@ -233,38 +251,42 @@ def error(msg):
233251
error("Family ID needs to be a number or one of: " + ", ".join(families.keys()))
234252

235253
if args.list:
236-
listdrives()
254+
list_drives()
237255
else:
238256
if not args.input:
239257
error("Need input file")
240-
with open(args.input, mode='rb') as file:
241-
inpbuf = file.read()
242-
fromUF2 = isUF2(inpbuf)
258+
with open(args.input, mode='rb') as f:
259+
inpbuf = f.read()
260+
from_uf2 = is_uf2(inpbuf)
243261
ext = "uf2"
244-
if fromUF2:
245-
outbuf = convertFromUF2(inpbuf)
262+
if from_uf2:
263+
outbuf = convert_from_uf2(inpbuf)
246264
ext = "bin"
247-
elif isHEX(inpbuf):
248-
outbuf = convertFromHexToUF2(inpbuf)
265+
elif is_hex(inpbuf):
266+
outbuf = convert_from_hex_to_uf2(inpbuf.decode("utf-8"))
267+
elif args.carray:
268+
outbuf = convert_to_carray(inpbuf)
269+
ext = "h"
249270
else:
250-
outbuf = convertToUF2(inpbuf)
251-
print "Converting to %s, output size: %d, start address: 0x%x" % (ext, len(outbuf), appstartaddr)
252-
271+
outbuf = convert_to_uf2(inpbuf)
272+
print("Converting to %s, output size: %d, start address: 0x%x" %
273+
(ext, len(outbuf), appstartaddr))
253274
if args.convert:
254275
drives = []
255276
if args.output == None:
256277
args.output = "flash." + ext
257278
else:
258-
drives = getdrives()
259-
279+
drives = get_drives()
280+
260281
if args.output:
261-
writeFile(args.output, outbuf)
282+
write_file(args.output, outbuf)
262283
else:
263284
if len(drives) == 0:
264285
error("No drive to deploy.")
265286
for d in drives:
266-
print "Flashing %s (%s)" % (d, boardID(d))
267-
writeFile(outbuf, d + "/NEW.UF2")
287+
print("Flashing %s (%s)" % (d, board_id(d)))
288+
write_file(d + "/NEW.UF2", outbuf)
289+
268290

269291
if __name__ == "__main__":
270-
main()
292+
main()

0 commit comments

Comments
 (0)