Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Ardupilot
GitHub Repository: Ardupilot/ardupilot
Path: blob/master/Tools/ardupilotwaf/embed.py
9673 views
1
#!/usr/bin/env python3
2
3
# flake8: noqa
4
5
'''
6
script to create ap_romfs_embedded.h from a set of static files
7
8
Andrew Tridgell
9
May 2017
10
'''
11
12
import os, sys, zlib
13
14
def write_encode(out, s):
15
out.write(s.encode())
16
17
def embed_file(out, f, idx, embedded_name, uncompressed):
18
'''embed one file'''
19
try:
20
contents = open(f,'rb').read()
21
except Exception:
22
raise Exception("Failed to embed %s" % f)
23
24
if embedded_name.endswith("bootloader.bin"):
25
# round size to a multiple of 32 bytes for bootloader, this ensures
26
# it can be flashed on a STM32H7 chip
27
blen = len(contents)
28
pad = (32 - (blen % 32)) % 32
29
if pad != 0:
30
contents += bytes([0xff]*pad)
31
print("Padded %u bytes for %s to %u" % (pad, embedded_name, len(contents)))
32
33
crc = crc32(contents)
34
write_encode(out, '__EXTFLASHFUNC__ static const uint8_t ap_romfs_%u[] = {' % idx)
35
36
if uncompressed:
37
# terminate if there's not already an existing null. we don't add it to
38
# the contents to avoid storing the wrong length
39
null_terminate = 0 not in contents
40
b = contents
41
else:
42
# compress it (max level, max window size, raw stream, max mem usage)
43
z = zlib.compressobj(level=9, method=zlib.DEFLATED, wbits=-15, memLevel=9)
44
b = z.compress(contents)
45
b += z.flush()
46
# decompressed data will be null terminated at runtime, nothing to do here
47
null_terminate = False
48
49
if len(b) == 0:
50
raise ValueError(f"Zero-length ROMFS contents ({embedded_name}) not permitted")
51
write_encode(out, ",".join(str(c) for c in b))
52
if null_terminate:
53
write_encode(out, ",0")
54
write_encode(out, '};\n\n');
55
return crc, len(contents)
56
57
def crc32(bytes, crc=0):
58
'''crc32 equivalent to crc32_small() from AP_Math/crc.cpp'''
59
for byte in bytes:
60
crc ^= byte
61
for i in range(8):
62
mask = (-(crc & 1)) & 0xFFFFFFFF
63
crc >>= 1
64
crc ^= (0xEDB88320 & mask)
65
return crc
66
67
def create_embedded_h(filename, files, uncompressed=False):
68
'''create a ap_romfs_embedded.h file'''
69
70
done = set()
71
72
out = open(filename, "wb")
73
write_encode(out, '''// generated embedded files for AP_ROMFS\n\n''')
74
75
# remove duplicates and sort
76
files = sorted(list(set(files)))
77
crc = {}
78
decompressed_size = {}
79
for i in range(len(files)):
80
(name, filename) = files[i]
81
if name in done:
82
print("Duplicate ROMFS file %s" % name)
83
sys.exit(1)
84
done.add(name)
85
try:
86
crc[filename], decompressed_size[filename] = embed_file(out, filename, i, name, uncompressed)
87
except Exception as e:
88
print(e)
89
return False
90
91
write_encode(out, '''const AP_ROMFS::embedded_file AP_ROMFS::files[] = {\n''')
92
93
for i in range(len(files)):
94
(name, filename) = files[i]
95
if uncompressed:
96
ustr = ' (uncompressed)'
97
else:
98
ustr = ''
99
print("Embedding file %s:%s%s" % (name, filename, ustr))
100
write_encode(out, '{ "%s", sizeof(ap_romfs_%u), %d, 0x%08x, ap_romfs_%u },\n' % (
101
name, i, decompressed_size[filename], crc[filename], i))
102
write_encode(out, '};\n')
103
out.close()
104
return True
105
106
if __name__ == '__main__':
107
import sys
108
flist = []
109
for i in range(1, len(sys.argv)):
110
f = sys.argv[i]
111
flist.append((f, f))
112
create_embedded_h("/tmp/ap_romfs_embedded.h", flist)
113
114