def check_fw(path): """Check that firmware is valid and return dict with binary data.""" try: intel_hex = IntelHex() with open(path, 'r') as file_handle: intel_hex.fromfile(file_handle, format='hex') bin_string = intel_hex.tobinstr() except (IntelHexError, TypeError, ValueError) as exception: _LOGGER.error(exception) return pads = len(bin_string) % 128 # 128 bytes per page for atmega328 for _ in range(128 - pads): # pad up to even 128 bytes bin_string += b'\xff' fware = { 'path': path, 'blocks': int(len(bin_string) / FIRMWARE_BLOCK_SIZE), 'crc': compute_crc(bin_string), 'data': bin_string, } return fware
def post_process(self): logging.info("Processing binaries") # save original dir cwd = os.getcwd() # change to target dir os.chdir(self.target_dir) ih = IntelHex('main.hex') fwid = uuid.UUID('{' + self.settings["FWID"] + '}') size = ih.maxaddr() - ih.minaddr() + 1 # get os info os_project = get_project_builder(self.settings["OS_PROJECT"]) # create firmware info structure fw_info = struct.pack('<I16s128s16s128s16s', size, fwid.bytes, os_project.proj_name, os_project.version, self.proj_name, self.version) # insert fw info into hex ih.puts(0x120, fw_info) # compute crc crc_func = crcmod.predefined.mkCrcFun('crc-aug-ccitt') crc = crc_func(ih.tobinstr()) logging.info("size: %d" % (size)) logging.info("fwid: %s" % (fwid)) logging.info("crc: 0x%x" % (crc)) logging.info("os name: %s" % (os_project.proj_name)) logging.info("os version: %s" % (os_project.version)) logging.info("app name: %s" % (self.proj_name)) logging.info("app version: %s" % (self.version)) ih.puts(ih.maxaddr() + 1, struct.pack('>H', crc)) ih.write_hex_file('main.hex') ih.tobinfile('firmware.bin') # get loader info loader_project = get_project_builder(self.settings["LOADER_PROJECT"]) # create loader image loader_hex = os.path.join(loader_project.target_dir, "main.hex") self.merge_hex('main.hex', loader_hex, 'loader_image.hex') # change back to original dir os.chdir(cwd)
def _write_ihx(self, filename): ihx = IntelHex(filename) print "Erasing." min_sector = rounddown_multiple(ihx.minaddr(), SECTORSIZE) max_sector = roundup_multiple(ihx.maxaddr(), SECTORSIZE) for addr in range(min_sector, max_sector, SECTORSIZE): self._erase_sector(addr) print "Writing." min_page = rounddown_multiple(ihx.minaddr(), PAGESIZE) max_page = roundup_multiple(ihx.maxaddr(), PAGESIZE) for addr in range(min_page, max_page, PAGESIZE): self._write(addr, ihx.tobinstr(start=addr, size=PAGESIZE))
def flash_file(self, filename, addr=0, verify=False): hexfile = IntelHex(filename) print('Min addr >> ', hexfile.minaddr()) assert hexfile.minaddr() == 0 data = hexfile.tobinstr() page_size = mcs51.consts.FLASH_PAGE_SIZE for i in range(0, len(data), page_size): cur = data[i:i + page_size] glog.info('Writing page %d of %d', i // page_size, len(data) // page_size) self.write_flash_page(addr + i, cur) if verify: glog.info('Verifying page') written = bytes(self.read_flash_page(addr + i)) written = written[:len(cur)] assert cur == written, '%s VS %s' % (cur, written)
def load_fw(path): """Open firmware file and return a binary string.""" fname = os.path.realpath(path) exists = os.path.isfile(fname) if not exists or not os.access(fname, os.R_OK): _LOGGER.error('Firmware path %s does not exist or is not readable', path) return None try: intel_hex = IntelHex() with open(path, 'r') as file_handle: intel_hex.fromfile(file_handle, format='hex') return intel_hex.tobinstr() except (IntelHexError, TypeError, ValueError) as exc: _LOGGER.error('Firmware not valid, check the hex file at %s: %s', path, exc) return None
def combine(bootloader_fn, app_fn, app_addr, hdr_addr, bootloader_addr, output_fn, version, no_bootloader): # read bootloader bootloader_format = bootloader_fn.split('.')[-1] bootloader = IntelHex() if not no_bootloader: if bootloader_format == 'hex': bootloader.fromfile(bootloader_fn, bootloader_format) elif bootloader_format == 'bin': bootloader.loadbin(bootloader_fn, bootloader_addr) else: print('Bootloader format can only be .bin or .hex') exit(-1) # read application app_format = app_fn.split('.')[-1] app = IntelHex() if app_format == 'hex': app.fromfile(app_fn, app_format) elif app_format == 'bin': app.loadbin(app_fn, app_addr) else: print('Application format can only be .bin or .hex') exit(-1) # create firmware header header = IntelHex() fw_header = create_header(app.tobinstr(), version) header.puts(hdr_addr, fw_header) # combine output_format = output_fn.split('.')[-1] output = IntelHex() if not no_bootloader: print("Writing bootloader to address 0x%08x-0x%08x." % (bootloader.addresses()[0], bootloader.addresses()[-1])) output.merge(bootloader, overlap='error') print("Writing header to address 0x%08x-0x%08x." % (header.addresses()[0], header.addresses()[-1])) output.merge(header, overlap='error') print("Writing application to address 0x%08x-0x%08x." % (app.addresses()[0], app.addresses()[-1])) output.merge(app, overlap='error') # write output file output.tofile(output_fn, format=output_format)
def slurp(self, filename): if filename.endswith('.bit') or filename.endswith('.bin'): with open(filename, 'rb') as f: return f.read() elif filename.endswith('.hex'): with open(filename, 'rb') as f: return bytes("".join(chr(int(i, 16)) for i in f.read().split())) elif filename.endswith('.mcs'): ih = IntelHex() ih.fromfile(filename, format='hex') bitstream = ih.tobinstr(start=0, end=ih.maxaddr()) bitstream = _mirror_each_byte(bitstream) return bitstream else: raise ValueError('Unknown bitstream extension')
def read_fw(args, model_a): # load the firmware image stock = None image = None if args.stock: with open(args.firmware, 'rb') as source: stock = firmware.UpdateFile(source.read()) image = firmware.Firmware( stock.a_firmware if model_a else stock.cs_firmware, encrypted=True, ) else: with open(args.firmware, 'r') as source: hexfile = IntelHex(source) image = firmware.Firmware( hexfile.tobinstr(start=0x1800, end=0x1FBFF), encrypted=False, ) return stock, image
def add_firmware(self, filename_hex, fw_info): ihex = IntelHex(filename_hex) # We remove configuration data from TSB firmware (last 16 bytes) # beginnin with TSB ... fw_data = ihex.tobinstr() fw_info.tsb_fwconf = "" fw_parts = fw_data.rsplit("TSB", 1) if len(fw_parts) == 2: fw_data = fw_parts[0] fw_info.tsb_fwconf = fw_parts[1] fw_info.tsb_start = ihex.minaddr() fw_md5 = hashlib.md5(fw_data).hexdigest() if not self.tsbdb.has_key(fw_md5): self.tsbdb[fw_md5] = [ fw_data ] self.add_firmware_info(fw_md5, fw_info)
def __init__(self, fw: Union[bytearray, bytes, str, BinaryIO], be: Optional[bool] = None) -> None: self.base = None # type: Optional[int] if isinstance(fw, str): if fw.lower().endswith('.hex'): ih = IntelHex() ih.loadhex(fw) self.base = ih.minaddr() self.fw = bytearray(ih.tobinstr()) else: with open(fw, 'rb') as f: self.fw = bytearray(f.read()) elif isinstance(fw, bytes): self.fw = bytearray(fw) elif isinstance(fw, bytearray): self.fw = fw else: self.fw = bytearray(fw.read()) self.size = len(self.fw) if self.size < 8 or (self.size & 3) != 0: raise ValueError('invalid firmware length') self.crc = crc32(self.fw[8:]) if be is None: (lcrc, lsz) = struct.unpack_from('<II', self.fw) (bcrc, bsz) = struct.unpack_from('>II', self.fw) if (lcrc == self.crc and lsz == self.size) or lsz == Firmware.SIZE_MAGIC: self.be = False elif (bcrc == self.crc and bsz == self.size) or bsz == Firmware.SIZE_MAGIC: self.be = True else: raise ValueError('could not determine firmware endianness') else: self.be = be self.ep = '>' if be else '<' (self.hcrc, self.hsize) = struct.unpack_from(self.ep + 'II', self.fw)
def combine(bootloader_fn, app_fn, app_addr, hdr_addr, bootloader_addr, output_fn, version, no_bootloader): ih = IntelHex() bootloader_format = bootloader_fn.split('.')[-1] # write the bootloader if not no_bootloader: print("Using bootloader %s" % bootloader_fn) if bootloader_format == 'hex': print("Loading bootloader from hex file.") ih.fromfile(bootloader_fn, format=bootloader_format) elif bootloader_format == 'bin': print("Loading bootloader to address 0x%08x." % bootloader_addr) ih.loadbin(bootloader_fn, offset=bootloader_addr) else: print('Bootloader format can only be .bin or .hex') exit(-1) # write firmware header app_format = app_fn.split('.')[-1] if app_format == 'bin': with open(app_fn, 'rb') as fd: app_blob = fd.read() elif app_format == 'hex': application = IntelHex(app_fn) app_blob = application.tobinstr() FirmwareHeader = create_header(app_blob, version) print("Writing header to address 0x%08x." % hdr_addr) ih.puts(hdr_addr, FirmwareHeader) # write the application if app_format == 'bin': print("Loading application to address 0x%08x." % app_addr) ih.loadbin(app_fn, offset=app_addr) elif app_format == 'hex': print("Loading application from hex file") ih.fromfile(app_fn, format=app_format) # output to file ih.tofile(output_fn, format=output_fn.split('.')[-1])
def main(argv): if len(argv) != 2: print('challenger.py <hexfile> <serialport>') sys.exit(2) # Check if hexfile exists hexfile = argv[0] if not os.path.isfile(hexfile): print("ERROR: File not found:", hexfile) sys.exit(2) ih = IntelHex(hexfile) ser = serial.Serial(argv[1], 9600) time.sleep(1) # Generate nonce nonce = os.urandom(20) print("Nonce: ") print(binascii.hexlify(nonce)) # Send nonce to prover ser.write(nonce) # Wait for answer 'o' --> OK -- This is only for debugging purposes, to make sure that the nonce is received. answer = ser.read() while answer != b'o': answer = ser.read() print(answer) #Calc digest hmac_gen = hmac.new(key, None, hashlib.sha1) hmac_gen.update(ih.tobinstr(0,32*1024-1)) #32*1024-1 hmac_gen.update(nonce) print("Expected response:"); print(binascii.hexlify(hmac_gen.digest())) # Get digest from mote mote_digest = ser.read(20) print("Prover response:"); print(binascii.hexlify(mote_digest))
def program_flash(programmer, in_file, start_address, erase, verify, force_bin, log_function): image_array = in_file.read() if image_array.startswith(b':') and not force_bin: print( "File type detected as Intel Hex -- converting to binary before flashing..." ) print("To force flashing as-is, pass --bin.") # HACK: The IntelHex class expects a filename or file-like object, but...we've already read the file. # So let's wrap it in a file-like object. Normally, we'd use io.BytesIO, # except IntelHex wants strings, not bytes objects. So... intel_hex = IntelHex(io.StringIO(image_array.decode('ascii'))) image_array = intel_hex.tobinstr() log_function("Writing data to flash...") programmer.program_flash(image_array, erase=erase, verify=verify, start=start_address)
def main(): parser = argparse.ArgumentParser(description="Bootloader CRC patcher") parser.add_argument('filename', help='Intel HEX file to patch') args = parser.parse_args() if not args.filename.lower().endswith('.hex'): print("Not a .hex file?") return ih = IntelHex() ih.loadhex(args.filename) data = ih.tobinstr(start=0, size=0x100) offset = data.find(b'\xCC\xCC') if offset < 0: return crc = fixcrc16pos(data, offset) print('Patching with CRC of %04X' % crc) ih[offset] = crc >> 8 ih[offset + 1] = crc & 255 #data = ih.tobinstr(start=0, size=0x100) #print('Final CRC = %04X' % crc16(data)) ih.write_hex_file(args.filename)
def write_hex_file(self, fname): print "Loading input file", fname ih = IntelHex(fname) input_crc = atmel_crc(ih.tobinstr(start=0, end=self.memsize, pad=0xff)) print "Size=%s; CRC=%s"%(ih.maxaddr(), hex(input_crc)) print "Erasing...", self.erase() print "done" print "Flashing...", self.program(ih) dev_crc = self.app_crc() print "Checked CRC is", hex(dev_crc) if input_crc == dev_crc: print "CRC matches" print "Resetting" self.reset() else: print "CRC DOES NOT MATCH"
def write_hex_file(self, fname): print "Loading input file", fname ih = IntelHex(fname) input_crc = atmel_crc(ih.tobinstr(start=0, end=self.memsize, pad=0xff)) print "Size=%s; CRC=%s" % (ih.maxaddr(), hex(input_crc)) print "Erasing...", self.erase() print "done" print "Flashing...", self.program(ih) dev_crc = self.app_crc() print "Checked CRC is", hex(dev_crc) if input_crc == dev_crc: print "CRC matches" print "Resetting" self.reset() else: print "CRC DOES NOT MATCH"
async def file_service(): # config r/w for cfg in os.listdir('configs'): if cfg.endswith('.json'): csa['cfgs'].append(cfg) sock = CDWebSocket(ws_ns, 'file') while True: dat, src = await sock.recvfrom() logger.debug(f'file ser: {dat}') if dat['action'] == 'get_cfgs': await sock.sendto(csa['cfgs'], src) elif dat['action'] == 'get_cfg': with open(os.path.join('configs', dat['cfg'])) as c_file: c = json5.load(c_file) await sock.sendto(c, src) elif dat['action'] == 'get_ihex': ret = [] ih = IntelHex() try: ih.loadhex(dat['path']) segs = ih.segments() logger.info( f'parse ihex file, segments: {[list(map(hex, l)) for l in segs]} (end addr inclusive)' ) for seg in segs: s = [seg[0], ih.tobinstr(seg[0], size=seg[1] - seg[0])] ret.append(s) except Exception as err: logger.error(f'parse ihex file error: {err}') await sock.sendto(ret, src) else: await sock.sendto('err: file: unknown cmd', src)
def main(argv): inputfile = '' port = '' split = 1024 usage_string = 'huzzah_exotag_firmware.py -i <inputfile> -p <comm port:/dev/ttyUSB or \\\.\COM12>' try: opts, args = getopt.getopt(argv, "hi:p:s:", ["file=", "port=", "split="]) except getopt.GetoptError: print() sys.exit(2) if not opts: print("no arguments provided ") print(usage_string) sys.exit(2) for opt, arg in opts: if opt == '-h': print(usage_string) sys.exit() elif opt in ("-i", "--file"): inputfile = arg elif opt in ("-p", "--port"): port = arg elif opt in ("-s", "--split"): split = int(arg) else: print("wrong arguments: " + opt) print(usage_string) print('input file: ' + inputfile) print('output port: ' + port) print('split in bytes: %d' % split) if inputfile.endswith('.hex'): ih = IntelHex() # create empty object ih.padding = 0xFF ih.fromfile(inputfile, format='hex') # also load from hex ascii_bin = binascii.hexlify(ih.tobinstr()) #sys.exit() elif inputfile.endswith( '.bin' ): #reconsider the extension here, the routine actually handles ascii with open(inputfile, 'r') as f: read_data = f.read() f.closed read_data = read_data.rstrip('\r\n') print(read_data) print([n for n in read_data]) ascii_bin = read_data #binascii.unhexlify(read_data) #sys.exit() #print(ascii_bin) crc_result = binascii.crc32(ascii_bin) & 0xffffffff print("CRC = %08x" % crc_result) #sys.exit() exotag_uart = serial.Serial(port, 115200, timeout=1) exotag_uart_io = io.TextIOWrapper( io.BufferedRWPair(exotag_uart, exotag_uart)) print('send start update: ' + unicode('exotag=update\r')) exotag_uart_io.write(unicode('exotag=update'.rstrip() + '\r')) exotag_uart_io.flush() time.sleep(1) #print (exotag_uart.readline()) print('write') for i in range(0, len(ascii_bin), split): print((ascii_bin[i:i + split])) exotag_uart.write((ascii_bin[i:i + split])) exotag_uart_io.flush() time.sleep(1) print(binascii.hexlify(struct.pack("<I", crc_result))) exotag_uart.write('!'.encode() + struct.pack("<I", crc_result)) exotag_uart_io.flush() #time.sleep(1) print('send end of firmware update') exotag_uart_io.write(unicode('~')) exotag_uart_io.flush() print('read exotag messages') exotag_string = exotag_uart_io.read() print("***********************\r\n" + exotag_string + "\r\n***********************") if (-1 != exotag_string.find('firmware update: SUCCESS')): print('tell huzzah to push update to exotag') exotag_uart_io.write(unicode('exotag=program'.rstrip() + '\r')) exotag_uart_io.flush() #time.sleep(10) print('read exotag messages') time.sleep(5) exotag_string = exotag_uart_io.read() print("***********************\r\n" + exotag_string + "\r\n***********************") if (-1 != exotag_string.find( 'EFM8 flash write read-back verify success')): print( 'EFM8 flash write read-back verify success - indicates SUCCESS' ) print('reset exotag') exotag_uart_io.write(unicode('exotag=reset'.rstrip() + '\r')) exotag_uart_io.flush() time.sleep(5) exotag_string = exotag_uart_io.read() print("***********************\r\n" + exotag_string + "\r\n***********************") exotag_uart.close()
def post_process(self): logging.info("Processing binaries") fw_info_fmt = '<I16s128s16s128s16s' fw_info_addr = int(self.settings["FW_INFO_ADDR"], 16) # save original dir cwd = os.getcwd() # change to target dir os.chdir(self.target_dir) ih = IntelHex('main.hex') fwid = uuid.UUID('{' + self.settings["FWID"] + '}') # get KV meta start kv_meta_addr = fw_info_addr + struct.calcsize(fw_info_fmt) kv_meta_len = KVMetaField().size() bindata = ih.tobinstr() kv_meta_data = [] while True: kv_meta = KVMetaField().unpack(bindata[kv_meta_addr:kv_meta_addr + kv_meta_len]) kv_meta_addr += kv_meta_len if kv_meta.param_name == "kvstart": continue elif kv_meta.param_name == "kvend": break else: kv_meta_data.append(kv_meta) kv_meta_by_hash = {} logging.info("Hash type: FNV1A_32") # create lookups by 32 bit hash index = 0 for kv in kv_meta_data: hash32 = fnv1a_32(str(kv.param_name)) if hash32 in kv_meta_by_hash: raise Exception("Hash collision!") kv_meta_by_hash[hash32] = (kv, index) index += 1 # sort indexes sorted_hashes = sorted(kv_meta_by_hash.keys()) # create binary look up table kv_index = '' for a in sorted_hashes: kv_index += struct.pack('<LB', a, kv_meta_by_hash[a][1]) # write to end of hex file ih.puts(ih.maxaddr() + 1, kv_index) size = ih.maxaddr() - ih.minaddr() + 1 # get os info try: os_project = get_project_builder(self.settings["OS_PROJECT"], target=self.target_type) except KeyError: os_project = "" # create firmware info structure fw_info = struct.pack(fw_info_fmt, size, fwid.bytes, os_project.proj_name, os_project.version, str(self.settings['PROJ_NAME']), self.version) # insert fw info into hex ih.puts(fw_info_addr, fw_info) # compute crc crc_func = crcmod.predefined.mkCrcFun('crc-aug-ccitt') crc = crc_func(ih.tobinstr()) logging.info("size: %d" % (size)) logging.info("fwid: %s" % (fwid)) logging.info("fwinfo: %x" % (fw_info_addr)) logging.info("kv index len: %d" % (len(kv_index))) logging.info("crc: 0x%x" % (crc)) logging.info("os name: %s" % (os_project.proj_name)) logging.info("os version: %s" % (os_project.version)) logging.info("app name: %s" % (self.settings['PROJ_NAME'])) logging.info("app version: %s" % (self.version)) ih.puts(ih.maxaddr() + 1, struct.pack('>H', crc)) ih.write_hex_file('main.hex') ih.tobinfile('firmware.bin') # get loader info loader_project = get_project_builder(self.settings["LOADER_PROJECT"], target=self.target_type) # create loader image loader_hex = os.path.join(loader_project.target_dir, "main.hex") self.merge_hex('main.hex', loader_hex, 'loader_image.hex') # create sha256 of binary sha256 = hashlib.sha256(ih.tobinstr()) # create manifest file data = { 'name': self.settings['FULL_NAME'], 'timestamp': datetime.utcnow().isoformat(), 'sha256': sha256.hexdigest(), 'fwid': self.settings['FWID'], 'version': self.version } with open('manifest.txt', 'w+') as f: f.write(json.dumps(data)) # create firmware zip file zf = zipfile.ZipFile('chromatron_main_fw.zip', 'w') zf.write('manifest.txt') zf.write('firmware.bin') zf.close() # create second, project specific zip # we'll remove the first zip after # we update the firmware tools zf = zipfile.ZipFile('%s.zip' % (self.settings['PROJ_NAME']), 'w') zf.write('manifest.txt') zf.write('firmware.bin') zf.close() # change back to original dir os.chdir(cwd) logging.info("Package dir: %s" % (get_build_package_dir())) # make sure we have the firmware package dir try: os.makedirs(get_build_package_dir()) except OSError: pass # copy firmware zip try: shutil.copy( os.path.join(self.target_dir, '%s.zip' % (self.proj_name)), get_build_package_dir()) except IOError: raise AppZipNotFound # update build date with open( os.path.join(get_build_package_dir(), firmware_package.PUBLISHED_AT_FILENAME), 'w') as f: f.write(util.now().isoformat())
def get_file_buf(self, filename): fil = open(filename, 'r') hexfile = IntelHex(fil) glog.info('Min addr >> ', hexfile.minaddr()) assert hexfile.minaddr() == 0 return hexfile.tobinstr()
}) if options.hexfiles: for hex in options.hexfiles: ih = IntelHex(hex) for (address, end) in ih.segments(): try: address = address & 0xFFFFFFFF except ValueError: print "Address %s invalid." % address sys.exit(1) target.append({ 'address': address, 'data': ih.tobinstr(start=address, end=end - 1) }) outfile = args[0] device = DEFAULT_DEVICE if options.device: device = options.device try: v, d = [int(x, 0) & 0xFFFF for x in device.split(':', 1)] except: print("Invalid device '%s'." % device) sys.exit(1) build(outfile, [target], DEFAULT_NAME, device) elif options.s19files and len(args) == 1: address = 0 data = ""
header_addr = prog.minaddr() # all programs require there header to be located at the start # read out the header header = ih2header(prog) # optional updates if args.pid != None and args.pid >= 0 and args.pid < 256: header['pid'] = args.pid if args.key != None: header['key'] = args.key if args.hw != None: header['hw_id'] = args.hw # update the header len l = prog.maxaddr() - prog.minaddr() + 1 header['len'] = l prog = header2ih(prog, header) # put the length back into the intel hex file for crc # update the header crc (note we do no include the CRC word in the CRC) crc_start_addr = prog.minaddr() + 4 prog.padding = 0xff buf = prog.tobinstr(start=crc_start_addr) crc.crc_init(crc.stm32f10x_crc_h) crc = crc.crc_buf(crc.stm32f10x_crc_h, buf, len(buf)) & 0xffffffff header['crc'] = crc prog = header2ih(prog, header) # put the crc back into the intel hex file so we can write it out # write header back to hex file prog.write_hex_file(sys.stdout)
%prog {-i|--ihex} file.hex [-i file.hex ...] [{-D|--device}=vendor:device] outfile.dfu""" parser = OptionParser(usage=usage) parser.add_option("-i", "--ihex", action="append", dest="hexfiles", help="build a DFU file from given HEXFILES", metavar="HEXFILES") parser.add_option("-D", "--device", action="store", dest="device", help="build for DEVICE, defaults to %s" % DEFAULT_DEVICE, metavar="DEVICE") (options, args) = parser.parse_args() if options.hexfiles and len(args)==1: target = [] for h in options.hexfiles: ih = IntelHex(h) for (s,e) in ih.segments(): target.append({ 'address': s, 'data': ih.tobinstr(s,e-1) }) outfile = args[0] device = DEFAULT_DEVICE if options.device: device=options.device try: v,d=map(lambda x: int(x,0) & 0xFFFF, device.split(':',1)) except: print("Invalid device '%s'." % device) sys.exit(1) build(outfile,[target],device) else: parser.print_help() sys.exit(1)
mergedHex.merge(fillHex, 'ignore') mergedHex = mergedHex[ startAddr:endAddr] # +1 since the last address is not inclusive mergedHex.padding = vargs.fill #if we are calculating metadata #Offchip OAD production images and NP images don't have embedded metadata headers, skip meta data calc for these #All onchip OAD images need metdata placement if not (vargs.oadtype == 'offchip' and (vargs.imgtype == 'production' or vargs.imgtype == 'np')): # Place metadata, onchip production image expects header at 0x600 if vargs.oadtype == 'onchip' and vargs.imgtype == 'production': residentHdr = OadHdr._make( struct.unpack( OAD_HDR_FMT, mergedHex.tobinstr(INT_FL_OAD_IMG_A_META_BEGIN, INT_FL_OAD_IMG_A_META_BEGIN + 15))) else: residentHdr = OadHdr._make( struct.unpack(OAD_HDR_FMT, mergedHex.tobinstr(startAddr, startAddr + 15))) metaAddr = vargs.meta if metaAddr is None: # Try first address, ideally there should be free space at the beginning of the image #in the reserved image metadata sector #if onchip production image, we must start at imgA start with is 0x600 if vargs.oadtype == 'onchip' and vargs.imgtype == 'production': attemptedMetaStart = INT_FL_OAD_IMG_A_META_BEGIN else: attemptedMetaStart = mergedHex.minaddr() beginning = mergedHex.gets(attemptedMetaStart, OAD_METADATA_SIZE)
ih = IntelHex(fw_file) sig = base64.b64decode(helpers.from_websafe(data["versions"][">2.5.3"]["signature"]).encode()) client = solo.client.find() client.use_hid() if not client.is_solo_bootloader(): print("[!] Please put the SoloKey in bootloader mode") exit(1) # desired_version = b"\x03\x00\x00\x00" # make the bootloader believe we're flashing 3.0.0.0 # desired_version = b"\x03\x00\x00\x02" # make the bootloader believe we're flashing 3.0.0.2 desired_version = b"\x03\x00\x25\x00" # make the bootloader believe we're flashing 3.0.37.0 version_offset = ih.tobinstr().find(desired_version) correct_version_offset = ih.tobinstr().rfind(b"\x03\x00\x00\x00") if version_offset == -1: print("Cannot find version bytes!") exit(1) print("[+] Using version bytes at offset 0x{:x} instead of 0x{:x}".format(version_offset, correct_version_offset)) print("[+] Flashing firmware...") chunk_size = 2048 start_address, end_address = ih.segments()[0] version_bytes_address = start_address + version_offset for chunk_start in tqdm(range(start_address, end_address, chunk_size)): chunk_end = min(chunk_start + chunk_size, end_address) data = ih.tobinarray(start=chunk_start, size=chunk_end - chunk_start)
except ValueError: print("Address %s invalid." % address) sys.exit(1) if not os.path.isfile(binfile): print("Unreadable file '%s'." % binfile) sys.exit(1) target.append({ 'address': address, 'data': open(binfile, 'rb').read() }) if options.hexfiles: for hex in options.hexfiles: ih = IntelHex(hex) address = ih.minaddr() data = ih.tobinstr() try: address = address & 0xFFFFFFFF except ValueError: print("Address %s invalid." % address) sys.exit(1) target.append({'address': address, 'data': data}) outfile = args[0] device = DEFAULT_DEVICE if options.device: device = options.device try: v, d = map(lambda x: int(x, 0) & 0xFFFF, device.split(':', 1)) except: print("Invalid device '%s'." % device)
print " Freqency=%03.02f Mhz (calculated)" % freq except: print "%s: Cannot decode frequency" % name dump=IntelHex(source) # Unpack fields # 14 - String - Working station # 2 = HEX - Working CRC # 14 - String - Factory station # 2 = HEX - Factory CRC #payload = list(unpack_from('<14sH14sH17sBB2s13s17s', dump.tobinstr())) payload = list(unpack_from('<14sH', dump.tobinstr())) #if not (eyecatcher in payload[9]): #print "NOTE:Eyecatcher text string not found" print "---Working" dump_freq(payload[0], payload[1]) print "---Factory" dump_freq(payload[2], payload[3]) print "SN: %s" % payload[4].strip('\000') print "WW: %d" % payload[5] print "YY: %d" % payload[6] print "Station: %s" % payload[7] print "Campaign: %s" % payload[8].strip('\000')
# read out the header header = ih2header(prog) # optional updates if args.pid != None and args.pid >= 0 and args.pid < 256: header['pid'] = args.pid if args.key != None: header['key'] = args.key if args.hw != None: header['hw_id'] = args.hw # update the header len l = prog.maxaddr() - prog.minaddr() + 1 header['len'] = l prog = header2ih(prog, header) # put the length back into the intel hex file for crc # update the header crc (note we do no include the CRC word in the CRC) crc_start_addr = prog.minaddr() + 4 prog.padding = 0xff buf = prog.tobinstr(start=crc_start_addr) crc.crc_init(crc.stm32f10x_crc_h) crc = crc.crc_buf(crc.stm32f10x_crc_h, buf, len(buf)) & 0xffffffff header['crc'] = crc prog = header2ih( prog, header) # put the crc back into the intel hex file so we can write it out # write header back to hex file prog.write_hex_file(sys.stdout)
# if specified, the script will pad the image with the pad value fillHex = IntelHex() fillHex.puts(startAddr, struct.pack("B", vargs.fill) * (endAddr)) mergedHex.merge(fillHex, "ignore") mergedHex = mergedHex[startAddr:endAddr] # +1 since the last address is not inclusive mergedHex.padding = vargs.fill # if we are calculating metadata # Offchip OAD production images and NP images don't have embedded metadata headers, skip meta data calc for these # All onchip OAD images need metdata placement if not (vargs.oadtype == "offchip" and (vargs.imgtype == "production" or vargs.imgtype == "np")): # Place metadata, onchip production image expects header at 0x600 if vargs.oadtype == "onchip" and vargs.imgtype == "production": residentHdr = OadHdr._make( struct.unpack( OAD_HDR_FMT, mergedHex.tobinstr(INT_FL_OAD_IMG_A_META_BEGIN, INT_FL_OAD_IMG_A_META_BEGIN + 15) ) ) else: residentHdr = OadHdr._make(struct.unpack(OAD_HDR_FMT, mergedHex.tobinstr(startAddr, startAddr + 15))) metaAddr = vargs.meta if metaAddr is None: # Try first address, ideally there should be free space at the beginning of the image # in the reserved image metadata sector # if onchip production image, we must start at imgA start with is 0x600 if vargs.oadtype == "onchip" and vargs.imgtype == "production": attemptedMetaStart = INT_FL_OAD_IMG_A_META_BEGIN else: attemptedMetaStart = mergedHex.minaddr() beginning = mergedHex.gets(attemptedMetaStart, OAD_METADATA_SIZE)
def main(): platforms = [x.name.lower() for x in Platform] functions = [x.name.lower() for x in ModuleFunction] flags = [x.name.lower() for x in ModuleFlags] parser = argparse.ArgumentParser( description='Convert a raw binary into a Particle module binary') parser.add_argument('input', metavar='INPUT', type=argparse.FileType('rb'), help='Input raw bin file') parser.add_argument('output', metavar='OUTPUT', type=argparse.FileType('wb'), help='Output Particle module bin file') parser.add_argument('--address', default=0, type=int, help='Start address of the module') parser.add_argument( '--version', default=0, type=int, help='Module version (automatically derived for Gen 3 SoftDevice)') parser.add_argument('--platform', required=True, help='Module platform name', choices=platforms) parser.add_argument('--function', required=True, help='Module function', choices=functions) parser.add_argument('--index', default=0, type=int, help='Module index number') parser.add_argument('--dependency', default=[], nargs=3, action='append', metavar=('FUNCTION', 'VERSION', 'INDEX'), help='Module dependency') parser.add_argument('--mcu', type=int, default=0, help='MCU target') parser.add_argument('--flag', default=[], help='Module flag', action='append', choices=flags) args = parser.parse_args() dependencies = [parse_dependency(x) for x in args.dependency] platform = Platform[args.platform.upper()] function = ModuleFunction[args.function.upper()] flags = reduce(lambda x, y: x | y, [ModuleFlags[x.upper()] for x in args.flag], ModuleFlags.NONE) version = args.version if not args.input.name.endswith('.hex'): bin = args.input.read() else: try: from intelhex import IntelHex # Reopen in non-binary mode :| name = args.input.name args.input.close() with open(args.input.name, 'r') as f: ihex = IntelHex(f) bin = ihex.tobinstr() except ImportError: print('`intelhex` library is required for hex file support') sys.exit(1) except: raise # Special handling for Gen 3 SoftDevice if platform in GEN3_PLATFORMS and function == ModuleFunction.RADIO_STACK and args.version == 0: (version, ) = struct.unpack_from('<H', bin, GEN3_RADIO_STACK_VERSION_OFFSET) if len(dependencies) == 0: dependencies = [ GEN3_RADIO_STACK_DEPENDENCY, GEN3_RADIO_STACK_DEPENDENCY2 ] if args.address == 0: # Skip MBR args.address = GEN3_RADIO_STACK_MBR_OFFSET bin = bin[GEN3_RADIO_STACK_MBR_OFFSET:] if len(args.flag) == 0: flags = GEN3_RADIO_STACK_FLAGS m = Module(bin, args.address, platform, function, version, args.index, flags, dependencies, mcu=args.mcu) args.output.write(m.dump()) print(m)
class ShdlcFirmwareImage(object): """ This class represents a firmware image for an SHDLC device. It is used to load and verify Intel-Hex files for performing firmware updates over SHDLC. Since the different SHDLC devices use different memory layouts, this class needs to know the bootloader base address and application base address (see constructor parameters). Drivers for specific SHDLC devices should create a subclass to provide a new type which already contains the correct addresses, so users don't have to care about these details. .. note:: This class is intended only for devices which contain the SHDLC bootloader. Devices which support firmware updates with another system aren't supported by this class. .. note:: The package ``intelhex`` must be installed to use this class. See :ref:`firmware-updater-dependencies` for details. """ _PRODUCT_TYPE_SIZE = 4 # Product type size def __init__(self, hexfile, bl_start_addr, app_start_addr, signature=b'\x4A\x47\x4F\x4B', bl_version_offset=0x1004): """ Constructor which loads and parses the firmware from a hex file. :param str/file hexfile: The filename or file-like object containing the firmware in Intel-Hex format (\\*.hex). :param int bl_start_addr: The base address of the bootloader inside the firmware image. :param int app_start_addr: The base address of the application inside the firmware image. :param bytes signature: Signature bytes used for the application. :param int bl_version_offset: Bootloader version address offset. :raise ~sensirion_shdlc_driver.errors.ShdlcFirmwareImageSignatureError: If the signature of the image is invalid. """ # Import intelhex here to allow importing the firmware_image module # without having the intelhex package installed (it's an optional # dependency, so it might be missing). from intelhex import IntelHex self._bl_start_addr = int(bl_start_addr) self._app_start_addr = int(app_start_addr) self._signature = bytes(bytearray(signature)) self._bl_version_offset = int(bl_version_offset) self._app_data_index = 0 self._data = IntelHex(hexfile) self._data.padding = 0xFF # is returned when reading undefined regions log.debug( "Loaded hex file: {} [minaddr=0x{:08X}, maxaddr=0x{:08X}]".format( hexfile, self._data.minaddr(), self._data.maxaddr())) self._check_signature() log.debug("Signature: OK") self._product_type = self._read_product_type() log.debug("Product type: 0x{:08X}".format(self._product_type)) self._bootloader_version = self._read_bootloader_version() log.debug("Bootloader version: {}".format(self._bootloader_version)) self._application_version = self._read_application_version() log.debug("Application version: {}".format(self._application_version)) self._app_data = self._read_application_data() log.debug("Application size: {:.2f} kB".format(self.size / 1024)) self._checksum = self._calc_application_checksum() log.debug("Application checksum: 0x{:02X}".format(self._checksum)) @property def product_type(self): """ Get the product type for which the loaded firmware is made. :return: Product type as an integer. :rtype: int """ return self._product_type @property def bootloader_version(self): """ Get the bootloader version which is contained in the loaded image. :return: Bootloader version (note: debug flag is not supported, it's always False). :rtype: ~sensirion_shdlc_driver.types.FirmwareVersion """ return self._bootloader_version @property def application_version(self): """ Get the application firmware version which is contained in the loaded image. :return: Application firmware version (note: debug flag is not supported, it's always False). :rtype: ~sensirion_shdlc_driver.types.FirmwareVersion """ return self._application_version @property def checksum(self): """ Get the checksum over the application firmware part of the loaded image. This is the checksum which needs to be sent to the product bootloader. :return: Checksum as a byte. :rtype: byte """ return self._checksum @property def size(self): """ Get the size of the application firmware. :return: Size in bytes. :rtype: int """ return len(self._app_data) @property def available_bytes(self): """ Get the count of available bytes left. :return: Count of available bytes. :rtype: int """ return len(self._app_data) - self._app_data_index def read(self, size=-1): """ Read the next bytes of the application firmware. :param int size: Maximum count of bytes to read (-1 reads all available) :return: Firmware data block. :rtype: bytes """ if size < 0: size = self.available_bytes else: size = min(size, self.available_bytes) data = self._app_data[self._app_data_index:self._app_data_index + size] self._app_data_index += len(data) return bytes(data) # immutable type to avoid modifying image data def _check_signature(self): """ Check the signature of the loaded image and throw an exception if it's invalid. """ signature = self._read_bytes(self._app_start_addr, len(self._signature)) if signature != self._signature: raise ShdlcFirmwareImageSignatureError(signature) def _read_product_type(self): """ Read the product type from the loaded image. :return: The read product type. :rtype: int """ address = self._app_start_addr + len(self._signature) return self._read_uint32(address) def _read_bootloader_version(self): """ Read the bootloader version from the loaded image. :return: The read bootloader version. :rtype: ~sensirion_shdlc_driver.types.FirmwareVersion """ addr_major = self._bl_start_addr + self._bl_version_offset + 1 addr_minor = self._bl_start_addr + self._bl_version_offset return FirmwareVersion(major=self._data[addr_major], minor=self._data[addr_minor], debug=False) def _read_application_version(self): """ Read the application version from the loaded image. :return: The read application version. :rtype: ~sensirion_shdlc_driver.types.FirmwareVersion """ addr_major = self._app_start_addr + len(self._signature) + \ self._PRODUCT_TYPE_SIZE + 1 addr_minor = self._app_start_addr + len(self._signature) + \ self._PRODUCT_TYPE_SIZE return FirmwareVersion(major=self._data[addr_major], minor=self._data[addr_minor], debug=False) def _read_application_data(self): """ Read the application data block from the loaded image. :return: The read application data block. :rtype: bytearray """ # Skip the signature because it must not be sent to the bootloader! start_addr = self._app_start_addr + len(self._signature) if self._bl_start_addr > self._app_start_addr: end_addr = self._bl_start_addr - 1 # Don't include bootloader else: end_addr = self._data.maxaddr() return bytearray(self._data.tobinarray(start=start_addr, end=end_addr)) def _read_uint32(self, address): """ Read an uint32 at a specific image address. :param int address: The address to read from. :return: The integer at the specified address. :rtype: int """ return unpack("<I", self._data.tobinarray(start=address, size=4))[0] def _read_bytes(self, address, number_of_bytes): """ Read at a specific image address. :param int address: The address to read from. :param int number_of_bytes: Number of bytes to read :return: The bytes from the specified address. :rtype: bytes """ return self._data.tobinstr(start=address, size=number_of_bytes) def _calc_application_checksum(self): """ Calculate the checksum over the application data, as needed for the firmware download command. :return: Checksum of application data :rtype: byte """ return (sum(self._app_data) % 256) ^ 0xFF
def cmd_update(args): if args.reset_tty: sys.stdout.write("resetting to bootloader via serial\n") serial = Tl866Driver(args.reset_tty) serial.cmd_reset_to_bootloader() # wait for the device to show up devs = None stop_time = time.time() + 5 # timeout 5s while not devs and time.time() < stop_time: time.sleep(0.100) devs = driver.list_devices() dev = find_dev() report = dev.report() if report.status != dev.STATUS_BOOTLOADER: sys.stdout.write("resetting to bootloader\n") dev.reset() report = dev.report() if report.status != dev.STATUS_BOOTLOADER: sys.stderr.write("device did not reset to booloader\n") sys.exit(2) model_a = (report.model == dev.MODEL_TL866A) # load the firmware image stock = None image = None if args.stock: with open(args.firmware, 'rb') as source: stock = firmware.UpdateFile(source.read()) image = firmware.Firmware( stock.a_firmware if model_a else stock.cs_firmware, encrypted=True, ) else: with open(args.firmware, 'r') as source: hexfile = IntelHex(source) image = firmware.Firmware( hexfile.tobinstr(start=0x1800, end=0x1FBFF), encrypted=False, ) # load encryption and erase keys target_key = None target_erase = None if args.keys_from: with open(args.keys_from, 'rb') as source: keyfile = firmware.UpdateFile(source.read()) keyfw = firmware.Firmware( keyfile.a_firmware if model_a else keyfile.cs_firmware, encrypted=True, ) target_key = keyfw.key target_erase = keyfile.a_erase if model_a else keyfile.cs_erase elif stock: target_key = image.key target_erase = stock.a_erase if model_a else stock.cs_erase else: target_key = firmware.KEY_A if model_a else firmware.KEY_CS target_erase = firmware.ERASE_A if model_a else firmware.ERASE_CS if not image.valid: raise RuntimeError("firmware image invalid") sys.stdout.write("erasing\n") dev.erase(target_erase) sys.stdout.write("programming\n") addr = 0x1800 cryptbuf = image.encrypt(target_key) for off in range(0, len(cryptbuf), 80): dev.write(addr, 80, cryptbuf[off:off + 80]) addr += 64 sys.stdout.write("success!\n") report = dev.report() if report.status != dev.STATUS_NORMAL: sys.stdout.write("resetting to firmware\n") dev.reset()
def parse_args(): parser = argparse.ArgumentParser( description='Hash data from file.', formatter_class=argparse.RawDescriptionHelpFormatter) parser.add_argument( '--infile', '-i', '--in', '-in', required=True, help= 'Hash the contents of the specified file. If a *.hex file is given, the contents will ' 'first be converted to binary, with all non-specified area being set to 0xff. ' 'For all other file types, no conversion is done.') return parser.parse_args() if __name__ == '__main__': args = parse_args() if args.infile.endswith('.hex'): ih = IntelHex(args.infile) ih.padding = 0xff # Allows hashing with empty regions to_hash = ih.tobinstr() else: to_hash = open(args.infile, 'rb').read() sys.stdout.buffer.write(hashlib.sha256(to_hash).digest())
checkbin(binfile) target.append({ 'address': address, 'data': open(binfile,'rb').read() }) if options.hexfiles: if not IntelHex: print("Error: IntelHex python module could not be found") sys.exit(1) for hex in options.hexfiles: ih = IntelHex(hex) for (address,end) in ih.segments(): try: address = address & 0xFFFFFFFF except ValueError: print "Address %s invalid." % address sys.exit(1) target.append({ 'address': address, 'data': ih.tobinstr(start=address, end=end-1)}) outfile = args[0] device = DEFAULT_DEVICE if options.device: device=options.device try: v,d=[int(x,0) & 0xFFFF for x in device.split(':',1)] except: print("Invalid device '%s'." % device) sys.exit(1) build(outfile,[target],DEFAULT_NAME,device) elif options.s19files and len(args)==1: address = 0 data = "" target = []
raise ApplicationError, 'No any DKSF*.hex files found!' hexfn = sorted(hexfnlist, key=os.path.getmtime)[-1] print print os.path.abspath(hexfn) bootfn = glob.glob('..\\..\\Bootloader_Debug\\Exe\\*.hex') if len(bootfn) != 1: raise ApplicationError, 'More than one bootloader .hex file found!' bootfn = os.path.abspath(bootfn[0]) print bootfn ih = IntelHex(hexfn) blih = IntelHex(bootfn) ih.padding = 0xff code = ih.tobinstr(start=fw_offset, end=fw_offset+fw_length-1) res = ih.tobinstr(start=res_offset, end=res_offset+res_length-1) ver_data_offset = code.index(verdatastart) + len(verdatastart) model, version, subversion, litera, assmcode =\ struct.unpack_from('<HHHcB', code, ver_data_offset) ver = str(model) + '.' + str(version) + '.' + str(subversion) + '.' + litera + '-' + str(assmcode) print 'Extracted version data:', ver print 'Merging bootloader file...', ih.start_addr = None # program start addr record will be from BL part try: ih.merge(blih, overlap='error') print 'Ok' except AddressOverlapError: print ' probably already merged, data overlap! CHECK THIS!'
%prog {-i|--ihex} file.hex [-i file.hex ...] [{-D|--device}=vendor:device] outfile.dfu""" parser = OptionParser(usage=usage) parser.add_option("-i", "--ihex", action="append", dest="hexfiles", help="build a DFU file from given HEXFILES", metavar="HEXFILES") parser.add_option("-D", "--device", action="store", dest="device", help="build for DEVICE, defaults to %s" % DEFAULT_DEVICE, metavar="DEVICE") (options, args) = parser.parse_args() if options.hexfiles and len(args)==1: target = [] for h in options.hexfiles: ih = IntelHex(h) for (s,e) in ih.segments(): target.append({ 'address': s, 'data': ih.tobinstr(s,e-1) }) outfile = args[0] device = DEFAULT_DEVICE if options.device: device=options.device try: v,d=map(lambda x: int(x,0) & 0xFFFF, device.split(':',1)) except: print "Invalid device '%s'." % device sys.exit(1) build(outfile,[target],device) else: parser.print_help() sys.exit(1)
sys.exit(1) try: address = int(address,0) & 0xFFFFFFFF except ValueError: print("Address %s invalid." % address) sys.exit(1) if not os.path.isfile(binfile): print("Unreadable file '%s'." % binfile) sys.exit(1) target.append({ 'address': address, 'data': open(binfile,'rb').read() }) if options.hexfiles: for hex in options.hexfiles: ih = IntelHex(hex) address = ih.minaddr() data = ih.tobinstr() try: address = address & 0xFFFFFFFF except ValueError: print("Address %s invalid." % address) sys.exit(1) target.append({ 'address': address, 'data': data }) revision = DEFAULT_REVISION if options.revision: try: rev2byte(options.revision) revision = options.revision except ValueError: print("Invalid revision value.") sys.exit(1)
#if specified, the script will pad the image with the pad value fillHex = IntelHex() fillHex.puts(startAddr, struct.pack('B', vargs.fill) * (endAddr)) mergedHex.merge(fillHex, 'ignore') mergedHex = mergedHex[startAddr:endAddr] # +1 since the last address is not inclusive mergedHex.padding = vargs.fill #if we are calculating metadata #Offchip OAD production images and NP images don't have embedded metadata headers, skip meta data calc for these #All onchip OAD images need metdata placement if not(vargs.oadtype == 'offchip' and (vargs.imgtype == 'production' or vargs.imgtype == 'np')): # Place metadata, onchip production image expects header at 0x600 if vargs.oadtype == 'onchip' and vargs.imgtype == 'production': residentHdr = OadHdr._make(struct.unpack(OAD_HDR_FMT, mergedHex.tobinstr(INT_FL_OAD_IMG_A_META_BEGIN, INT_FL_OAD_IMG_A_META_BEGIN+15))) else: residentHdr = OadHdr._make(struct.unpack(OAD_HDR_FMT, mergedHex.tobinstr(startAddr, startAddr+15))) metaAddr = vargs.meta if metaAddr is None: # Try first address, ideally there should be free space at the beginning of the image #in the reserved image metadata sector #if onchip production image, we must start at imgA start with is 0x600 if vargs.oadtype == 'onchip' and vargs.imgtype == 'production': attemptedMetaStart = INT_FL_OAD_IMG_A_META_BEGIN else: attemptedMetaStart = mergedHex.minaddr() beginning = mergedHex.gets(attemptedMetaStart, OAD_METADATA_SIZE)
out = open(sys.argv[2], 'wb') # Sanity checks, very important if ih.maxaddr() < 0x1004 or ih.maxaddr() > 32767: print "Insane hexfile: min=0x%x max=0x%x" % (ih.minaddr(), ih.maxaddr()) sys.exit(2) print "Length: %d / 28672" % (ih.maxaddr() - 4096 + 1) print "Free: %d" % (28672 - (ih.maxaddr() - 4096 + 1)) # Hack to force tobinstr() to write data from addres 0. IntelHex will # only write data from the first location with initialized data, skipping # over any uninitialized data beforehand. This initializes address 0, # forcing IntelHex to do what I want. ih[0]=ih[0] sumdata = (ih.tobinstr())[0x1004:] sumdata += '\xff' * (0x6ffc - len(sumdata)) cksum = binascii.crc32(sumdata) & 0xffffffff print "Checksum: 0x%08x" % cksum ih.puts(0x1000, struct.pack('<L', cksum)) # Rather than using IntelHex.tobinfile(), i'm writing to a file this way # to ensure that the file ends up at exactly 32768 bytes. binfw = ih.tobinstr() binfw += '\xff' * (0x8000 - len(binfw)) out.write(binfw) out.close() # Testing only. a=IntelHex() a.loadbin(sys.argv[2])
else: imgLen = int(math.ceil( (endAddr - startAddr) / 4.0)) # Image length in words imgVer = vargs.imgVer # Offchip OAD has no requirements for LSB usrId = vargs.usrId imgAddr = startAddr / 4 # In words imgType = imgTypes[vargs.imgtype] crcShdw = 0xffff meta = struct.pack('HHHH4sHBB', crcShdw, crcShdw, imgVer, imgLen, usrId, imgAddr, imgType, META_STATUS_SUCCESS) mergedHex.puts(metaAddr, meta) #production image only calculates over imgA region if vargs.oadtype == 'onchip' and vargs.imgtype == 'production': asBin = mergedHex.tobinstr(INT_FL_OAD_IMG_A_META_BEGIN, INT_FL_OAD_IMG_A_END) else: asBin = mergedHex.tobinstr(startAddr, endAddr - 1) crc = crc16(asBin[4:]) mergedHex.puts(metaAddr, struct.pack('H', crc)) metaVector = OadHdr._make([ crc, crcShdw, imgVer, imgLen, usrId, imgAddr, imgType, META_STATUS_SUCCESS ]) print_metadata(metaVector) if vargs.out and not (vargs.out is sys.stdout and vargs.outbin is sys.stdout): print("Writing to:\n", vargs.out.name)
print "%s: CRC mismatch" % name else: (band, deemph, spacing, chan, vol) = unpack('<BBBHB8x', info) try: freq = calc_freq(band, spacing, chan) print "%s: Freq %.2f MHz" % (name, freq) except: print "%s: Cannot decode frequency" % name print " Band: %02x" % band print " Deemphasis: %02x" % deemph print " Spacing: %02x" % spacing print " Channel: %d" % chan print " Volume: %02x" % vol dump=IntelHex(source) payload = list(unpack_from('<14sH14sH17sBB2s13s17s', dump.tobinstr())) if eyecatcher in payload[9]: dump_freq(payload[0], payload[1], "Working") dump_freq(payload[2], payload[3], "Factory") print "SN: %s" % payload[4].strip('\000') print "WW: %d" % payload[5] print "YY: %d" % payload[6] print "Station: %s" % payload[7] print "Campaign: %s" % payload[8].strip('\000') else: sys.exit(1)
def get_bootloader_hex_image(bootoaderFile): hex = IntelHex(bootoaderFile) hex.padding = 0x00 hexImage = hex.tobinstr(BOOTLOADER_START_ADDRESS, BOOTLOADER_END_ADDRESS) return hexImage