-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsrec2bin.py
136 lines (116 loc) · 4.59 KB
/
srec2bin.py
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#!/usr/bin/env python
#-----------------------------------------------------------------------------
#
# Motorola S-Record to Binary File Converter (Python 3)
#
# by Oliver Thamm - ELMICRO Computer
# https://github.com/elmicro/srec2bin_py
#
# This software is Copyright (C)2017 by ELMICRO - https://elmicro.com
# and may be freely used, modified and distributed under the terms of
# the MIT License - see accompanying LICENSE.md for details
#
#-----------------------------------------------------------------------------
import os
import sys
import argparse
from srecord import *
#-- definitions --------------------------------------------------------------
SCRIPT_VERSION = '0.90'
DEFAULT_OUT_FILE_EXT = '.bin'
DEFAULT_OUT_FILE_NAME = 'out' + DEFAULT_OUT_FILE_EXT
#-----------------------------------------------------------------------------
def _mkofn(out_fn, in_fn):
""" if output file name is not specified, derive from input file name """
if out_fn is None:
if in_fn == '<stdin>':
return DEFAULT_OUT_FILE_NAME
else:
base, ext = os.path.splitext(in_fn)
return base + DEFAULT_OUT_FILE_EXT
return out_fn
#-----------------------------------------------------------------------------
def _auto_int(x):
return int(x, 0)
#-----------------------------------------------------------------------------
# main program
#-----------------------------------------------------------------------------
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description='Motorola S-Record to Binary Converter V' + SCRIPT_VERSION)
parser.add_argument(
'srec_file',
type=argparse.FileType('r'),
nargs='?', default=sys.stdin,
help='s-record file name (if not specified: read from stdin)')
parser.add_argument(
'-v', '--verbose',
action='store_true',
help='display additional runtime information')
parser.add_argument(
'-s', '--start_addr',
type=_auto_int,
default=0x00000,
help='start address for output, default is 0')
parser.add_argument(
'-e', '--end_addr',
type=_auto_int,
default=0x10000,
help='end address (last + 1) for output, default is 0x10000')
parser.add_argument(
'-f', '--fill_byte',
type=_auto_int,
default=0xff,
help='fill byte for unoccupied space, default is 0xff')
parser.add_argument(
'-o', '--out_file',
help='output file name, default is <srec_file>' + DEFAULT_OUT_FILE_EXT +
' or ' + DEFAULT_OUT_FILE_NAME + ' if input is STDIN')
args = parser.parse_args()
fill_byte = (args.fill_byte % 0x100).to_bytes(1, 'big')
target_memory = bytearray(0x10000 * fill_byte)
target_memmap = bytearray(0x10000 * b'\xff')
if args.verbose:
print("Start address: 0x{0:04x}".format(args.start_addr))
print("End address: 0x{0:04x}".format(args.end_addr))
print("Filling with: 0x{0:02x}".format(fill_byte[0]))
srecs = []
line_no = 1
byte_cnt = 0
for srec_line in args.srec_file:
srec = SRecord()
if not srec.process(srec_line):
if srec.type == "S1":
srecs.append(srec)
else:
if args.verbose:
print("Skipping", srec.type if srec.type!="" else "empty", "line")
else:
print("Error in", args.srec_file.name, "Line", str(line_no) + ":")
# to display the offending line we better use bytes type here in case
# the input is (mistakenly) binary stuff instead of a text file
print(srec_line.rstrip().encode('ASCII', 'ignore'))
print(srec.error)
print('Program terminated.')
sys.exit(1)
line_no += 1
if args.verbose:
print("S-Record lines processed: {0:d}".format(line_no - 1))
for srec in srecs:
addr = srec.addr
for b in srec.data:
if target_memmap[addr] != 0:
target_memmap[addr] = 0
target_memory[addr] = b
byte_cnt += 1
else:
print("Error: duplicate access to addr", "0x%04x" % addr)
addr += 1
if args.verbose:
print("Total bytes processed: {0:d}".format(byte_cnt))
out_file_name = _mkofn(args.out_file, args.srec_file.name)
if args.verbose:
print("Writing to output file", out_file_name)
with open(out_file_name, 'wb') as outfile:
outfile.write(target_memory[args.start_addr:args.end_addr])
#-----------------------------------------------------------------------------