File: hexlifyscript.py

package info (click to toggle)
firmware-microbit-micropython 1.0.1-4
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, sid
  • size: 25,448 kB
  • sloc: ansic: 83,496; cpp: 27,664; python: 2,475; asm: 274; makefile: 245; javascript: 41; sh: 25
file content (48 lines) | stat: -rwxr-xr-x 1,491 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#!/usr/bin/env python3

'''
Turn a Python script into Intel HEX format to be concatenated at the
end of the MicroPython firmware.hex.  A simple header is added to the
script.

To execute from command line: ./hexlifyscript.py <script.py>
It also accepts data on standard input.
'''

import struct
import binascii
import fileinput


IHEX_TYPE_DATA = 0
IHEX_TYPE_EXT_LIN_ADDR = 4

SCRIPT_ADDR = 0x3e000 # magic start address in flash of script

def make_ihex_record(addr, type, data):
    record = struct.pack('>BHB', len(data), addr & 0xffff, type) + data
    checksum = (-(sum(record))) & 0xff
    return ':%s%02X' % (str(binascii.hexlify(record), 'utf8').upper(), checksum)

def hexlify_script(script):
    # add header, pad to multiple of 16 bytes
    data = b'MP' + struct.pack('<H', len(script)) + script
    data = data + bytes(16 - len(data) % 16)
    assert len(data) <= 0x2000

    # convert to .hex format
    output = []
    addr = SCRIPT_ADDR
    assert(SCRIPT_ADDR >> 16 == 3) # 0x0003 is hard coded in line below
    output.append(make_ihex_record(0, IHEX_TYPE_EXT_LIN_ADDR, b'\x00\x03'))
    for i in range(0, len(data), 16):
        chunk = data[i:min(i + 16, len(data))]
        output.append(make_ihex_record(addr, IHEX_TYPE_DATA, chunk))
        addr += 16

    return '\n'.join(output)

if __name__ == '__main__':
    # read script from a file and print out the hexlified version
    with fileinput.input(mode='rb') as lines:
        print(hexlify_script(b''.join(lines)))