Rev 137 | Blame | Last modification | View Log | RSS feed
#!/usr/bin/env python### Copyright 2010 TheSeven, benedikt93### This file is part of emBIOS.## emBIOS is free software: you can redistribute it and/or# modify it under the terms of the GNU General Public License as# published by the Free Software Foundation, either version 2 of the# License, or (at your option) any later version.## emBIOS is distributed in the hope that it will be useful,# but WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.# See the GNU General Public License for more details.## You should have received a copy of the GNU General Public License# along with emBIOS. If not, see <http://www.gnu.org/licenses/>.### note: handles commands 1 to 21import sysimport mathimport structimport timeimport usbclass embios:def __init__(self, devtype = 0, type = 0):busses = usb.busses()for bus in busses:devices = bus.devicesfor dev in devices:if dev.idVendor == 0xffff and dev.idProduct == 0xe000:# get endpointsself.__coutep = dev.configurations[0].interfaces[0][0].endpoints[0].addressself.__cinep = dev.configurations[0].interfaces[0][0].endpoints[1].addressself.__doutep = dev.configurations[0].interfaces[0][0].endpoints[2].addressself.__dinep = dev.configurations[0].interfaces[0][0].endpoints[3].addresshandle = dev.open()handle.setConfiguration(1)handle.claimInterface(0)# get version infohandle.bulkWrite(self.__coutep, struct.pack("<IIII", 1, 0, 0, 0))response = self.__getbulk(handle, self.__cinep, 0x10)self.__checkstatus(response)i = struct.unpack("<IIBBBBI", response)if devtype in [0, i[6]] and type in [0, i[5]]:# correct deviceself.handle = handleself.dev = devself.svnrev, self.major, self.minor, self.patch, self.type, self.devtype = i[1:]self.__myprint("Connected to emBIOS %s v%d.%d.%d (SVN revision: %d) on %s, USB version %s\n" \% (self.type2name(self.type), self.major, self.minor, self.patch, self.svnrev, \self.devtype2name(self.devtype), dev.deviceVersion))# get packet size infoself.getinfo("packetsize", 1)return# wrong devicehandle.releaseInterface()raise Exception("Could not find specified device (devtype = %d, type = %d)" % (devtype, type))#=====================================================================================@staticmethoddef __myprint(data, silent = 0):if not silent:sys.stdout.write(data)sys.stdout.flush()@staticmethoddef __gethexviewprintout(data, title, showaddr):printout_temp = struct.unpack("%dB" % (len(data)), data)printout = title + ":\n"pointer = 0pointer2 = 0while (pointer < len(printout_temp)):pointer2 = 0if (showaddr): printout += "0x%08x " % (pointer)while (pointer2 < 0x10) and (pointer < len(printout_temp)):printout += ("%2x " % (printout_temp[pointer]))pointer += 1pointer2 += 1printout += "\n"if (pointer2 != 0x10):printout += "\n"return printout@staticmethoddef __getbulk(handle, endpoint, size):data = handle.bulkRead(endpoint, size, 1000)return struct.pack("%dB" % len(data), *data)@staticmethoddef __checkstatus(data):errorcode = struct.unpack("<I", data[:4])[0]if errorcode == 1:# everything went finereturnelif errorcode == 2:print("\nError: Device doesn't support this function!")raise Exception("emBIOS device doesn't support this function!")elif errorcode == 3:print("\nError: Device is busy!")raise Exception("emBIOS device is busy!")else:print("\nUnknown error %d" % errorcode)raise Exception("Unknown emBIOS error %d" % errorcode)@staticmethoddef type2name(type):if type == 1: return "Debugger"else: return "UNKNOWN (0x%08x)" % type@staticmethoddef devtype2name(devtype):if devtype == 0x47324e49: return "iPod Nano 2G"if devtype == 0x47334e49: return "iPod Nano 3G"if devtype == 0x47344e49: return "iPod Nano 4G"if devtype == 0x4c435049: return "iPod Classic"else: return "UNKNOWN (0x%08x)" % devtype#=====================================================================================def getinfo (self, infotype, silent = 0):if (infotype == "version"):self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 1, 0, 0, 0))response = self.__getbulk(self.handle, self.__cinep, 0x10)self.__checkstatus(response)i = struct.unpack("<IIBBBBI", response)self.svnrev, self.major, self.minor, self.patch, self.type, self.devtype = i[1:]self.__myprint("emBIOS %s v%d.%d.%d (SVN revision: %d) on %s, USB version %s\n" \% (self.type2name(self.type), self.major, self.minor, self.patch, self.svnrev, \self.devtype2name(self.devtype), self.dev.deviceVersion)\, silent)elif (infotype == "packetsize"):self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 1, 1, 0, 0))response = self.__getbulk(self.handle, self.__cinep, 0x10)self.__checkstatus(response)i = struct.unpack("<IHHII", response)self.cout_maxsize = i[1]self.cin_maxsize = i[2]self.dout_maxsize = i[3]self.din_maxsize = i[4]self.__myprint("Maximum packet sizes:\n Command out: %d bytes\n Command in: %d bytes\n Data out: %d bytes\n Data in: %d bytes\n" \% (self.cout_maxsize, self.cin_maxsize, self.dout_maxsize, self.din_maxsize), silent)elif (infotype == "usermemrange"):self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 1, 1, 0, 0))response = self.__getbulk(self.handle, self.__cinep, 0x10)self.__checkstatus(response)i = struct.unpack("<IIII", response)self.usermem_lower = i[1]self.usermem_upper = i[2]self.__myprint("User memory range:\n Lower bound (inclusive): %x\n Upper bound (exclusive) %x\n" \% (self.usermem_lower, self.usermem_upper), silent)else:self.__myprint("Unsupported type of info: %d" % (infotype))def reset(self, force, silent = 0):""" Resets the device.<force>: if 0, the reset will be gracefully, otherwise it will be forced.<silent>: if not 0, nothing will be printed to the console window"""if (force == 0):force = 1else:force = 0self.__myprint("Resetting device...", silent)self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 2, force, 0, 0))if (force == 1):# reset not forcedresponse = self.__getbulk(self.handle, self.__cinep, 0x10)self.__checkstatus(response)self.__myprint(" done\n", silent)def poweroff(self, force, silent = 0):""" Powers the device off.<force>: if 0, the poweroff will be gracefully, otherwise it will be forced.<silent>: if not 0, nothing will be printed to the console window"""if (force == 0):force = 1else:force = 0self.__myprint("Powering device off...", silent)self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 3, force, 0, 0))if (force == 1):# shutdown not forcedresponse = self.__getbulk(self.handle, self.__cinep, 0x10)self.__checkstatus(response)self.__myprint(" done\n", silent)#=====================================================================================def write(self, offset, data, usedma, freezesched, *range):boffset = 0size = len(data)if len(range) > 0:boffset = range[0]if len(range) > 1:size = range[1]if (size == 0):return# correct alignmentwhile (offset & 0xF) != 0:blocklen = sizeif (blocklen > size):blocklen = sizeif (blocklen > self.cout_maxsize - 0x10):blocklen = self.cout_maxsize - 0x10blocklen = (blocklen & 0xFFFFFFF0) + (offset & 0xF)self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 5, offset, blocklen, 0) + data[boffset:boffset+blocklen])response = self.__getbulk(self.handle, self.__cinep, 0x10)self.__checkstatus(response)offset += blocklenboffset += blocklensize -= blocklen# write data with DMA, if it makes sense (-> much data) and isn't forbiddenif (usedma) and (size > 2 * (self.cout_maxsize - 16)):if (freezesched):self.freezescheduler(1, 0)while (size > (self.cout_maxsize - 16)):blocklen = sizeif (blocklen > self.dout_maxsize):blocklen = self.dout_maxsizeself.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 7, offset, blocklen, 0))response = self.__getbulk(self.handle, self.__cinep, 0x10)self.__checkstatus(response)self.handle.bulkWrite(self.__doutep, data[boffset:boffset+blocklen])offset += blocklenboffset += blocklensize -= blocklenif (freezesched):self.freezescheduler(0, 0)# write rest of datawhile (size > 0):blocklen = sizeif (blocklen > self.cout_maxsize - 0x10):blocklen = self.cout_maxsize - 0x10self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 5, offset, blocklen, 0) + data[boffset:boffset+blocklen])response = self.__getbulk(self.handle, self.__cinep, 0x10)self.__checkstatus(response)offset += blocklenboffset += blocklensize -= blocklendef read(self, offset, size, usedma, freezesched):if (size == 0):returndata = ""# correct alignmentwhile (offset & 0xF) != 0:blocklen = sizeif (blocklen > size):blocklen = sizeif (blocklen > self.cin_maxsize - 0x10):blocklen = self.cin_maxsize - 0x10blocklen = (blocklen & 0xFFFFFFF0) + (offset & 0xF)self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 4, offset, blocklen, 0))response = self.__getbulk(self.handle, self.__cinep, 0x10 + blocklen)self.__checkstatus(response)data += response[0x10:]offset += blocklensize -= blocklen# read data with DMA, if it makes sense (-> much data) and isn't forbiddenif (usedma) and (size > 2 * (self.cin_maxsize - 16)):if (freezesched):self.freezescheduler(1, 0)while (size > (self.cin_maxsize - 16)):blocklen = sizeif (blocklen > self.din_maxsize):blocklen = self.din_maxsizeself.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 6, offset, blocklen, 0))response = self.__getbulk(self.handle, self.__cinep, 0x10)self.__checkstatus(response)data += self.__getbulk(self.handle, self.__doutep, blocklen)offset += blocklensize -= blocklenif (freezesched):self.freezescheduler(0, 0)# read rest of datawhile (size > 0):blocklen = sizeif (blocklen > self.cin_maxsize - 0x10):blocklen = self.cin_maxsize - 0x10self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 4, offset, blocklen, 0))response = self.__getbulk(self.handle, self.__cinep, 0x10 + blocklen)self.__checkstatus(response)data += response[0x10:]offset += blocklensize -= blocklenreturn datadef uploadfile(self, offset, file, usedma = 1, freezesched = 0, silent = 0):self.__myprint("Uploading %s to 0x%08x..." % (file, offset), silent)f = open(file, "rb")while True:data = f.read(262144)if data == "": breakself.write(offset, data, usedma, freezesched)offset += len(data)self.__myprint(".")self.__myprint(" done\n", silent)def downloadfile(self, offset, size, file, usedma = 1, freezesched = 0, silent = 0):self.__myprint("Downloading 0x%x bytes from 0x%08x to %s..." % (size, offset, file), silent)f = open(file, "wb")while True:blocklen = sizeif blocklen == 0: breakif blocklen > 262144: blocklen = 262144f.write(self.read(offset, blocklen, usedma, freezesched))offset += blocklensize -= blocklenself.__myprint(".")self.__myprint(" done\n", silent)def uploadint(self, offset, data, silent = 0):self.__myprint("Uploading 0x%08x to 0x%08x..." % (data, offset), silent)data = struct.pack('<I', data)self.write(offset, data, 0, 0)self.__myprint(" done\n", silent)def downloadint(self, offset, silent = 0):self.__myprint("Downloading an integer from 0x%08x..." % (offset), silent)data = self.read(offset, 4, 0, 0)number = struct.unpack('<I', data)self.__myprint(" done\nValue was: 0x%08x\n" % (number), silent)return data#=====================================================================================def i2crecv(self, bus, slave, addr, size, silent = 0):if (size > self.cin_maxsize - 0x10) or (size > 0xFF):raise Exception ("The data exceeds the maximum amount that can be received with this instruction.")self.__myprint("Reading 0x%2x bytes from 0x%2x at I2C device at bus 0x%2x, slave adress 0x%2x ..." % (size, addr, bus, slave), silent)self.handle.bulkWrite(self.__coutep, struct.pack("<IBBBBII", 8, bus, slave, addr, size, 0, 0))data = self.__getbulk(self.handle, self.__cinep, 0x10 + size)self.__checkstatus(response)self.__myprint(" done\n data was:\n%s\n" % (self.__gethexviewprintout(data[16:])), silent)return data[16:]def i2csend(self, bus, slave, addr, data, silent = 0):size = len(data)if (size > self.cout_maxsize - 0x10) or (size > 0xFF):raise Exception ("The data exceeds the maximum amount that can be send with this instruction.")self.__myprint("Writing 0x%2x bytes to 0x%2x at I2C device at bus 0x%2x, slave adress 0x%2x ..." % (size, addr, bus, slave), silent)self.handle.bulkWrite(self.__coutep, struct.pack("<IBBBBII", 9, bus, slave, addr, size, 0, 0) + data)response = self.__getbulk(self.handle, self.__cinep, 0x10)self.__checkstatus(response)self.__myprint(" done\n", silent)#=====================================================================================def readusbcon(self, size, outtype = "", file = "", silent = 0):""" reads from USB console<size>: number of bytes to be read, if its length exceeds the Command In endpoint packet size - 0x10, it will be read in several steps<outtype>: how the data will be put out"file" => writes data to file <file>"printstring" => prints data as a string to the console window"printhex" => prints a hexview view of the data to the console window"" => only returns the data<silent>: if 0, nothing will be written to the console window (even if <outtype> defines something else)in every case, the data will be returned in an array with additional information[len, buffersize, datainbuffer, data]where len is the length of the data actually read,buffersize is the on-device read buffer size,datainbuffer is the number of bytes still left in the on device buffer,data is the actual datain case that within 5 secs, it's not possible to read <size> bytes, a timeout will occur"""out_data = ""readbytes = 0buffersize = 0bytesleft = 0timeoutcounter = 0self.__myprint("Reading 0x%x bytes from USB console..." % (size), silent)while size > 0 and timoutcounter < 50:blocklen = sizeif size > self.cin_maxsize - 0x10:blocklen = self.cin_maxsize - 0x10self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 10, blocklen, 0, 0))response = self.__getbulk(self.handle, self.__cinep, blocklen + 0x10)self.__checkstatus(response)readbytes, buffersize, bytesleft = struct.unpack("<III", response[4:])out_data += response[0x10:0x10+readbytes]size -= blocklenif not bytesleft > 0: # no data left to read => wait a bit and prevent an infinite loop trying to read data when there is nonetimeoutcounter += 1time.sleep(0.1)else:timeoutcounter -= 3if timeoutcounter < 0:timeoutcounter = 0self.__myprint(" done\n", silent)self.__myprint("\nBytes read: 0x%x\nOn-device buffersize: 0x%x\nBytes still in device's buffer: 0x%x\n\n"\% (len(out_data), buffersize, bytesleft), silent)if (outtype == "file"):f = open(file, "wb")f.write(out_data)elif (outtype == "printstring"):self.__myprint(out_data, silent)self.__myprint("\n\n", silent)elif (outtype == "printhex"):self.__myprint(self.__gethexviewprintout(out_data, "", 1), silent)self.__myprint("\n\n", silent)elif (outtype == ""):pass # return onlyelse:raise Exception ("Invalid argument for <outtype>: '%s'." % (outtype))return [len(out_data), buffersize, bytesleft, out_data]def writeusbcon(self, data, silent = 0, *range):""" writes to USB console<data>: the data to be written<range>: the range in <data> that should be written, in the from [offset, length]<silent>: if 0, nothing will be written to the console windowif the data to be written exceeds the Command Out endpoint packet size - 0x10, it will be written in several steps"""size = len(data)boffset = 0if len(range) > 0:boffset = range[0]if len(range) > 1:size = range[1]self.__myprint("Writing 0x%x bytes to USB console..." % (size), silent)timeoutcounter = 0while (size > 0) and (timeoutcounter < 50):blocklen = sizeif blocklen > self.cout_maxsize - 0x10:blocklen = self.cout_maxsize - 0x10self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 11, size, 0, 0) + data[boffset:boffset+blocklen])response = self.__getbulk(self.handle, self.__cinep, 0x10)self.__checkstatus(response)sendbytes = struct.unpack("<I", response[4:])[0]if sendbytes < blocklen: # not everything has been written, need to resent some stuff but wait a bit before doing sotime.sleep(0.1)timeoutcounter += 1elif timeoutcounter > 0: # lower timeoutcounter againtimeoutcounter -= 3if timeoutcounter < 0:timeoutcounter = 0size -= sendbytesboffset += sendbytesif (timeoutcounter >=50):raise Exception("Timeout, 0x%x bytes couldn't be send." % size)self.__myprint(" done\n", silent)return size # number of bytes that have not been sentdef readdevcon(self, bitmask, size, outtype = "", file = "", silent = 0):""" reads from one or more of the device's consoles<bitmask>: bitmask of consoles to be read from<size>: number of bytes to be read, if its length exceeds the Command In endpoint packet size - 0x10, it will be read in several steps<outtype>: how the data will be put out"file" => writes data to file <file>"printstring" => prints data as a string to the console window"printhex" => prints a hexview view of the data to the console window"" => only returns the data<silent>: if 0, nothing will be written to the console window (even if <outtype> defines something else)in every case, the data will be returnedin case that within 5 secs, it's not possible to read <size> bytes, a timeout will occur"""out_data = ""readbytes = 0timeoutcounter = 0self.__myprint("Reading 0x%x bytes from device's console(s)..." % (size), silent)while size > 0 and timoutcounter < 50:blocklen = sizeif size > self.cin_maxsize - 0x10:blocklen = self.cin_maxsize - 0x10self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 13, bitmask, blocklen, 0))response = self.__getbulk(self.handle, self.__cinep, blocklen + 0x10)self.__checkstatus(response)readbytes = struct.unpack("<III", response[4:])[0]out_data += response[0x10:0x10+readbytes]size -= blocklenif not readbytes > 0: # no data read => wait a bit and prevent an infinite loop trying to read data when there is nonetimeoutcounter += 1time.sleep(0.1)else:timeoutcounter -= 3if timeoutcounter < 0:timeoutcounter = 0self.__myprint(" done\n", silent)self.__myprint("\nBytes read: 0x%x\n\n" % (len(out_data)), silent)if (outtype == "file"):f = open(file, "wb")f.write(out_data)elif (outtype == "printstring"):self.__myprint(out_data, silent)self.__myprint("\n\n", silent)elif (outtype == "printhex"):self.__myprint(self.__gethexviewprintout(out_data, "", 1), silent)self.__myprint("\n\n", silent)elif (outtype == ""):pass # return onlyelse:raise Exception ("Invalid argument for <outtype>: '%s'." % (outtype))return out_datadef writedevcon(self, bitmask, data, silent = 0, *range):""" writes to USB console<bitmask>: bitmask of consoles to be written to<data>: the data to be written<range>: the range in <data> that should be written, in the from [offset, length]<silent>: if 0, nothing will be written to the console windowif the data to be written exceeds the Command Out endpoint packet size - 0x10, it will be written in several steps"""size = len(data)boffset = 0if len(range) > 0:boffset = range[0]if len(range) > 1:size = range[1]self.__myprint("Writing 0x%x bytes to device's console(s)..." % (size), silent)timeoutcounter = 0while size > 0:blocklen = sizeif blocklen > self.cout_maxsize - 0x10:blocklen = self.cout_maxsize - 0x10self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 12, bitmask, size, 0) + data[boffset:boffset+blocklen])response = self.__getbulk(self.handle, self.__cinep, 0x10)self.__checkstatus(response)size -= blocklenboffset += blocklenself.__myprint(" done\n", silent)def flushconsolebuffers(self, bitmask, silent = 0):self.__myprint("Flushing device console('s) buffer('s)...")self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 14, bitmask, 0, 0))response = self.__getbulk(self.handle, self.__cinep, 0x10)self.__checkstatus(response)self.__myprint(" done\n")#=====================================================================================def freezescheduler(self, freeze, silent = 0):if (freeze):self.__myprint("Freezing scheduler...", silent)freeze = 1else:self.__myprint("Unfreezing scheduler...", silent)freeze = 0self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 16, freeze, 0, 0))response = self.__getbulk(self.handle, self.__cinep, 0x10)self.__checkstatus(response)self.__myprint(" done\n", silent)def suspendthread(self, suspend, threadid, silent = 0):if (suspend):self.__myprint("Suspending thread 0x%08x..." % threadid, silent)suspend = 1else:self.__myprint("Unsuspending thread 0x%08x..." % threadid, silent)suspend = 0self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 17, suspend, threadid, 0))response = self.__getbulk(self.handle, self.__cinep, 0x10)self.__checkstatus(response)self.__myprint(" done\n", silent)def killthread(self, threadid, silent = 0):self.__myprint("Killing thread 0x%08x..." % threadid, silent)self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 18, threadid, 0, 0))response = self.__getbulk(self.handle, self.__cinep, 0x10)self.__checkstatus(response)self.__myprint(" done\n", silent)def createthread(self, namepointer, entrypoint, stackpointer, stacksize, type, priority, state, silent = 0):self.__myprint("Creating thread...", silent)self.handle.bulkWrite(self.__coutep, struct.pack("<IIIIIIII", 19, namepointer, entrypoint, stackpointer, stacksize, type, priority, state))response = self.__getbulk(self.handle, self.__cinep, 0x10)self.__checkstatus(response)if (struct.unpack("<i", response[4:8])[0] < 0):self.__myprint(" failed, error code: 0x%x" % (struct.unpack("<i", response[4:8])[0]), silent)else:self.__myprint(" done\n, thread ID: 0x%x" % (struct.unpack("<I", response[4:8])[0]), silent)def getprocinfo(self, silent = 0):"""printout on console window:<silent> = 0: Process information struct version, Process information table size<silent> = 1: nothing"""# inline functions ----------------------------------------------def procinfotolist(processinfo, structver):if (structver == 1): # Process information struct version == 1ptr = 0process_n = 0retval = []while ptr < len(processinfo):if struct.unpack("<I", processinfo[ptr + 68:ptr + 72])[0] == 0: # THREAD_FREEptr += 120process_n += 1continueretval.append({})retval[process_n]['regs'] = struct.unpack("<IIIIIIIIIIIIIIII", processinfo[ptr:ptr + 64])ptr += 16 * 0x4retval[process_n]['cpsr'] = struct.unpack("<I", processinfo[ptr:ptr + 4])[0]ptr += 1 * 0x4retval[process_n]['state'] = struct.unpack("<I", processinfo[ptr:ptr + 4])[0]ptr += 1 * 0x4retval[process_n]['name_ptr'] = struct.unpack("<I", processinfo[ptr:ptr + 4])[0]ptr += 1 * 0x4retval[process_n]['cputime_current'] = struct.unpack("<I", processinfo[ptr:ptr + 4])[0]ptr += 1 * 0x4retval[process_n]['cputime_total'] = struct.unpack("<Q", processinfo[ptr:ptr + 8])[0]ptr += 1 * 0x8retval[process_n]['startusec'] = struct.unpack("<I", processinfo[ptr:ptr + 4])[0]ptr += 1 * 0x4retval[process_n]['queue_next_ptr'] = struct.unpack("<I", processinfo[ptr:ptr + 4])[0]ptr += 1 * 0x4retval[process_n]['timeout'] = struct.unpack("<I", processinfo[ptr:ptr + 4])[0]ptr += 1 * 0x4retval[process_n]['blocked_since'] = struct.unpack("<I", processinfo[ptr:ptr + 4])[0]ptr += 1 * 0x4retval[process_n]['blocked_by_ptr'] = struct.unpack("<I", processinfo[ptr:ptr + 4])[0]ptr += 1 * 0x4retval[process_n]['stack_ptr'] = struct.unpack("<I", processinfo[ptr:ptr + 4])[0]ptr += 1 * 0x4retval[process_n]['err_no'] = struct.unpack("<I", processinfo[ptr:ptr + 4])[0]ptr += 1 * 0x4retval[process_n]['block_type'] = struct.unpack("<B", processinfo[ptr:ptr + 1])[0]ptr += 1 * 0x1retval[process_n]['thread_type'] = struct.unpack("<B", processinfo[ptr:ptr + 1])[0]ptr += 1 * 0x1retval[process_n]['priority'] = struct.unpack("<B", processinfo[ptr:ptr + 1])[0]ptr += 1 * 0x1retval[process_n]['cpuload'] = struct.unpack("<B", processinfo[ptr:ptr + 1])[0]ptr += 1 * 0x1process_n += 1return retvaldef state2name(state, structver):if structver == 1:if state == 0: return "THREAD_FREE"elif state == 1: return "THREAD_SUSPENDED"elif state == 2: return "THREAD_READY"elif state == 3: return "THREAD_RUNNING"elif state == 4: return "THREAD_BLOCKED"elif state == 5: return "THREAD_DEFUNCT"elif state == 6: return "THREAD_DEFUNCT_ACK"else: return "UNKNOWN"else: return "UNKNOWN"def blocktype2name(blocktype, structver):if structver == 1:if blocktype == 0: return "THREAD_NOT_BLOCKED"elif blocktype == 1: return "THREAD_BLOCK_SLEEP"elif blocktype == 2: return "THREAD_BLOCK_MUTEX"elif blocktype == 3: return "THREAD_BLOCK_WAKEUP"elif blocktype == 4: return "THREAD_DEFUNCT_STKOV"elif blocktype == 5: return "THREAD_DEFUNCT_PANIC"else: return "UNKNOWN"else: return "UNKNOWN"def threadtype2name (threadtype, structver):if structver == 1:if threadtype == 0: return "USER_THREAD"elif threadtype == 1: return "OS_THREAD"elif threadtype == 2: return "CORE_THREAD"else: return "UNKNOWN"else: return "UNKNOWN"def procinfotostring(procinfolist, structver):processinfoprint = ""ptr = 0while structver == 1 and ptr < len(procinfolist): # Process information struct version == 1processinfoprint += "--------------------------------------------------------------------------------\n"processinfoprint += "R0: 0x%08x, R1: 0x%08x, R2: 0x%08x, R3: 0x%08x,\n"\% (procinfolist[ptr]['regs'][0], procinfolist[ptr]['regs'][1], procinfolist[ptr]['regs'][2], procinfolist[ptr]['regs'][3])\+ "R4: 0x%08x, R5: 0x%08x, R6: 0x%08x, R7: 0x%08x,\n"\% (procinfolist[ptr]['regs'][4], procinfolist[ptr]['regs'][5], procinfolist[ptr]['regs'][6], procinfolist[ptr]['regs'][7])\+ "R8: 0x%08x, R9: 0x%08x, R10: 0x%08x, R11: 0x%08x,\n"\% (procinfolist[ptr]['regs'][8], procinfolist[ptr]['regs'][9], procinfolist[ptr]['regs'][10], procinfolist[ptr]['regs'][11])\+ "R12: 0x%08x, SP: 0x%08x, LR: 0x%08x, PC: 0x%08x\n" \% (procinfolist[ptr]['regs'][12], procinfolist[ptr]['regs'][13], procinfolist[ptr]['regs'][14], procinfolist[ptr]['regs'][15])processinfoprint += "cpsr: 0x%08x " % (procinfolist[ptr]['cpsr'])processinfoprint += "state: %s " % (state2name([procinfolist[ptr]['state']], structver))processinfoprint += "nameptr: 0x%08x\n" % (procinfolist[ptr]['name_ptr'])processinfoprint += "current cpu time: 0x%08x " % (procinfolist[ptr]['cputime_current'])processinfoprint += "total cpu time: 0x%016x\n" % (procinfolist[ptr]['cputime_total'])processinfoprint += "startusec: 0x%08x " % (procinfolist[ptr]['startusec'])processinfoprint += "queue next ptr: 0x%08x\n" % (procinfolist[ptr]['queue_next_ptr'])processinfoprint += "timeout: 0x%08x\n" % (procinfolist[ptr]['timeout'])processinfoprint += "blocked since: 0x%08x " % (procinfolist[ptr]['blocked_since'])processinfoprint += "blocked by ptr: 0x%08x\n" % (procinfolist[ptr]['blocked_by_ptr'])processinfoprint += "err_no: 0x%08x " % (procinfolist[ptr]['err_no'])processinfoprint += "block type: %s\n" % (blocktype2name([procinfolist[ptr]['block_type']], structver))processinfoprint += "thread type: %s\n" % (threadtype2name([procinfolist[ptr]['thread_type']], structver))processinfoprint += "priority: 0x%02x " % (procinfolist[ptr]['priority'])processinfoprint += "cpu load: 0x%02x\n" % (procinfolist[ptr]['cpuload'])ptr += 1processinfoprint += "--------------------------------------------------------------------------------\n"return processinfoprint# reading code --------------------------------------------------self.__myprint("Retrieving process information...", silent)offset = 0blocklen = tablesize = self.cin_maxsize - 0x10procinfo = ""structversion = 0# reading loopwhile (offset < tablesize):self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 15, offset, blocklen, 0))response = self.__getbulk(self.handle, self.__cinep, blocklen + 0x10)self.__checkstatus(response)tablesize = struct.unpack("<I", response[8:12])[0]if tablesize <= offset + blocklen:blocklen = tablesize - offsetprocinfo += response[0x10:0x10 + blocklen]structversion = struct.unpack("<I", response[4:8])[0]tablesize = struct.unpack("<I", response[8:12])[0]else:procinfo += response[0x10:0x10 + blocklen]offset += blocklenblocklen = self.cin_maxsize - 0x10if blocklen > tablesize - offset:blocklen = tablesize - offsetout = (structversion, tablesize, procinfotolist(procinfo, structversion))self.__myprint(" done\n"\+ "Process information struct version: 0x%08x\n" % out[0]\+ "Total size of process information table: 0x%08x\n" % out[1]\+ procinfotostring(out[2], 1)\+ "\n\n")return outdef execimage(self, offset, silent = 0):self.__myprint("Executing emBIOS executable image at 0x%08x..." % offset, silent)self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 21, offset, 0, 0))response = self.__getbulk(self.handle, self.__cinep, 0x10)self.__checkstatus(response)self.__myprint(" done\n execimage() return code: 0x%08x\n" % struct.unpack("<I", response[4:8])[0], silent)return struct.unpack("<I", response[4:8])[0]def execfirmware(self, offset, silent = 0):self.__myprint("Executing firmware image at 0x%08x..." % offset, silent)self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 24, offset, 0, 0))response = self.__getbulk(self.handle, self.__cinep, 0x10)self.__checkstatus(response)self.__myprint(" done\n", silent)return#=====================================================================================def readrawbootflash(self, addr_bootflsh, addr_mem, size, silent = 0):self.__myprint("Reading 0x%x bytes from 0x%08x at bootflash to 0x%08x..." % (size, addr_bootflsh, addr_mem), silent)self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 22, addr_mem, addr_bootflsh, size))response = self.__getbulk(self.handle, self.__cinep, 0x10)self.__checkstatus(response)self.__myprint(" done\n", silent)def writerawbootflash(self, addr_mem, addr_bootflsh, size, silent = 0):self.__myprint("Writing 0x%x bytes from 0x%08x to bootflash at 0x%08x..." % (size, addr_fmem, addr_bootflsh), silent)self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 23, addr_mem, addr_bootflsh, size))response = self.__getbulk(self.handle, self.__cinep, 0x10)self.__checkstatus(response)self.__myprint(" done\n", silent)#=====================================================================================def flushcaches(self, silent = 0):self.__myprint("Flushing caches...", silent)self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 20, 0, 0, 0))response = self.__getbulk(self.handle, self.__cinep, 0x10)self.__checkstatus(response)self.__myprint(" done\n", silent)#======================================================================================# backlight control, remnant from libibugger adjusted to work with libembios ==========def backlighton(self, fade, brightness, silent = 0):self.__myprint("Turning on backlight...", silent)if self.devtype == 2:self.i2csend(0, 0xe6, 0x2b, struct.pack("<B", fade), 1)self.i2csend(0, 0xe6, 0x28, struct.pack("<B", int(brightness * 46)), 1)self.i2csend(0, 0xe6, 0x29, struct.pack("<B", 1), 1)self.__myprint(" done\n", silent)elif self.devtype == 4:self.i2csend(0, 0xe6, 0x30, struct.pack("<B", int(brightness * 250)), 1)self.i2csend(0, 0xe6, 0x31, struct.pack("<B", 3), 1)self.__myprint(" done\n", silent)else: self.__myprint(" unsupported (%s)\n" % self.devtype2name(self.devtype), silent)def backlightoff(self, fade, silent = 0):self.__myprint("Turning off backlight...", silent)if self.devtype == 2:self.i2csend(0, 0xe6, 0x2b, struct.pack("<B", fade), 1)self.i2csend(0, 0xe6, 0x29, struct.pack("<B", 0), 1)self.__myprint(" done\n", silent)elif self.devtype == 4:self.i2csend(0, 0xe6, 0x31, struct.pack("<B", 2), 1)self.__myprint(" done\n", silent)else: self.__myprint(" unsupported (%s)\n" % self.devtype2name(self.devtype), silent)