From 57657a44bef969f2ef900a8aafd48e8313630b6c Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Wed, 10 Jul 2013 01:59:51 +0000 Subject: reenabled read flash git-svn-id: https://svn.spreadspace.org/pic/trunk@66 a09c6847-51d9-44de-8ef2-e725cf50f3c7 --- bootloader/downloader.py | 40 +++++---- bootloader/ihexpic.py | 221 ++++++++++++++++++++++++----------------------- 2 files changed, 132 insertions(+), 129 deletions(-) diff --git a/bootloader/downloader.py b/bootloader/downloader.py index 260ff7e..27b15c3 100755 --- a/bootloader/downloader.py +++ b/bootloader/downloader.py @@ -42,13 +42,16 @@ def load_hex(file): hexdata.load_from_file(fin) return hexdata -# TODO: re-add this as soon as write_hex_file works -# def write_hex(file, hexdata): -# fout = file -# if fout == '-': -# fout = sys.stdout +def write_hex(file, codedata): + from ihexpic import IHexPic + + fout = file + if fout == '-': + fout = sys.stdout -# hexdata.write_hex_file(fout) + hexdata = IHexPic() + hexdata.load_from_dict(codedata) + hexdata.write_to_file(fout) def get_lowest_flash_addr(hexdata, fss): lowest_code_addr = hexdata.get_lowest_addr() @@ -222,18 +225,17 @@ def write_flash(dev, id, file): # print >> sys.stderr, "%05X: %s" % (segment[0], ''.join('%04X '%i for i in segment[1])) cmd_write_flash_segment(dev, id, segment[0], segment[1]) -# TODO: re-add this as soon as write_hex_file works -# def read_flash(dev, id, file): -# codedata = {} -# for addr in xrange(0, id['fs'], id['fss']): -# data = cmd_read_flash_segment(dev, id, addr) -# # print >> sys.stderr, "%05X: %s" % (addr, ''.join('%04X '%i for i in data)) -# a = addr -# for d in data: -# codedata[a] = d -# a += 1 - -# write_hex(file, codedata) +def read_flash(dev, id, file): + codedata = {} + for addr in xrange(0, id['fs'], id['fss']): + data = cmd_read_flash_segment(dev, id, addr) +# print >> sys.stderr, "%05X: %s" % (addr, ''.join('%04X '%i for i in data)) + a = addr + for d in data: + if d != 0x3FFF: + codedata[a] = d + a += 1 + write_hex(file, codedata) def verify_flash(dev, id, file): hexdata = load_hex(file) @@ -260,7 +262,7 @@ def verify_flash(dev, id, file): commands = { 'boot': boot, 'write': write_flash, -# 'read': read_flash, # TODO: re-add this as soon as write_hex_file works + 'read': read_flash, 'verify': verify_flash } diff --git a/bootloader/ihexpic.py b/bootloader/ihexpic.py index d6978de..77b2929 100644 --- a/bootloader/ihexpic.py +++ b/bootloader/ihexpic.py @@ -191,116 +191,117 @@ class IHexPic(object): self._buf.update(s) # TODO: fix this so it works with 16bit data - # def write_to_file(self, f): - # """Write data to file f in HEX format. - - # @param f filename or file-like object for writing - # """ - # fwrite = getattr(f, "write", None) - # if fwrite: - # fobj = f - # fclose = None - # else: - # fobj = file(f, 'w') - # fwrite = fobj.write - # fclose = fobj.close - - # # Translation table for uppercasing hex ascii string. - # # timeit shows that using hexstr.translate(table) - # # is faster than hexstr.upper(): - # # 0.452ms vs. 0.652ms (translate vs. upper) - # if sys.version_info[0] >= 3: - # table = bytes(range(256)).upper() - # else: - # table = ''.join(chr(i).upper() for i in range(256)) - - - # # data - # addresses = self._buf.keys() - # addresses.sort() - # addr_len = len(addresses) - # if addr_len: - # minaddr = addresses[0] - # maxaddr = addresses[-1] - - # if maxaddr > 65535: - # need_offset_record = True - # else: - # need_offset_record = False - # high_ofs = 0 - - # cur_addr = minaddr - # cur_ix = 0 - - # while cur_addr <= maxaddr: - # if need_offset_record: - # bin = array('B', str('\0'*7)) - # bin[0] = 2 # reclen - # bin[1] = 0 # offset msb - # bin[2] = 0 # offset lsb - # bin[3] = 4 # rectyp - # high_ofs = int(cur_addr>>16) - # b = divmod(high_ofs, 256) - # bin[4] = b[0] # msb of high_ofs - # bin[5] = b[1] # lsb of high_ofs - # bin[6] = (-sum(bin)) & 0x0FF # chksum - # fwrite(':' + - # str(hexlify(bin.tostring()).translate(table)) + - # '\n') - - # while True: - # # produce one record - # low_addr = cur_addr & 0x0FFFF - # # chain_len off by 1 - # chain_len = min(15, 65535-low_addr, maxaddr-cur_addr) - - # # search continuous chain - # stop_addr = cur_addr + chain_len - # if chain_len: - # ix = bisect_right(addresses, stop_addr, - # cur_ix, - # min(cur_ix+chain_len+1, addr_len)) - # chain_len = ix - cur_ix # real chain_len - # # there could be small holes in the chain - # # but we will catch them by try-except later - # # so for big continuous files we will work - # # at maximum possible speed - # else: - # chain_len = 1 # real chain_len - - # bin = array('B', str('\0'*(5+chain_len))) - # b = divmod(low_addr, 256) - # bin[1] = b[0] # msb of low_addr - # bin[2] = b[1] # lsb of low_addr - # bin[3] = 0 # rectype - # try: # if there is small holes we'll catch them - # for i in range(chain_len): - # bin[4+i] = self._buf[cur_addr+i] - # except KeyError: - # # we catch a hole so we should shrink the chain - # chain_len = i - # bin = bin[:5+i] - # bin[0] = chain_len - # bin[4+chain_len] = (-sum(bin)) & 0x0FF # chksum - # fwrite(':' + - # str(hexlify(bin.tostring()).translate(table)) + - # '\n') - - # # adjust cur_addr/cur_ix - # cur_ix += chain_len - # if cur_ix < addr_len: - # cur_addr = addresses[cur_ix] - # else: - # cur_addr = maxaddr + 1 - # break - # high_addr = int(cur_addr>>16) - # if high_addr > high_ofs: - # break - - # # end-of-file record - # fwrite(":00000001FF\n") - # if fclose: - # fclose() + def write_to_file(self, f): + """Write data to file f in HEX format. + + @param f filename or file-like object for writing + """ + fwrite = getattr(f, "write", None) + if fwrite: + fobj = f + fclose = None + else: + fobj = file(f, 'w') + fwrite = fobj.write + fclose = fobj.close + + # Translation table for uppercasing hex ascii string. + # timeit shows that using hexstr.translate(table) + # is faster than hexstr.upper(): + # 0.452ms vs. 0.652ms (translate vs. upper) + if sys.version_info[0] >= 3: + table = bytes(range(256)).upper() + else: + table = ''.join(chr(i).upper() for i in range(256)) + + + # data + addresses = self._buf.keys() + addresses.sort() + addr_len = len(addresses) + if addr_len: + minaddr = addresses[0] + maxaddr = addresses[-1] + + if maxaddr > 65535/2: + need_offset_record = True + else: + need_offset_record = False + high_ofs = 0 + + cur_addr = minaddr + cur_ix = 0 + + while cur_addr <= maxaddr: + if need_offset_record: + bin = array('B', str('\0'*7)) + bin[0] = 2 # reclen + bin[1] = 0 # offset msb + bin[2] = 0 # offset lsb + bin[3] = 4 # rectype + high_ofs = int(cur_addr>>16) + b = divmod(high_ofs*2, 256) + bin[4] = b[0] # msb of high_ofs + bin[5] = b[1] # lsb of high_ofs + bin[6] = (-sum(bin)) & 0x0FF # chksum + fwrite(':' + + str(hexlify(bin.tostring()).translate(table)) + + '\n') + + while True: + # produce one record + low_addr = cur_addr & 0x0FFFF + # chain_len off by 1 + chain_len = min(7, 65535-low_addr, maxaddr-cur_addr) + + # search continuous chain + stop_addr = cur_addr + chain_len + if chain_len: + ix = bisect_right(addresses, stop_addr, + cur_ix, + min(cur_ix+chain_len+1, addr_len)) + chain_len = ix - cur_ix # real chain_len + # there could be small holes in the chain + # but we will catch them by try-except later + # so for big continuous files we will work + # at maximum possible speed + else: + chain_len = 1 # real chain_len + + bin = array('B', str('\0'*(5+(chain_len*2)))) + b = divmod(low_addr*2, 256) + bin[1] = b[0] # msb of low_addr + bin[2] = b[1] # lsb of low_addr + bin[3] = 0 # rectype + try: # if there is small holes we'll catch them + for i in range(chain_len): + bin[4+(i*2)] = self._buf[cur_addr+i] & 0x00FF + bin[4+(i*2)+1] = self._buf[cur_addr+i] >> 8 + except KeyError: + # we catch a hole so we should shrink the chain + chain_len = i + bin = bin[:5+(i*2)] + bin[0] = chain_len*2 + bin[4+(chain_len*2)] = (-sum(bin)) & 0x0FF # chksum + fwrite(':' + + str(hexlify(bin.tostring()).translate(table)) + + '\n') + + # adjust cur_addr/cur_ix + cur_ix += chain_len + if cur_ix < addr_len: + cur_addr = addresses[cur_ix] + else: + cur_addr = maxaddr + 1 + break + high_addr = int(cur_addr>>16) + if high_addr > high_ofs: + break + + # end-of-file record + fwrite(":00000001FF\n") + if fclose: + fclose() def get_lowest_addr(self): return sorted(self._buf.keys())[0] -- cgit v1.2.3