| Index: embios/trunk/tools/embios.py |
| — | — | @@ -120,7 +120,8 @@ |
| 121 | 121 | class Logger(object):
|
| 122 | 122 | """
|
| 123 | 123 | Simple stdout logger.
|
| 124 | | - Loglevel 4 is most verbose, Loglevel 0 only say something if there is an error.
|
| | 124 | + Loglevel 4 is most verbose, Loglevel 0: Only say something if there is an error.
|
| | 125 | + The log function doesn't care about the loglevel and always logs to stdout.
|
| 125 | 126 | """
|
| 126 | 127 | def __init__(self):
|
| 127 | 128 | # Possible values: 0 (only errors), 1 (warnings), 2 (info, recommended for production use), 3 and more (debug)
|
| — | — | @@ -131,13 +132,13 @@ |
| 132 | 133 |
|
| 133 | 134 | def debug(self, text):
|
| 134 | 135 | if self.loglevel >= 3:
|
| 135 | | - self.log(text)
|
| | 136 | + self.log("DEBUG: " + text)
|
| 136 | 137 |
|
| 137 | 138 | def info(self, text):
|
| 138 | 139 | if self.loglevel >= 2:
|
| 139 | 140 | self.log(text)
|
| 140 | 141 |
|
| 141 | | - def warning(self, text):
|
| | 142 | + def warn(self, text):
|
| 142 | 143 | if self.loglevel >= 1:
|
| 143 | 144 | self.log("WARNING: " + text)
|
| 144 | 145 |
|
| — | — | @@ -269,15 +270,27 @@ |
| 270 | 271 | hwtype = libembiosdata.hwtypes[self.embios.lib.dev.hwtypeid]
|
| 271 | 272 | except KeyError:
|
| 272 | 273 | hwtype = "UNKNOWN (ID = " + self._hex(self.embios.lib.dev.hwtypeid) + ")"
|
| 273 | | - self.logger.info("Connected to "+libembiosdata.swtypes[self.embios.lib.dev.swtypeid] + " v" + str(self.embios.lib.dev.version.majorv) + "." + str(self.embios.lib.dev.version.minorv) +
|
| 274 | | - "." + str(self.embios.lib.dev.version.patchv) + " r" + str(self.embios.lib.dev.version.revision) + " running on " + hwtype + "\n")
|
| | 274 | + self.logger.info("Connected to " + \
|
| | 275 | + libembiosdata.swtypes[self.embios.lib.dev.swtypeid] + \
|
| | 276 | + " v" + str(self.embios.lib.dev.version.majorv) + \
|
| | 277 | + "." + str(self.embios.lib.dev.version.minorv) + \
|
| | 278 | + "." + str(self.embios.lib.dev.version.patchv) + \
|
| | 279 | + " r" + str(self.embios.lib.dev.version.revision) + \
|
| | 280 | + " running on " + hwtype + "\n")
|
| 275 | 281 |
|
| 276 | 282 | elif infotype == "packetsize":
|
| 277 | | - self.logger.info("Maximum packet sizes: \n command out: " + str(self.embios.lib.dev.packetsizelimit.cout) + "\n command in: " + str(self.embios.lib.dev.packetsizelimit.cin) + "\n data in: " + str(self.embios.lib.dev.packetsizelimit.din) + "\n data out: " + str(self.embios.lib.dev.packetsizelimit.dout))
|
| | 283 | + self.logger.info("Maximum packet sizes: \n command out: " + str(self.embios.lib.dev.packetsizelimit.cout) + \
|
| | 284 | + "\n command in: " + str(self.embios.lib.dev.packetsizelimit.cin) + \
|
| | 285 | + "\n data in: " + str(self.embios.lib.dev.packetsizelimit.din) + \
|
| | 286 | + "\n data out: " + str(self.embios.lib.dev.packetsizelimit.dout))
|
| 278 | 287 |
|
| 279 | 288 | elif infotype == "usermemrange":
|
| 280 | 289 | resp = self.embios.getusermemrange()
|
| 281 | | - self.logger.info("The user memory range is "+self._hex(self.embios.lib.dev.usermem.lower)+" - "+self._hex(self.embios.lib.dev.usermem.upper - 1))
|
| | 290 | + self.logger.info("The user memory range is " + \
|
| | 291 | + self._hex(self.embios.lib.dev.usermem.lower) + \
|
| | 292 | + " - " + \
|
| | 293 | + self._hex(self.embios.lib.dev.usermem.upper - 1))
|
| | 294 | +
|
| 282 | 295 | else:
|
| 283 | 296 | raise ArgumentTypeError("one out of 'version', 'packetsize', 'usermemrange'", infotype)
|
| 284 | 297 |
|
| — | — | @@ -317,7 +330,8 @@ |
| 318 | 331 | f = open(filename, 'rb')
|
| 319 | 332 | except IOError:
|
| 320 | 333 | raise ArgumentError("File not readable. Does it exist?")
|
| 321 | | - self.logger.info("Writing file '"+filename+"' to memory at "+self._hex(addr)+"...")
|
| | 334 | + self.logger.info("Writing file '" + filename + \
|
| | 335 | + "' to memory at " + self._hex(addr) + "...")
|
| 322 | 336 | with f:
|
| 323 | 337 | self.embios.write(addr, f.read())
|
| 324 | 338 | f.close()
|
| — | — | @@ -337,7 +351,9 @@ |
| 338 | 352 | f = open(filename, 'wb')
|
| 339 | 353 | except IOError:
|
| 340 | 354 | raise ArgumentError("Can not open file for write!")
|
| 341 | | - self.logger.info("Reading data from address "+self._hex(addr)+" with the size "+self._hex(size)+" to '"+filename+"'...")
|
| | 355 | + self.logger.info("Reading data from address " + self._hex(addr) + \
|
| | 356 | + " with the size " + self._hex(size) + \
|
| | 357 | + " to '"+filename+"'...")
|
| 342 | 358 | with f:
|
| 343 | 359 | f.write(self.embios.read(addr, size))
|
| 344 | 360 | f.close()
|
| — | — | @@ -356,7 +372,8 @@ |
| 357 | 373 | raise ArgumentError("Specified integer too long")
|
| 358 | 374 | data = struct.pack("I", integer)
|
| 359 | 375 | self.embios.write(addr, data)
|
| 360 | | - self.logger.info("Integer '"+self._hex(integer)+"' written successfully to "+self._hex(addr)+"\n")
|
| | 376 | + self.logger.info("Integer '" + self._hex(integer) + \
|
| | 377 | + "' written successfully to " + self._hex(addr) + "\n")
|
| 361 | 378 |
|
| 362 | 379 | @command
|
| 363 | 380 | def downloadint(self, addr):
|
| — | — | @@ -367,7 +384,8 @@ |
| 368 | 385 | addr = self._hexint(addr)
|
| 369 | 386 | data = self.embios.read(addr, 4)
|
| 370 | 387 | integer = struct.unpack("I", data)[0]
|
| 371 | | - self.logger.info("Integer '"+self._hex(integer)+"' read from address "+self._hex(addr)+"\n")
|
| | 388 | + self.logger.info("Integer '" + self._hex(integer) + \
|
| | 389 | + "' read from address " + self._hex(addr) + "\n")
|
| 372 | 390 |
|
| 373 | 391 | @command
|
| 374 | 392 | def i2cread(self, bus, slave, addr, size):
|
| — | — | @@ -453,7 +471,8 @@ |
| 454 | 472 | for word in args:
|
| 455 | 473 | text += word + " "
|
| 456 | 474 | text = text[:-1]
|
| 457 | | - self.logger.info("Writing '"+text+"' to the device consoles identified with "+self._hex(bitmask)+"\n")
|
| | 475 | + self.logger.info("Writing '" + text + \
|
| | 476 | + "' to the device consoles identified with " + self._hex(bitmask) + "\n")
|
| 458 | 477 | self.embios.cwrite(text, bitmask)
|
| 459 | 478 |
|
| 460 | 479 | @command
|
| — | — | @@ -463,7 +482,8 @@ |
| 464 | 483 | <bitmask>: the bitmask of the consoles to be flushed
|
| 465 | 484 | """
|
| 466 | 485 | bitmask = self._hexint(bitmask)
|
| 467 | | - self.logger.info("Flushing consoles identified with the bitmask "+self._hex(bitmask)+"\n")
|
| | 486 | + self.logger.info("Flushing consoles identified with the bitmask " + \
|
| | 487 | + self._hex(bitmask) + "\n")
|
| 468 | 488 | self.embios.cflush(bitmask)
|
| 469 | 489 |
|
| 470 | 490 | @command
|
| — | — | @@ -473,18 +493,32 @@ |
| 474 | 494 | """
|
| 475 | 495 | import datetime
|
| 476 | 496 | threads = self.embios.getprocinfo()
|
| 477 | | - self.logger.info("The device has "+str(len(threads))+" running threads:\n\n")
|
| | 497 | + cpuload = 1
|
| | 498 | + threadload = 0
|
| | 499 | + idleload = 0
|
| 478 | 500 | for thread in threads:
|
| | 501 | + if thread.priority != 0:
|
| | 502 | + threadload += (thread.cpuload*100)/255
|
| | 503 | + else:
|
| | 504 | + idleload += (thread.cpuload*100)/255
|
| | 505 | + coreload = 1 - (threadload + idleload)
|
| | 506 | + cpuload = threadload + coreload
|
| | 507 | + self.logger.info("The device has " + str(len(threads)) + " running threads.\n" + \
|
| | 508 | + "It is running at " + str(cpuload * 100) + "% cpu load with a core load of " + \
|
| | 509 | + str(coreload * 100) + "%, a thread load of " + str(threadload * 100) + "% " + \
|
| | 510 | + "and an idle load of " + str(idleload * 100) + "%\n\n")
|
| | 511 | + self.logger.info("Thread dump:\n")
|
| | 512 | + for thread in threads:
|
| 479 | 513 | self.logger.info(" "+thread.name+":\n")
|
| 480 | | - self.logger.info(" Thread id: "+str(thread.id)+"\n")
|
| 481 | | - self.logger.info(" Thread type: "+thread.type+"\n")
|
| 482 | | - self.logger.info(" Thread state: "+thread.state+"\n")
|
| 483 | | - self.logger.info(" Block type: "+thread.block_type+"\n")
|
| 484 | | - self.logger.info(" Blocked by: "+self._hex(thread.blocked_by_ptr)+"\n")
|
| 485 | | - self.logger.info(" Priority: "+str(thread.priority)+"/255\n")
|
| | 514 | + self.logger.info(" Thread id: " + str(thread.id)+"\n")
|
| | 515 | + self.logger.info(" Thread type: " + thread.type+"\n")
|
| | 516 | + self.logger.info(" Thread state: " + thread.state+"\n")
|
| | 517 | + self.logger.info(" Block type: " + thread.block_type+"\n")
|
| | 518 | + self.logger.info(" Blocked by: " + self._hex(thread.blocked_by_ptr)+"\n")
|
| | 519 | + self.logger.info(" Priority: " + str(thread.priority)+"/255\n")
|
| 486 | 520 | self.logger.info(" Current CPU load: "+str((thread.cpuload*100)/255)+"%\n")
|
| 487 | 521 | self.logger.info(" CPU time (total): "+str(datetime.timedelta(microseconds=thread.cputime_total))+"\n")
|
| 488 | | - self.logger.info(" Stack address: "+self._hex(thread.stackaddr)+"\n")
|
| | 522 | + self.logger.info(" Stack address: " + self._hex(thread.stackaddr)+"\n")
|
| 489 | 523 | self.logger.info(" Registers:\n")
|
| 490 | 524 | for registerrange in range(4):
|
| 491 | 525 | self.logger.info(" ")
|
| — | — | @@ -557,7 +591,12 @@ |
| 558 | 592 | priority = self._hexint(priority)
|
| 559 | 593 | data = self.embios.createthread(nameptr, entrypoint, stackptr, stacksize, type, priority, state)
|
| 560 | 594 | name = self.embios.readstring(nameptr)
|
| 561 | | - self.logger.info("Created a thread with the threadid " + data.id + ", the name \"" + name + "\", the entrypoint at " + self._hex(entrypoint) + ", the stack at " + self._hex(stackpointer) + " with a size of " + self._hex(stacksize) + " and a priority of " + self._hex(priority) + "\n")
|
| | 595 | + self.logger.info("Created a thread with the threadid " + data.id + \
|
| | 596 | + ", the name \"" + name + "\"" + \
|
| | 597 | + ", the entrypoint at " + self._hex(entrypoint) + \
|
| | 598 | + ", the stack at " + self._hex(stackpointer) + \
|
| | 599 | + " with a size of " + self._hex(stacksize) + \
|
| | 600 | + " and a priority of " + self._hex(priority) + "\n")
|
| 562 | 601 |
|
| 563 | 602 | @command
|
| 564 | 603 | def run(self, filename):
|
| — | — | @@ -620,10 +659,10 @@ |
| 621 | 660 | addr_mem = self._hexint(addr_mem)
|
| 622 | 661 | size = self._hexint(size)
|
| 623 | 662 | force = self._bool(force)
|
| 624 | | - self.logger.info("Writing boot flash from the memory in "+self._hex(addr_mem)+" - "+
|
| | 663 | + self.logger.warn("Writing boot flash from the memory in "+self._hex(addr_mem)+" - "+
|
| 625 | 664 | hex(addr_mem+size)+" to "+self._hex(addr_flash)+" - "+self._hex(addr_flash+size)+"\n")
|
| 626 | 665 | if force == False:
|
| 627 | | - self.logger.info("If this was not what you intended press Ctrl-C NOW")
|
| | 666 | + self.logger.warn("If this was not what you intended press Ctrl-C NOW")
|
| 628 | 667 | for i in range(10):
|
| 629 | 668 | self.logger.info(".")
|
| 630 | 669 | time.sleep(1)
|
| — | — | @@ -681,8 +720,9 @@ |
| 682 | 721 | size = self._hexint(size)
|
| 683 | 722 | destination = self._hexint(destination)
|
| 684 | 723 | sha1size = 0x14
|
| 685 | | - self.logger.info("Generating hmac-sha1 hash from the buffer at "+self._hex(addr)+" with the size "+self._hex(size)+
|
| 686 | | - " and saving it to "+self._hex(destination)+" - "+self._hex(destination+sha1size)+"...")
|
| | 724 | + self.logger.info("Generating hmac-sha1 hash from the buffer at " + self._hex(addr) + \
|
| | 725 | + " with the size " + self._hex(size) + " and saving it to " + \
|
| | 726 | + self._hex(destination) + " - " + self._hex(destination+sha1size) + "...")
|
| 687 | 727 | self.embios.lib.dev.timeout = 30000
|
| 688 | 728 | self.embios.hmac_sha1(addr, size, destination)
|
| 689 | 729 | self.logger.info("done\n")
|
| — | — | @@ -697,11 +737,11 @@ |
| 698 | 738 | Gathers some information about the NAND chip used
|
| 699 | 739 | """
|
| 700 | 740 | data = self.embios.ipodnano2g_getnandinfo()
|
| 701 | | - self.logger.info("NAND chip type: "+self._hex(data["type"])+"\n")
|
| 702 | | - self.logger.info("Number of banks: "+str(data["banks"])+"\n")
|
| 703 | | - self.logger.info("Number of blocks: "+str(data["blocks"])+"\n")
|
| 704 | | - self.logger.info("Number of user blocks: "+str(data["userblocks"])+"\n")
|
| 705 | | - self.logger.info("Pages per block: "+str(data["pagesperblock"]))
|
| | 741 | + self.logger.info("NAND chip type: " + self._hex(data["type"])+"\n")
|
| | 742 | + self.logger.info("Number of banks: " + str(data["banks"])+"\n")
|
| | 743 | + self.logger.info("Number of blocks: " + str(data["blocks"])+"\n")
|
| | 744 | + self.logger.info("Number of user blocks: " + str(data["userblocks"])+"\n")
|
| | 745 | + self.logger.info("Pages per block: " + str(data["pagesperblock"]))
|
| 706 | 746 |
|
| 707 | 747 | @command
|
| 708 | 748 | def ipodnano2g_nandread(self, addr, start, count, doecc, checkempty):
|
| — | — | @@ -714,7 +754,8 @@ |
| 715 | 755 | count = self._hexint(count)
|
| 716 | 756 | doecc = int(doecc)
|
| 717 | 757 | checkempty = int(checkempty)
|
| 718 | | - self.logger.info("Reading "+self._hex(count)+" NAND pages starting at "+self._hex(start)+" to "+self._hex(addr)+"...")
|
| | 758 | + self.logger.info("Reading " + self._hex(count) + " NAND pages starting at " + \
|
| | 759 | + self._hex(start) + " to " + self._hex(addr) + "...")
|
| 719 | 760 | self.embios.lib.dev.timeout = 30000
|
| 720 | 761 | self.embios.ipodnano2g_nandread(addr, start, count, doecc, checkempty)
|
| 721 | 762 | self.logger.info("done\n")
|
| — | — | @@ -729,7 +770,8 @@ |
| 730 | 771 | start = self._hexint(start)
|
| 731 | 772 | count = self._hexint(count)
|
| 732 | 773 | doecc = int(doecc)
|
| 733 | | - self.logger.info("Writing "+self._hex(count)+" NAND pages starting at "+self._hex(start)+" from "+self._hex(addr)+"...")
|
| | 774 | + self.logger.info("Writing " + self._hex(count) + " NAND pages starting at " + \
|
| | 775 | + self._hex(start) + " from " + self._hex(addr) + "...")
|
| 734 | 776 | self.embios.lib.dev.timeout = 30000
|
| 735 | 777 | self.embios.ipodnano2g_nandwrite(addr, start, count, doecc)
|
| 736 | 778 | self.logger.info("done\n")
|
| — | — | @@ -743,7 +785,8 @@ |
| 744 | 786 | addr = self._hexint(addr)
|
| 745 | 787 | start = self._hexint(start)
|
| 746 | 788 | count = self._hexint(count)
|
| 747 | | - self.logger.info("Erasing "+self._hex(count)+" NAND blocks starting at "+self._hex(start)+" and logging to "+self._hex(addr)+"...")
|
| | 789 | + self.logger.info("Erasing " + self._hex(count) + " NAND blocks starting at " + \
|
| | 790 | + self._hex(start) + " and logging to " + self._hex(addr) + "...")
|
| 748 | 791 | self.embios.lib.dev.timeout = 30000
|
| 749 | 792 | self.embios.ipodnano2g_nanderase(addr, start, count)
|
| 750 | 793 | self.logger.info("done\n")
|
| — | — | @@ -763,11 +806,11 @@ |
| 764 | 807 | statusfile = open(filenameprefix+"_status.bin", 'wb')
|
| 765 | 808 | except IOError:
|
| 766 | 809 | raise ArgumentError("Can not open file for writing!")
|
| 767 | | - infofile.write("NAND chip type: "+self._hex(info["type"])+"\r\n")
|
| 768 | | - infofile.write("Number of banks: "+str(info["banks"])+"\r\n")
|
| 769 | | - infofile.write("Number of blocks: "+str(info["blocks"])+"\r\n")
|
| 770 | | - infofile.write("Number of user blocks: "+str(info["userblocks"])+"\r\n")
|
| 771 | | - infofile.write("Pages per block: "+str(info["pagesperblock"])+"\r\n")
|
| | 810 | + infofile.write("NAND chip type: " + self._hex(info["type"]) + "\r\n")
|
| | 811 | + infofile.write("Number of banks: " + str(info["banks"]) + "\r\n")
|
| | 812 | + infofile.write("Number of blocks: " + str(info["blocks"]) + "\r\n")
|
| | 813 | + infofile.write("Number of user blocks: "+ str(info["userblocks"]) + "\r\n")
|
| | 814 | + infofile.write("Pages per block: " + str(info["pagesperblock"]) + "\r\n")
|
| 772 | 815 | self.embios.lib.dev.timeout = 30000
|
| 773 | 816 | for i in range(info["banks"] * info["blocks"] * info["pagesperblock"] / 8192):
|
| 774 | 817 | self.logger.info(".")
|
| — | — | @@ -788,9 +831,9 @@ |
| 789 | 832 | Wipes the whole NAND chip and logs the result to a file
|
| 790 | 833 | <force>: Use this flag to suppress the 5 seconds delay
|
| 791 | 834 | """
|
| 792 | | - self.logger.info("Wiping the whole NAND chip!\n")
|
| | 835 | + self.logger.warn("Wiping the whole NAND chip!\n")
|
| 793 | 836 | if force == False:
|
| 794 | | - self.logger.info("If this was not what you intended press Ctrl-C NOW")
|
| | 837 | + self.logger.warn("If this was not what you intended press Ctrl-C NOW")
|
| 795 | 838 | for i in range(10):
|
| 796 | 839 | self.logger.info(".")
|
| 797 | 840 | time.sleep(1)
|
| — | — | @@ -1038,5 +1081,8 @@ |
| 1039 | 1082 | if __name__ == "__main__":
|
| 1040 | 1083 | if len(sys.argv) < 2:
|
| 1041 | 1084 | usage("No command specified")
|
| 1042 | | - interface = Commandline()
|
| 1043 | | - interface._parsecommand(sys.argv[1], sys.argv[2:]) |
| \ No newline at end of file |
| | 1085 | + try:
|
| | 1086 | + interface = Commandline()
|
| | 1087 | + interface._parsecommand(sys.argv[1], sys.argv[2:])
|
| | 1088 | + except KeyboardInterrupt:
|
| | 1089 | + sys.exit() |
| \ No newline at end of file |