def checkCRC(self, addr, crcs): if (addr in self.memChecks): this = self.memChecks[addr] logger.info("{} ?= {}".format(this["crcs"], crcs)) crcsize_words = max(this["length"] / self.sf, self.MEMCHECKMINSIZE) addr_offset = 2 * crcsize_words # "*2" because addr is in bytes and the rest is in words, length/4 because we ack one/fourth of the total message for x in range(len(crcs) / 4 - 1, -1, -1): if (this["crcs"][x * 4:x * 4 + 4] == crcs[x * 4:x * 4 + 4] ): # each CRC is 4 characters long # good :) wisp has good data in this part self.memcheck_widget.ack( h2i(addr) + x * addr_offset, crcsize_words) self.memIsGood[i2h( h2i(addr) + x * addr_offset)] = crcsize_words # store the good stuff logger.debug(i2h(h2i(addr) + x * addr_offset) + " = good") else: # do something with a bad crc: self.badCRC(address=h2i(addr) + addr_offset * x, length=crcsize_words) if (addr in self.memIsBad or addr in self.memIsGood): del self.memChecks[addr] return True return False
def defineMemChecksFromHexlines(self, lines, MLM=MEMCHECKMAXSIZE): memCheckAddresses = dict() # first chop very long data chuncks in smaller parts for line in lines: length = len(line[9:-3]) / 4 # in words checkaddress = h2i(line[3:7]) while (length > 0): if (length > MLM): memCheckAddresses[i2h(checkaddress)] = MLM checkaddress += 2 * MLM # MLM is in words, address is in bytes else: # do some math magic to ceil to the nearest factor of 2 (crc must be factor of 2) memCheckAddresses[i2h(checkaddress)] = max( int(pow(2, ceil(log(length, 2)))), 16) length -= MLM self.mcas = memCheckAddresses logger.debug("new memchecks based upon hexlines: {}".format( pprint.pformat(self.mcas))) # get a list of expected CRC results per small chunck of data self.memChecks = dict() # do not redefine self.memIsGood = dict() # do redefine the memIsBad self.memIsBad = dict() for mca in self.mcas: # check CRC of this block in 4 subparts self.memChecks[mca] = { "crcs": self.crcString(address=h2i(mca), nr_of_words=self.mcas[mca]), "length": self.mcas[mca], }
def defineMemChecks(self, MLM=MEMCHECKMAXSIZE): memCheckAddresses = dict() # first chop very long data chuncks in smaller parts for addr in self.startAddresses: length = self.startAddresses[addr] checkaddress = h2i(addr) while (length > 0): if (length > MLM): memCheckAddresses[i2h(checkaddress)] = MLM checkaddress += 2 * MLM # MLM is in words, address is in bytes else: # do some math magic to ceil to the nearest factor of 2 (crc must be factor of 2) memCheckAddresses[i2h(checkaddress)] = max( int(pow(2, ceil(log(length, 2)))), 16) length -= MLM self.mcas = memCheckAddresses logger.debug("{}".format(pprint.pformat(self.mcas))) # get a list of expected CRC results per small chunck of data self.memChecks = dict() self.memIsGood = dict() self.memIsBad = dict() for mca in self.mcas: # check CRC of this block in 4 subparts self.memChecks[mca] = {"crcs": #"{:04x}{:04x}{:04x}{:04x}".format(self.getCRC(address = h2i(mca), nr_of_words = self.mcas[mca]/4), # self.getCRC(address = h2i(mca)+self.mcas[mca]/2 , nr_of_words = self.mcas[mca]/4), # self.getCRC(address = h2i(mca)+self.mcas[mca]/2 *2, nr_of_words = self.mcas[mca]/4), # self.getCRC(address = h2i(mca)+self.mcas[mca]/2 *3, nr_of_words = self.mcas[mca]/4) ) self.crcString(address = h2i(mca),nr_of_words = self.mcas[mca]), "length": self.mcas[mca],}
def getLineNumber(self, address): for a in range(len(self.addresses))[::-1]: if (address >= self.addresses[a]): return a else: raise NameError('Address' + i2h(address) + ' not found in {}'.format(' '.join( [i2h(x) for x in self.addresses])))
def addChoppedMemCheck(self, addr, length): logger.debug(i2h(addr) + " = bad -> chopping (trying;)") if ( length <= self.MEMCHECKMINSIZE * self.sf ): # if previous message was already tiny, don"t add a new smaller CRCcheck return False self.memChecks[i2h(addr)] = { "crcs": self.crcString(address=addr, nr_of_words=length), "length": length, } return True
def localizeMemBlocks(self): self.startAddresses = dict() lastAddress = -1 # start of the current memory block holecounter = 10 # length of the not interesting memory, which is used for hysteresis for w in range(self.MINMEM, self.MAXMEM, 2): if ( self.getMem(w, 1) != "FFFF" or holecounter < 2 ): # check if this is interesting or if previous 2 blocks where interesting if ( lastAddress == -1 ): # check if this is the first word of an interesting block lastAddress = i2h(w) self.startAddresses[lastAddress] = 1 else: self.startAddresses[lastAddress] += 1 if (self.getMem(w, 1) != "FFFF"): holecounter = 0 else: holecounter += 1 else: lastAddress = -1 holecounter += 1 for x in self.startAddresses: self.startAddresses[ x] -= 2 # reduce by 2 because that is the window of the stop condition
def getLongHexLinesFromBadCRCs(self): lines = [] addresses = self.memIsBad.keys() addresses.sort( ) # sort the lines such that they are in increasing order, such that hexlinewrapping is possible # [warning:] sort function does sorting based upon characters, fortunately hex is also sorted as 0123456789ABCDEFabcdef for addr in addresses: mem = self.getMem(address=h2i(addr), length_in_words=self.memIsBad[addr]) lines.append(":" + i2h(len(mem) / 2, 2) + addr + "00" + mem + "FF\n") logger.debug(self.ID + ": hexline made from bad CRCcheck: " + i2h(len(mem) / 2, 2) + " " + addr + "[00]" + mem + "[FF]") lines.append(":00000001FF\n") # add the end of file line return wrapHexLines(lines)
def getCRC(self, address, nr_of_words): crc = self.crcWords(0, self.getMem(address, nr_of_words)) if (crc == self.crcWords(0, "FFFF" * nr_of_words) and self.getMem(address, nr_of_words) != "FFFF" * nr_of_words): logger.info( "WARNING: crc of address " + i2h(address) + " is equal to empty 'FFFF' mem crc of equal amount of words " + str(nr_of_words)) return crc
def nextRound(self): counter = 0 for addr in self.memChecks: this = self.memChecks[addr] resultpos = log( max(this["length"] / self.sf, self.MEMCHECKMINSIZE) / 2, 2 ) # 16 should be 1 (if wisp receives 1 then it will translate to X blocks of 2<<1 =4), # 32 should be 2 (if wisp receives 2 then it will translate to X blocks of 2<<2 =8), etc if (resultpos.is_integer()): resultpos = int(resultpos) else: raise NameError("trying to do a CRC with strange number " + str(this["length"]) + " = not 16*2^x for integer x > -1") checksum = i2h((h2i(addr[0:2]) + h2i(addr[2:4])) % 256, 2) # calc checksum message = i2h(resultpos * 32, 2) + checksum + addr # *32 == shift by 5 logger.info(self.ID + ": sending memcheck [" + message + "], expecting CRCs = " + this["crcs"]) self.memcheck_widget.send(address=h2i(addr), size_in_words=this["length"]) self.send_util.addOpspec(OpSpecCreator.getBlockWrite(message)) nr_to_read = 1 + min(self.sf, this["length"] / self.MEMCHECKMINSIZE) self.send_util.addOpspec( OpSpecCreator.getRead(mb=3, address=0, nr_of_words=nr_to_read)) counter += 1 if counter == 4: break if (len(self.send_util.opspecs)): self.send_util.sendOpspecs(OCV=1, nack=self.timeout) else: logger.info(self.ID + ": memcheck finished") logger.info(self.ID + ": " + str(len(self.memIsGood)) + " good and " + str(len(self.memIsBad)) + " bad memblocks") self.iAmFinished()
def badCRC(self, address, length): # bad :( wisp has bad data in this quarterpart # if the data chunck was large, try CRC over smaller data chuncks: if (not self.addChoppedMemCheck(address, length)): # data chunck was already small: # check if target memory was actually interesting: if (not all(x == "F" for x in self.getMem(address, length))): self.memcheck_widget.nack(address, length) self.memIsBad[i2h(address)] = length # store the bad stuff logger.debug( i2h(address) + " = bad, must be reprogrammed, too small to chop") else: self.memcheck_widget.dontcare(address, length) logger.debug(i2h(address) + " = bad, don't care, only 'F'") self.memIsGood[i2h( address)] = length # store the don't care stuff as good # because this part is not important, the target only contains F"s else: self.memcheck_widget.chop(address, length) logger.debug( i2h(address) + " = bad, chopped to check in smaller chunks")
def __init__(self, wispRam, title="", destroy_callback=None): super(MemCheckWidget, self).__init__() memchecks = wispRam.memChecks self.setMemCheckTarget( [memchecks[x]["length"] for x in sorted(memchecks)]) self.addresses = [h2i(x) for x in sorted(memchecks)] self.root = Tk() self.root.protocol("WM_DELETE_WINDOW", self.destroyedByUser) self.destroy_callback = destroy_callback # self.root.focus() self.root.title(wispRam.ID + ": " + title) self.root.geometry('+%d-%d' % (20, 20)) text_w = min(max(self.plot_y_target), 250) + 5 text_h = sum( len([y for y in self.plot_y_target if y > i * 220]) for i in range(10)) + 2 self.txt = Text(self.root, width=text_w, height=text_h) self.txt.pack(fill=BOTH, expand=True) for x in range(len(self.plot_y_target)): self.txt.insert( INSERT, i2h(self.addresses[x]) + " " + "?" * self.plot_y_target[x] + "\n")