0
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
1 #!/usr/bin/env python3
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
2
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
3 '''
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
4 Combine the MicroPython firmware with a Python script and produce a hex file
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
5 ready for uploading to the micro:bit.
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
6
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
7 Usage: ./makecombinedhex.py <firmware.hex> <script.py> [-o <combined.hex>]
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
8
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
9 Output goes to stdout if no filename is given.
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
10 '''
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
11
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
12 import sys
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
13 import argparse
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
14 import hexlifyscript
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
15
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
16 def get_largest_addr(hexfile):
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
17 largest_addr = 0
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
18 for line in hexfile:
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
19 count = int(line[1:3], 16)
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
20 addr = int(line[3:7], 16)
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
21 type = int(line[7:9], 16)
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
22 if count == 2 and type == 4: # ext linear addr
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
23 page = int(line[9:13], 16) << 16
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
24 elif type == 0: # data
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
25 largest_addr = max(largest_addr, page + addr + count)
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
26 return largest_addr
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
27
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
28 if __name__ == '__main__':
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
29 arg_parser = argparse.ArgumentParser(description='Produce combined hex firmware for the micro:bit.')
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
30 arg_parser.add_argument('-o', '--output', default=sys.stdout, type=argparse.FileType('wt'), help='output file (default is stdout)')
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
31 arg_parser.add_argument('firmware', nargs=1, help='input MicroPython firmware')
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
32 arg_parser.add_argument('script', nargs=1, help='input Python script')
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
33 args = arg_parser.parse_args()
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
34
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
35 # read in the firmware
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
36 with open(args.firmware[0], 'rt') as f:
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
37 firmware = f.readlines()
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
38
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
39 # check the firmware is not too large
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
40 if get_largest_addr(firmware) > hexlifyscript.SCRIPT_ADDR:
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
41 raise Exception('firmware overflows into script region')
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
42
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
43 # hexlify the script
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
44 with open(args.script[0], 'rb') as f:
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
45 script = hexlifyscript.hexlify_script(f.read())
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
46
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
47 # print head of firmware
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
48 for line in firmware[:-2]:
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
49 print(line, end='', file=args.output)
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
50
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
51 # print script
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
52 print(script, file=args.output)
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
53
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
54 # print tail of firmware
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
55 print(firmware[-2], end='', file=args.output)
|
Radomir Dopieralski <sheep-devel@sheep.art.pl>
parents:
diff
changeset
|
56 print(firmware[-1], end='', file=args.output)
|