📄 tos-bsl.in
字号:
addr = addr - 1 #Decrement address and blkout = chr(0xFF) + blkOut #fill first byte of blkout with 0xFF length = length + 1 #Make sure that len is even if (length % 2) != 0: blkout = blkout + chr(0xFF) #Inc. len and fill last byte of blkout with 0xFF length = length + 1 elif cmd == self.BSL_RXBLK: #Align to even start address if (addr % 2) != 0: addr = addr - 1 #Decrement address but length = length + 1 #request an additional byte #Make sure that len is even if (length % 2) != 0: length = length + 1 #if cmd == self.BSL_TXBLK or cmd == self.BSL_TXPWORD: # length = len + 4 #Add necessary information data to frame dataOut = struct.pack("<HH", addr, length) if blkout: #Copy data out of blkout into frame dataOut = dataOut + blkout self.bslSync(wait) #synchronize BSL rxFrame = self.comTxRx(cmd, dataOut, len(dataOut)) #Send frame if rxFrame: #test answer return rxFrame[4:] #return only data w/o [hdr,null,len,len] else: return rxFrameclass Segment: """store a string with memory contents along with its startaddress""" def __init__(self, startaddress = 0, data=None): if data is None: self.data = '' else: self.data = data self.startaddress = startaddress def __getitem__(self, index): return self.data[index] def __len__(self): return len(self.data) def __repr__(self): return "Segment(startaddress = 0x%04x, data=%r)" % (self.startaddress, self.data)class Memory: """represent memory contents. with functions to load files""" def __init__(self, filename=None): self.segments = [] if filename: self.filename = filename self.loadFile(filename) def append(self, seg): self.segments.append(seg) def __getitem__(self, index): return self.segments[index] def __len__(self): return len(self.segments) def loadIHex(self, file): """load data from a (opened) file in Intel-HEX format""" segmentdata = [] currentAddr = 0 startAddr = 0 lines = file.readlines() for l in lines: if l[0] != ':': raise BSLException("File Format Error\n") l = l.strip() #fix CR-LF issues... length = int(l[1:3],16) address = int(l[3:7],16) type = int(l[7:9],16) check = int(l[-2:],16) if type == 0x00: if currentAddr != address: if segmentdata: self.segments.append( Segment(startAddr, string.join(segmentdata,'')) ) startAddr = currentAddr = address segmentdata = [] for i in range(length): segmentdata.append( chr(int(l[9+2*i:11+2*i],16)) ) currentAddr = length + currentAddr elif type in (0x01, 0x02, 0x03, 0x04, 0x05): pass else: sys.stderr.write("Ignored unknown field (type 0x%02x) in ihex file.\n" % type) if segmentdata: self.segments.append( Segment(startAddr, string.join(segmentdata,'')) ) def loadTIText(self, file): """load data from a (opened) file in TI-Text format""" next = 1 startAddr = 0 segmentdata = [] #Convert data for MSP430, TXT-File is parsed line by line while next >= 1: #Read one line l = file.readline() if not l: break #EOF l = l.strip() if l[0] == 'q': break elif l[0] == '@': #if @ => new address => send frame and set new addr. #create a new segment if segmentdata: self.segments.append( Segment(startAddr, string.join(segmentdata,'')) ) startAddr = int(l[1:],16) segmentdata = [] else: for i in string.split(l): segmentdata.append(chr(int(i,16))) if segmentdata: self.segments.append( Segment(startAddr, string.join(segmentdata,'')) ) def loadELF(self, file): """load data from a (opened) file in ELF object format. File must be seekable""" import elf obj = elf.ELFObject() obj.fromFile(file) if obj.e_type != elf.ELFObject.ET_EXEC: raise Exception("No executable") for section in obj.getSections(): if DEBUG: sys.stderr.write("ELF section %s at 0x%04x %d bytes\n" % (section.name, section.lma, len(section.data))) if len(section.data): self.segments.append( Segment(section.lma, section.data) ) def loadFile(self, filename): """fill memory with the contents of a file. file type is determined from extension""" #TODO: do a contents based detection if filename[-4:].lower() == '.txt': self.loadTIText(open(filename, "rb")) elif filename[-4:].lower() in ('.a43', '.hex'): self.loadIHex(open(filename, "rb")) else: self.loadELF(open(filename, "rb")) def getMemrange(self, fromadr, toadr): """get a range of bytes from the memory. unavailable values are filled with 0xff.""" res = '' toadr = toadr + 1 #python indxes are excluding end, so include it while fromadr < toadr: #print "fromto: %04x %04x" % (fromadr, toadr) for seg in self.segments: #print seg segend = seg.startaddress + len(seg.data) if seg.startaddress <= fromadr and fromadr < segend: #print "startok 0x%04x %d" % (seg.startaddress, len(seg.data)) #print ("0x%04x "*3) % (segend, fromadr, toadr) if toadr > segend: #not all data in segment #print "out of segment" catchlength = segend-fromadr else: catchlength = toadr-fromadr #print toadr-fromadr #print catchlength res = res + seg.data[fromadr-seg.startaddress : fromadr-seg.startaddress+catchlength] fromadr = fromadr + catchlength #adjust start if len(res) >= toadr-fromadr: break#return res else: res = res + chr(255) fromadr = fromadr + 1 #adjust start #print "fill FF" #print "res: %r" % res return resclass BootStrapLoader(LowLevel): """higher level Bootstrap Loader functions.""" ERR_VERIFY_FAILED = "Error: verification failed" ERR_ERASE_CHECK_FAILED = "Error: erase check failed" ACTION_PROGRAM = 0x01 #Mask: program data ACTION_VERIFY = 0x02 #Mask: verify data ACTION_ERASE_CHECK = 0x04 #Mask: erase check #Max. bytes sent within one frame if parsing a TI TXT file. #( >= 16 and == n*16 and <= MAX_DATA_BYTES!) MAXDATA = 240-16 def __init__(self, *args, **kargs): LowLevel.__init__(self, *args, **kargs) self.byteCtr = 0 self.meraseCycles = 1 self.patchRequired = 0 self.patchLoaded = 0 self.bslVer = 0 self.passwd = None self.data = None self.maxData = self.MAXDATA self.cpu = None def preparePatch(self): """prepare to download patch""" if DEBUG > 1: sys.stderr.write("* preparePatch()\n") if self.patchLoaded: #Load PC with 0x0220. #This will invoke the patched bootstrap loader subroutines. self.bslTxRx(self.BSL_LOADPC, #Command: Load PC 0x0220) #Address to load into PC self.BSLMemAccessWarning = 0 #Error is removed within workaround code return def postPatch(self): """setup after the patch is loaded""" if DEBUG > 1: sys.stderr.write("* postPatch()\n") if self.patchLoaded: self.BSLMemAccessWarning = 1 #Turn warning back on. def verifyBlk(self, addr, blkout, action): """verify memory against data or 0xff""" if DEBUG > 1: sys.stderr.write("* verifyBlk()\n") if action & self.ACTION_VERIFY or action & self.ACTION_ERASE_CHECK: if DEBUG: sys.stderr.write(" Check starting at 0x%04x, %d bytes ... \n" % (addr, len(blkout))) self.preparePatch() blkin = self.bslTxRx(self.BSL_RXBLK, addr, len(blkout)) self.postPatch() for i in range(len(blkout)): if action & self.ACTION_VERIFY: #Compare data in blkout and blkin if blkin[i] != blkout[i]: sys.stderr.write("Verification failed at 0x%04x (0x%02x, 0x%02x)\n" % (addr+i, ord(blkin[i]), ord(blkout[i]))) sys.stderr.flush() raise BSLException(self.ERR_VERIFY_FAILED) #Verify failed! continue elif action & self.ACTION_ERASE_CHECK: #Compare data in blkin with erase pattern if blkin[i] != chr(0xff): sys.stderr.write("Erase Check failed at 0x%04x (0x%02x)\n" % (addr+i, ord(blkin[i]))) sys.stderr.flush() raise BSLException(self.ERR_ERASE_CHECK_FAILED) #Erase Check failed! continue def programBlk(self, addr, blkout, action): """programm a memory block""" if DEBUG > 1: sys.stderr.write("* programBlk()\n") #Check, if specified range is erased self.verifyBlk(addr, blkout, action & self.ACTION_ERASE_CHECK) if action & self.ACTION_PROGRAM: if DEBUG: sys.stderr.write(" Program starting at 0x%04x, %i bytes ...\n" % (addr, len(blkout))) self.preparePatch() #Program block self.bslTxRx(self.BSL_TXBLK, addr, len(blkout), blkout) self.postPatch() #Verify block self.verifyBlk(addr, blkout, action & self.ACTION_VERIFY) #segments: #list of tuples or lists: #segements = [ (addr1, [d0,d1,d2,...]), (addr2, [e0,e1,e2,...])] def programData(self, segments, action): """programm or verify data""" if DEBUG > 1: sys.stderr.write("* programData()\n") for seg in segments: currentAddr = seg.startaddress pstart = 0 while pstart<len(seg.data): length = self.MAXDATA if pstart+length > len(seg.data): length = len(seg.data) - pstart self.programBlk(currentAddr, seg.data[pstart:pstart+length], action) pstart = pstart + length currentAddr = currentAddr + length self.byteCtr = self.byteCtr + length #total sum def uploadData(self, startaddress, size, wait=0): """upload a datablock""" if DEBUG > 1: sys.stderr.write("* uploadData()\n") data = '' pstart = 0 while pstart<size: length = self.maxData if pstart+length > size: length = size - pstart data = data + self.bslTxRx(self.BSL_RXBLK, pstart+startaddress, length, wait=wait)[:-2] #cut away checksum pstart = pstart + length return data def txPasswd(self, passwd=None, wait=0): """transmit password, default if None is given.""" if DEBUG > 1: sys.stderr.write("* txPassword(%r)\n" % passwd) if passwd is None: #Send "standard" password to get access to protected functions. sys.stderr.write("Transmit default password ...\n") sys.stderr.flush() #Flash is completely erased, the contents of all Flash cells is 0xff passwd = chr(0xff)*32 else:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -