From 9a9691fb79e1053fc3acd333abd8af7ecc0b50a2 Mon Sep 17 00:00:00 2001 From: Tyler Bell Date: Mon, 23 Jul 2018 14:23:57 -0500 Subject: [PATCH 1/6] Adding setup.py --- setup.py | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 setup.py diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..9e369c6 --- /dev/null +++ b/setup.py @@ -0,0 +1,7 @@ +from distutils.core import setup + +setup(name="srec2bin_py", + description="This utility converts binary data from Motorola S-Record file format to raw binary", + version="1.0", + py_modules=["srec2bin", + "srecord"]) From a62ed99443c9b1efe814c3b6ffbd1dd83a88856c Mon Sep 17 00:00:00 2001 From: Tyler Bell Date: Thu, 26 Jul 2018 09:14:12 -0500 Subject: [PATCH 2/6] Simplified code and support all SRecord types Changed print to log.debug Better setup.py Moved code to src folder --- setup.py | 81 +++++++++++++++++++++-- src/__init__.py | 6 ++ src/srec.py | 44 +++++++++++++ srec2bin.py => src/srec2bin.py | 72 ++++++++------------ src/srecord.py | 117 +++++++++++++++++++++++++++++++++ srecord.py | 81 ----------------------- 6 files changed, 268 insertions(+), 133 deletions(-) create mode 100644 src/__init__.py create mode 100644 src/srec.py rename srec2bin.py => src/srec2bin.py (64%) create mode 100644 src/srecord.py delete mode 100644 srecord.py diff --git a/setup.py b/setup.py index 9e369c6..fa1ff8d 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,76 @@ -from distutils.core import setup +#!/usr/bin/env python +# -*- coding: utf-8 -*- -setup(name="srec2bin_py", - description="This utility converts binary data from Motorola S-Record file format to raw binary", - version="1.0", - py_modules=["srec2bin", - "srecord"]) +import codecs +import os +import re + +from setuptools import find_packages, setup + +NAME = 'srec2bin_py' +PACKAGES = find_packages(where='.') +META_PATH = os.path.join('src', '__init__.py') +KEYWORDS = ['motorola', 'srecord', 'S3'] +CLASSIFIERS = [ + 'Development Status :: 4 - Beta', + 'Environment :: Other Environment', + 'Natural Language :: English', + 'Intended Audience :: Developers', + 'License :: OSI Approved :: MIT License', + 'Operating System :: MacOS :: MacOS X', + 'Operating System :: POSIX', + 'Operating System :: Win32', + 'Programming Language :: Python :: 3.5', + 'Topic :: Software Development :: Libraries :: Python Modules', +] +INSTALL_REQUIRES = [ +] + +HERE = os.path.abspath(os.path.dirname(__file__)) + + +def read(*parts): + """ + Build an absolute path from *parts* and and return the contents of the + resulting file. Assume UTF-8 encoding. + """ + with codecs.open(os.path.join(HERE, *parts), 'rb', 'utf-8') as f: + return f.read() + + +META_FILE = read(META_PATH) + + +def find_meta(meta): + """ + Extract __*meta*__ from META_FILE. + """ + meta_match = re.search( + r"^__{meta}__ = ['\"]([^'\"]*)['\"]".format(meta=meta), + META_FILE, re.M + ) + if meta_match: + return meta_match.group(1) + raise RuntimeError("Unable to find __{meta}__ string.".format(meta=meta)) + + +if __name__ == '__main__': + setup( + name=NAME, + description=find_meta('description'), + license=find_meta('license'), + url=find_meta('uri'), + version=find_meta('version'), + # author=find_meta('author'), + # author_email=find_meta('email'), + # maintainer=find_meta('author'), + # maintainer_email=find_meta('email'), + keywords=KEYWORDS, + long_description=read('README.md'), + packages=PACKAGES, + package_dir={'src': '.'}, + package_data={'srec2bin': ['*.rst']}, + classifiers=CLASSIFIERS, + install_requires=INSTALL_REQUIRES, + python_requires='>=3.5', + ) diff --git a/src/__init__.py b/src/__init__.py new file mode 100644 index 0000000..7286cf2 --- /dev/null +++ b/src/__init__.py @@ -0,0 +1,6 @@ +__version__ = '1.0' +__title__ = 'srec2bin' +__description__ = 'This utility converts binary data from Motorola S-Record file format [1] to raw binary.' +__uri__ = 'https://github.com/mrbell321/srec2bin_py' +__doc__ = __description__ + ' <' + __uri__ + '>' +__license__ = 'MIT' diff --git a/src/srec.py b/src/srec.py new file mode 100644 index 0000000..4b54317 --- /dev/null +++ b/src/srec.py @@ -0,0 +1,44 @@ +import logging +from typing import Tuple, Iterable + +from srecord import SRecord, Purpose + +log = logging.getLogger(__name__) +log.setLevel(logging.INFO) + + +def load(filename: str): + if isinstance(filename, str): + with open(filename, 'r') as f: + srecords = (SRecord(line) for line in f.readlines()) + else: + srecords = (SRecord(line) for line in filename) + + return srecords + + +def to_binary(srecords: Iterable[SRecord], fill_byte: int = 0xff, offset: int = 0) -> Tuple[bytearray, int]: + log.debug("Converting SRecords to binary, fill: 0x{:X}, offset: 0x{:x}".format(fill_byte, offset)) + + target_memory = bytearray(0x100000 * fill_byte) + target_memmap = bytearray(0x100000 * b'\xff') + byte_cnt = 0 + high_address = 0 + for srecord in srecords: + if srecord.type.value == Purpose.Data: + addr = srecord.address - offset + log.debug("Processing SRecord: {} @ 0x{}".format(srecord, addr)) + for b in srecord.data: + if target_memmap[addr] != 0: + target_memmap[addr] = 0 + target_memory[addr] = b + byte_cnt += 1 + else: + log.error("Non critical error: duplicate access to address: 0x{:04X}; {}".format(addr, srecord)) + addr += 1 + if addr > high_address: + high_address = addr + else: + log.debug("Skipping non-data line") + + return target_memory[:high_address], byte_cnt diff --git a/srec2bin.py b/src/srec2bin.py similarity index 64% rename from srec2bin.py rename to src/srec2bin.py index 338b1c8..a5f5ee9 100644 --- a/srec2bin.py +++ b/src/srec2bin.py @@ -13,19 +13,24 @@ # #----------------------------------------------------------------------------- +import argparse import os import sys -import argparse -from srecord import * + +from src.srec import * +from src.srecord import * #-- definitions -------------------------------------------------------------- SCRIPT_VERSION = '0.90' DEFAULT_OUT_FILE_EXT = '.bin' DEFAULT_OUT_FILE_NAME = 'out' + DEFAULT_OUT_FILE_EXT - #----------------------------------------------------------------------------- + +log = logging.getLogger(__name__) + + def _mkofn(out_fn, in_fn): """ if output file name is not specified, derive from input file name """ @@ -39,6 +44,7 @@ def _mkofn(out_fn, in_fn): #----------------------------------------------------------------------------- + def _auto_int(x): return int(x, 0) @@ -46,6 +52,7 @@ def _auto_int(x): # main program #----------------------------------------------------------------------------- + if __name__ == "__main__": parser = argparse.ArgumentParser( @@ -81,55 +88,28 @@ def _auto_int(x): 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 + log.setLevel(logging.DEBUG) - 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 + log.debug("Start address: 0x{0:04x}".format(args.start_addr) + + "End address: 0x{0:04x}".format(args.end_addr) + + "Filling with: 0x{0:02x}".format(fill_byte[0])) - if args.verbose: - print("Total bytes processed: {0:d}".format(byte_cnt)) + try: + srecords = load(args.srec_file) + except ParseException as e: + log.error("Error in {}:".format(args.srec_file.name)) + log.error(e) + log.error('Program terminated.') + sys.exit(1) + + target_memory, byte_cnt = to_binary(srecords, fill_byte) + log.debug("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) + log.debug("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]) diff --git a/src/srecord.py b/src/srecord.py new file mode 100644 index 0000000..3167666 --- /dev/null +++ b/src/srecord.py @@ -0,0 +1,117 @@ +from enum import Enum +from typing import AnyStr + + +# ----------------------------------------------------------------------------- +# +# srecord.py - Handling Module for Motorola S-Records +# by Oliver Thamm - Elektronikladen Microcomputer +# 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 +# +# ----------------------------------------------------------------------------- + + +class ParseException(Exception): + pass + + +class Purpose(Enum): + Header = 0 + Data = 1 + Count = 2 + StartAddress = 3 + + +class Type(Enum): + S0 = Purpose.Header + S1 = Purpose.Data + S2 = Purpose.Data + S3 = Purpose.Data + S5 = Purpose.Count + S6 = Purpose.Count + S7 = Purpose.StartAddress + S8 = Purpose.StartAddress + S9 = Purpose.StartAddress + + +class SRecord: + """ + An SRecord is an ASCII string of the following structure: + S | Type | Count | Address | Data | Checksum + S : The character 'S'(0x53) + Type : a numeric digit defining the type of the record + Count : two hex digits indicating the number of bytes in the rest of the record + Address : 4, 6 or 8 hex digits depending on record type in big endian + Data : a sequence of 2n hex digits for n bytes of data + Checksum : two hex digits, the least significant byte of ones' compliment of the sum of values of the count, + address and data fields + """ + + address_sizes = { + Type.S0: 2, + Type.S1: 2, + Type.S2: 3, + Type.S3: 4, + Type.S5: 2, + Type.S6: 3, + Type.S7: 4, + Type.S8: 3, + Type.S9: 2 + } + + def __init__(self, source: AnyStr): + self.type: Type = None + self.byte_count: int = 0 + self.address: int = 0 + self.data: bytes = None + self.checksum: int = None + self.__process(source) + + def __repr__(self): + address_formatter = "{{:0{}}}".format(self.address_sizes[self.type] * 2) + formatter = "{}{:02x}" + address_formatter + "{}{:02X}" + return formatter.format(self.type.name, self.byte_count, self.address, self.data.hex().upper(), self.checksum) + + def __process(self, source: AnyStr): + """ determine type and starting address of a single S-Record line, + extract data bytes, verify syntax and checksum, ignore any + blank lines, return an empty string "" on success, + otherwise a string containing the error description + """ + # determine length of input + source = source.rstrip() + # gracefully ignore an empty line + if len(source) == 0: + log.debug("Empty line") + return + + assert 2 < len(source), ParseException("Truncated S-record: " + source) + + try: + self.type = Type[source[:2]] + except KeyError: + ParseException("Incorrect S-record type specification: " + source[:2]) + + try: + self.byte_count = int(source[2:4], 16) + assert (self.byte_count << 1) == (len(source[4:])), \ + ParseException("Incorrect byte count(actual: {}; specified: {})".format( + len(source[4:]) >> 1, + self.byte_count)) + + address_length = self.address_sizes[self.type] + self.address = int(source[4:4 + (address_length << 1)], 16) + self.data = bytes.fromhex(source[4 + (address_length << 1):2 + (self.byte_count << 1)]) + self.checksum = int(source[-2:], 16) + except Exception as e: + raise ParseException("Invalid characters in S-record") from e + + calculated_checksum = (sum(int(source[i:i + 2], 16) for i in range(2, len(source) - 2, 2)) & 0xFF) ^ 0xFF + assert self.checksum == calculated_checksum, \ + ParseException("Incorrect checksum: {} != {}".format(self.checksum, calculated_checksum)) + +# ----------------------------------------------------------------------------- diff --git a/srecord.py b/srecord.py deleted file mode 100644 index 10abf49..0000000 --- a/srecord.py +++ /dev/null @@ -1,81 +0,0 @@ -#----------------------------------------------------------------------------- -# -# srecord.py - Handling Module for Motorola S-Records -# by Oliver Thamm - Elektronikladen Microcomputer -# 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 -# -#----------------------------------------------------------------------------- - -class SRecord: - - _type2asiz = {"S0":2, "S1":2, "S2":3, "S3":4, "S5":2, "S6":3, "S7":4, "S8":3, "S9":2} - - def __init__(self): - self.type = "" - self.addr = 0 - self.data = bytearray() - self.error = "" - - def process(self, srecline): - """ determine type and starting address of a single S-Record line, - extract data bytes, verify syntax and checksum, ignore any - blank lines, return an empty string "" on success, - otherwise a string containing the error description - """ - self.type = "" - self.addr = 0 - self.data = bytearray() - - # determine length of input - self.line = srecline.rstrip() - self.line_len = len(self.line) - # gracefully ignore an empty line - if self.line_len == 0: - self.error = "" - return self.error - - # check size limits and test for even number of chars - if self.line_len < 10 or self.line_len > 514 or self.line_len % 2: - self.error = "s-record has wrong size" - return self.error - - self.type = self.line[:2] - self.addr_siz = self._type2asiz.get(self.type, 0) - if not self.addr_siz: - self.error = "s-record type unknown" - return self.error - - # construe char pairs as hex values - try: - self.values = bytearray([int(self.line[i:i+2], 16) for i in range(2,self.line_len, 2)]) - except ValueError: - self.error = "s-record contains invalid character(s)" - return self.error - - # check byte count field vs. number of char pairs - if self.values[0] != len(self.values)-1: - self.error = "s-record byte count mismatch" - return self.error - - # determine starting address - self.addr = self.values[1] * 0x100 + self.values[2] - if self.addr_siz > 2: - self.addr = self.addr * 0x100 + self.values[3] - if self.addr_siz > 3: - self.addr = self.addr * 0x100 + self.values[4] - - # verify check sum - if sum(self.values, 1) % 0x100: - self.error = "s-record checksum error" - return self.error - - # deliver the data bytes - self.data = self.values[self.addr_siz+1:-1] - self.error = "" - return self.error - -#----------------------------------------------------------------------------- From e4a4abb4e8c32d42cafe2abc81b7d1ce57f94cd6 Mon Sep 17 00:00:00 2001 From: Tyler Bell Date: Fri, 27 Jul 2018 15:24:57 -0500 Subject: [PATCH 3/6] Separating SREC address size from SREC type definition Adding purpose and address_length properties --- src/srecord.py | 73 +++++++++++++++++++++++++++++++------------------- 1 file changed, 46 insertions(+), 27 deletions(-) diff --git a/src/srecord.py b/src/srecord.py index 3167666..36bd64f 100644 --- a/src/srecord.py +++ b/src/srecord.py @@ -27,15 +27,40 @@ class Purpose(Enum): class Type(Enum): - S0 = Purpose.Header - S1 = Purpose.Data - S2 = Purpose.Data - S3 = Purpose.Data - S5 = Purpose.Count - S6 = Purpose.Count - S7 = Purpose.StartAddress - S8 = Purpose.StartAddress - S9 = Purpose.StartAddress + S0 = 0 + S1 = 1 + S2 = 2 + S3 = 3 + S5 = 5 + S6 = 6 + S7 = 7 + S8 = 8 + S9 = 9 + + +TypePurpose = { + Type.S0: Purpose.Header, + Type.S1: Purpose.Data, + Type.S2: Purpose.Data, + Type.S3: Purpose.Data, + Type.S5: Purpose.Count, + Type.S6: Purpose.Count, + Type.S7: Purpose.StartAddress, + Type.S8: Purpose.StartAddress, + Type.S9: Purpose.StartAddress, +} + +TypeAddressSize = { + Type.S0: 2, + Type.S1: 2, + Type.S2: 3, + Type.S3: 4, + Type.S5: 2, + Type.S6: 3, + Type.S7: 4, + Type.S8: 3, + Type.S9: 2 +} class SRecord: @@ -51,18 +76,6 @@ class SRecord: address and data fields """ - address_sizes = { - Type.S0: 2, - Type.S1: 2, - Type.S2: 3, - Type.S3: 4, - Type.S5: 2, - Type.S6: 3, - Type.S7: 4, - Type.S8: 3, - Type.S9: 2 - } - def __init__(self, source: AnyStr): self.type: Type = None self.byte_count: int = 0 @@ -72,8 +85,8 @@ def __init__(self, source: AnyStr): self.__process(source) def __repr__(self): - address_formatter = "{{:0{}}}".format(self.address_sizes[self.type] * 2) - formatter = "{}{:02x}" + address_formatter + "{}{:02X}" + address_formatter = "{{:0{}X}}".format(self.address_length * 2) + formatter = "{} {:02x} " + address_formatter + " {} {:02X}" return formatter.format(self.type.name, self.byte_count, self.address, self.data.hex().upper(), self.checksum) def __process(self, source: AnyStr): @@ -86,7 +99,6 @@ def __process(self, source: AnyStr): source = source.rstrip() # gracefully ignore an empty line if len(source) == 0: - log.debug("Empty line") return assert 2 < len(source), ParseException("Truncated S-record: " + source) @@ -103,9 +115,8 @@ def __process(self, source: AnyStr): len(source[4:]) >> 1, self.byte_count)) - address_length = self.address_sizes[self.type] - self.address = int(source[4:4 + (address_length << 1)], 16) - self.data = bytes.fromhex(source[4 + (address_length << 1):2 + (self.byte_count << 1)]) + self.address = int(source[4:4 + (self.address_length << 1)], 16) + self.data = bytes.fromhex(source[4 + (self.address_length << 1):2 + (self.byte_count << 1)]) self.checksum = int(source[-2:], 16) except Exception as e: raise ParseException("Invalid characters in S-record") from e @@ -114,4 +125,12 @@ def __process(self, source: AnyStr): assert self.checksum == calculated_checksum, \ ParseException("Incorrect checksum: {} != {}".format(self.checksum, calculated_checksum)) + @property + def address_length(self): + return TypeAddressSize[self.type] + + @property + def purpose(self): + return TypePurpose[self.type] + # ----------------------------------------------------------------------------- From d0bd7222da2471179c68141d47b07c9d08856ba6 Mon Sep 17 00:00:00 2001 From: Tyler Bell Date: Fri, 27 Jul 2018 15:25:50 -0500 Subject: [PATCH 4/6] Paginating to_binary --- src/srec.py | 55 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 31 insertions(+), 24 deletions(-) diff --git a/src/srec.py b/src/srec.py index 4b54317..860d566 100644 --- a/src/srec.py +++ b/src/srec.py @@ -1,11 +1,13 @@ import logging -from typing import Tuple, Iterable +from typing import Generator, Iterable, Optional from srecord import SRecord, Purpose log = logging.getLogger(__name__) log.setLevel(logging.INFO) +MAX_PAGE_SIZE = 0x100000 + def load(filename: str): if isinstance(filename, str): @@ -17,28 +19,33 @@ def load(filename: str): return srecords -def to_binary(srecords: Iterable[SRecord], fill_byte: int = 0xff, offset: int = 0) -> Tuple[bytearray, int]: - log.debug("Converting SRecords to binary, fill: 0x{:X}, offset: 0x{:x}".format(fill_byte, offset)) +def to_binary(srecords: Iterable[SRecord], page_size: Optional[int] = None) -> Generator[bytearray, None, None]: + page_size = page_size or MAX_PAGE_SIZE + log.debug("Converting SRecords to binary, page_size: 0x{:x}".format(page_size)) + + page = bytearray() - target_memory = bytearray(0x100000 * fill_byte) - target_memmap = bytearray(0x100000 * b'\xff') - byte_cnt = 0 - high_address = 0 + page_address = -1 for srecord in srecords: - if srecord.type.value == Purpose.Data: - addr = srecord.address - offset - log.debug("Processing SRecord: {} @ 0x{}".format(srecord, addr)) - for b in srecord.data: - if target_memmap[addr] != 0: - target_memmap[addr] = 0 - target_memory[addr] = b - byte_cnt += 1 - else: - log.error("Non critical error: duplicate access to address: 0x{:04X}; {}".format(addr, srecord)) - addr += 1 - if addr > high_address: - high_address = addr - else: - log.debug("Skipping non-data line") - - return target_memory[:high_address], byte_cnt + if srecord.purpose == Purpose.Data: + log.debug("Processing SRecord: {}".format(srecord)) + if page_address < 0: + page_address = srecord.address + + elif srecord.address < page_address or srecord.address >= (page_address + page_size): + log.debug("Switching from page at 0x{:08X} to 0x{:08X}".format(page_address, srecord.address)) + yield page_address, page + page = bytearray() + page_address = srecord.address + + if len(page) + len(srecord.data) >= page_size: + remaining = page_size - len(page) + page[len(page):] = srecord.data[:remaining] + yield page_address, page + page = bytearray(srecord.data[remaining:]) + page_address = srecord.address + remaining + else: + page[len(page):] = srecord.data[:] + + if page: + yield page_address, page From b0f1190ad7c59f4379e5438de2587d62e6eb73c0 Mon Sep 17 00:00:00 2001 From: Tyler Bell Date: Fri, 27 Jul 2018 16:29:12 -0500 Subject: [PATCH 5/6] Re-implementing image generation and renamed to_binary->to_pages --- src/srec.py | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/src/srec.py b/src/srec.py index 860d566..80c4d96 100644 --- a/src/srec.py +++ b/src/srec.py @@ -1,5 +1,5 @@ import logging -from typing import Generator, Iterable, Optional +from typing import Generator, Iterable, Tuple, Optional from srecord import SRecord, Purpose @@ -19,7 +19,35 @@ def load(filename: str): return srecords -def to_binary(srecords: Iterable[SRecord], page_size: Optional[int] = None) -> Generator[bytearray, None, None]: +def to_image(srecords: Iterable[SRecord], fill_byte: bytes = b'\xff', offset: int = 0) -> Tuple[bytearray, int]: + log.debug("Converting SRecords to binary, fill: 0x{}, offset: 0x{:x}".format(fill_byte.hex(), offset)) + + target_memory = bytearray(fill_byte * 0x100000) + target_memmap = bytearray(0x100000 * b'\xff') + byte_cnt = 0 + high_address = 0 + for srecord in srecords: + if srecord.purpose == Purpose.Data: + addr = srecord.address - offset + log.debug("Processing SRecord: {} @ 0x{:08x}".format(srecord, addr)) + for b in srecord.data: + if target_memmap[addr] == 0: + log.debug("Non critical error: duplicate access to address: 0x{:04X}; {}".format(addr, srecord)) + else: + byte_cnt += 1 + target_memmap[addr] = 0 + target_memory[addr] = b + addr += 1 + if addr > high_address: + high_address = addr + else: + log.debug("Skipping non-data line") + + return target_memory[:high_address], byte_cnt + + +def to_pages(srecords: Iterable[SRecord], page_size: Optional[int] = None) -> Generator[ + Tuple[int, bytearray], None, None]: page_size = page_size or MAX_PAGE_SIZE log.debug("Converting SRecords to binary, page_size: 0x{:x}".format(page_size)) From 0c0bef36eabbb3d1f6059c1b03ce0fa2939a3603 Mon Sep 17 00:00:00 2001 From: Tyler Bell Date: Sat, 28 Jul 2018 21:54:07 -0500 Subject: [PATCH 6/6] Better setup.py --- {src => bin}/srec2bin.py | 4 ++-- setup.py | 17 +++++++++-------- {src => srec2bin}/__init__.py | 5 +++++ {src => srec2bin}/srec.py | 2 +- {src => srec2bin}/srecord.py | 0 5 files changed, 17 insertions(+), 11 deletions(-) rename {src => bin}/srec2bin.py (98%) rename {src => srec2bin}/__init__.py (64%) rename {src => srec2bin}/srec.py (98%) rename {src => srec2bin}/srecord.py (100%) diff --git a/src/srec2bin.py b/bin/srec2bin.py similarity index 98% rename from src/srec2bin.py rename to bin/srec2bin.py index a5f5ee9..86a9fff 100644 --- a/src/srec2bin.py +++ b/bin/srec2bin.py @@ -14,11 +14,11 @@ #----------------------------------------------------------------------------- import argparse +import logging import os import sys -from src.srec import * -from src.srecord import * +from srec2bin import * #-- definitions -------------------------------------------------------------- diff --git a/setup.py b/setup.py index fa1ff8d..bb55c5f 100644 --- a/setup.py +++ b/setup.py @@ -7,9 +7,9 @@ from setuptools import find_packages, setup -NAME = 'srec2bin_py' +NAME = 'srec2bin' PACKAGES = find_packages(where='.') -META_PATH = os.path.join('src', '__init__.py') +META_PATH = os.path.join('srec2bin', '__init__.py') KEYWORDS = ['motorola', 'srecord', 'S3'] CLASSIFIERS = [ 'Development Status :: 4 - Beta', @@ -61,15 +61,16 @@ def find_meta(meta): license=find_meta('license'), url=find_meta('uri'), version=find_meta('version'), - # author=find_meta('author'), - # author_email=find_meta('email'), - # maintainer=find_meta('author'), - # maintainer_email=find_meta('email'), + author=find_meta('author'), + author_email=find_meta('email'), + maintainer=find_meta('author'), + maintainer_email=find_meta('email'), keywords=KEYWORDS, long_description=read('README.md'), packages=PACKAGES, - package_dir={'src': '.'}, - package_data={'srec2bin': ['*.rst']}, + # package_dir={'srec2bin': 'srec2bin'}, + # package_data={'srec2bin': ['*.rst']}, + scripts=['bin/srec2bin.py'], classifiers=CLASSIFIERS, install_requires=INSTALL_REQUIRES, python_requires='>=3.5', diff --git a/src/__init__.py b/srec2bin/__init__.py similarity index 64% rename from src/__init__.py rename to srec2bin/__init__.py index 7286cf2..76ebdca 100644 --- a/src/__init__.py +++ b/srec2bin/__init__.py @@ -1,6 +1,11 @@ __version__ = '1.0' __title__ = 'srec2bin' __description__ = 'This utility converts binary data from Motorola S-Record file format [1] to raw binary.' +__author__ = 'Oliver Thamm' +__email__ = 'support@elmicro.com' __uri__ = 'https://github.com/mrbell321/srec2bin_py' __doc__ = __description__ + ' <' + __uri__ + '>' __license__ = 'MIT' + +from .srecord import SRecord, Purpose, Type +from .srec import to_image, to_pages, load \ No newline at end of file diff --git a/src/srec.py b/srec2bin/srec.py similarity index 98% rename from src/srec.py rename to srec2bin/srec.py index 80c4d96..2cf09a3 100644 --- a/src/srec.py +++ b/srec2bin/srec.py @@ -1,7 +1,7 @@ import logging from typing import Generator, Iterable, Tuple, Optional -from srecord import SRecord, Purpose +from .srecord import SRecord, Purpose log = logging.getLogger(__name__) log.setLevel(logging.INFO) diff --git a/src/srecord.py b/srec2bin/srecord.py similarity index 100% rename from src/srecord.py rename to srec2bin/srecord.py