freemyipod r506 - Code Review

Jump to: navigation, search
Repository:freemyipod
Revision:r505‎ | r506 | r507 >
Date:23:48, 1 February 2011
Author:farthen
Status:new
Tags:
Comment:
emcore tools: Implement a scheduler_thread structure and use it. Deprecate scheduler_thread version 1 and support scheduler_thread version 2. Change some lists to enums as that type fits them more.
Modified paths:
  • /emcore/trunk/tools/emcore.py (modified) (history)
  • /emcore/trunk/tools/libemcore.py (modified) (history)
  • /emcore/trunk/tools/libemcoredata.py (modified) (history)

Diff [purge]

Index: emcore/trunk/tools/emcore.py
@@ -464,23 +464,23 @@
465465 self.logger.info("Thread dump:\n")
466466 for thread in threads:
467467 self.logger.info(thread.name+":\n", 2)
468 - self.logger.info("Thread id: " + str(thread.id)+"\n", 4)
469 - self.logger.info("Thread type: " + thread.type+"\n", 4)
470 - self.logger.info("Thread state: " + thread.state+"\n", 4)
471 - self.logger.info("Block type: " + thread.block_type+"\n", 4)
472 - self.logger.info("Blocked by: " + self._hex(thread.blocked_by_ptr)+"\n", 4)
 468+ self.logger.info("Threadstruct address: " + self._hex(thread.addr)+"\n", 4)
 469+ self.logger.info("Thread type: " + str(thread.thread_type)+"\n", 4)
 470+ self.logger.info("Thread state: " + str(thread.state)+"\n", 4)
 471+ self.logger.info("Block type: " + str(thread.block_type)+"\n", 4)
 472+ self.logger.info("Blocked by: " + self._hex(thread.blocked_by)+"\n", 4)
473473 self.logger.info("Priority: " + str(thread.priority)+"/255\n", 4)
474474 self.logger.info("Current CPU load: %.1f%%\n" % ((thread.cpuload * 100) / 255.), 4)
475475 self.logger.info("CPU time (total): "+str(datetime.timedelta(microseconds = thread.cputime_total))+"\n", 4)
476 - self.logger.info("Stack address: " + self._hex(thread.stackaddr)+"\n", 4)
 476+ self.logger.info("Stack address: " + self._hex(thread.stack)+"\n", 4)
477477 self.logger.info("Registers:\n", 4)
478478 for registerrange in range(4):
479479 self.logger.info(" ")
480480 for register in range(registerrange, 16, 4):
481481 registerrepr = "r"+str(register)
482 - self.logger.info("{0:3s}: 0x{1:08X} ".format(registerrepr, thread.regs["r"+str(register)]))
 482+ self.logger.info("{0:3s}: 0x{1:08X} ".format(registerrepr, thread.regs[register]))
483483 self.logger.info("\n")
484 - self.logger.info("cpsr: 0x{0:08X}".format(thread.regs.cpsr), 6)
 484+ self.logger.info("cpsr: 0x{0:08X}".format(thread.cpsr), 6)
485485 self.logger.info("\n")
486486
487487 @command
Index: emcore/trunk/tools/libemcoredata.py
@@ -21,39 +21,63 @@
2222 #
2323 #
2424
25 -thread_state = (
26 - "THREAD_FREE",
27 - "THREAD_SUSPENDED",
28 - "THREAD_READY",
29 - "THREAD_RUNNING",
30 - "THREAD_BLOCKED",
31 - "THREAD_DEFUNCT",
32 - "THREAD_DEFUNCT_ACK"
33 -)
 25+from ctypes import *
 26+from misc import ExtendedCStruct, c_enum
3427
35 -thread_block = (
36 - "THREAD_NOT_BLOCKED",
37 - "THREAD_BLOCK_SLEEP",
38 - "THREAD_BLOCK_MUTEX",
39 - "THREAD_BLOCK_WAKEUP",
40 - "THREAD_DEFUNCT_STKOV",
41 - "THREAD_DEFUNCT_PANIC"
42 -)
4328
44 -thread_type = (
45 - "USER_THREAD",
46 - "OS_THREAD",
47 - "CORE_THREAD"
48 -)
 29+class thread_type(c_enum):
 30+ _fields_ = ["USER_THREAD",
 31+ "OS_THREAD",
 32+ "CORE_THREAD",
 33+ ]
4934
50 -hwtypes = {
51 - 0: "invalid",
52 - 0x47324e49: "iPod nano 2g",
53 - 0x47334e49: "iPod nano 3g",
54 - 0x47344e49: "iPod nano 4g",
55 - 0x4c435049: "iPod classic"
56 -}
 35+class thread_state(c_enum):
 36+ _fields_ = ["THREAD_FREE",
 37+ "THREAD_SUSPENDED",
 38+ "THREAD_READY",
 39+ "THREAD_RUNNING",
 40+ "THREAD_BLOCKED",
 41+ "THREAD_DEFUNCT",
 42+ "THREAD_DEFUNCT_ACK",
 43+ ]
5744
 45+class thread_block(c_enum):
 46+ _fields_ = ["THREAD_NOT_BLOCKED",
 47+ "THREAD_BLOCK_SLEEP",
 48+ "THREAD_BLOCK_MUTEX",
 49+ "THREAD_BLOCK_WAKEUP",
 50+ "THREAD_DEFUNCT_STKOV",
 51+ "THREAD_DEFUNCT_PANIC"
 52+ ]
 53+
 54+class responsecode(c_enum):
 55+ _fields_ = ["INVALID",
 56+ "OK",
 57+ "UNSUPPORTED",
 58+ "BUSY"
 59+ ]
 60+
 61+class scheduler_thread(ExtendedCStruct):
 62+ _fields_ = [("regs", c_uint32 * 16),
 63+ ("cpsr", c_uint32),
 64+ ("state", c_uint32),
 65+ ("name", c_uint32),
 66+ ("cputime_current", c_uint32),
 67+ ("cputime_total", c_uint64),
 68+ ("startusec", c_uint32),
 69+ ("thread_next", c_uint32),
 70+ ("queue_next", c_uint32),
 71+ ("timeout", c_uint32),
 72+ ("blocked_since", c_uint32),
 73+ ("blocked_by", c_uint32),
 74+ ("stack", c_uint32),
 75+ ("err_no", c_int32),
 76+ ("block_type", thread_block),
 77+ ("thread_type", thread_type),
 78+ ("priority", c_uint8),
 79+ ("cpuload", c_uint8),
 80+ ]
 81+
5882 swtypes = {
5983 0: "invalid",
6084 1: "emBIOS Debugger",
@@ -60,9 +84,10 @@
6185 2: "emCORE Debugger"
6286 }
6387
64 -responsecodes = {
 88+hwtypes = {
6589 0: "invalid",
66 - 1: "ok",
67 - 2: "unsupported",
68 - 3: "busy"
 90+ 0x47324e49: "iPod nano 2g",
 91+ 0x47334e49: "iPod nano 3g",
 92+ 0x47344e49: "iPod nano 4g",
 93+ 0x4c435049: "iPod classic"
6994 }
Index: emcore/trunk/tools/libemcore.py
@@ -28,9 +28,10 @@
2929
3030 import sys
3131 import struct
 32+import ctypes
3233 import usb.core
33 -import libemcoredata
3434
 35+from libemcoredata import *
3536 from misc import Logger, Bunch, Error, gethwname
3637 from functools import wraps
3738
@@ -369,66 +370,27 @@
370371 @command()
371372 def getprocinfo(self):
372373 """ Gets current state of the scheduler """
373 - cin_maxsize = self.lib.dev.packetsizelimit.cin - self.lib.headersize
374 - # Get the size
375374 schedulerstate = self.lockscheduler()
376 - resp = self.lib.monitorcommand(struct.pack("IIII", 15, 0, 0, 0), "III", ("structver", "tablesize", None))
377 - tablesize = resp.tablesize
378 - size = tablesize
379 - structver = resp.structver
380 - offset = 0
381 - data = ""
382 - while size > 0:
383 - if size > cin_maxsize:
384 - readsize = cin_maxsize
385 - else:
386 - readsize = size
387 - resp = self.lib.monitorcommand(struct.pack("IIII", 15, offset, readsize, 0), "III%ds" % readsize, ("structver", "tablesize", None, "data"))
388 - data += resp.data
389 - offset += readsize
390 - size -= readsize
391 - self.lockscheduler(schedulerstate)
392 - threadstructsize = 120
393 - registersize = 32
394 - if len(data) % threadstructsize != 0:
395 - raise DeviceError("The thread struct is not a multiple of "+str(threadsturcsize)+"!")
396 - threadcount = len(data) / threadstructsize
 375+ resp = self.lib.monitorcommand(struct.pack("IIII", 15, 0, 0, 0), "III", ("structver", "structptr", None))
 376+ if resp.structver != 2:
 377+ raise DeviceError("Unsupported thread struct version!")
 378+
397379 threads = []
 380+ structptr = resp.structptr
398381 id = 0
399 - for thread in range(threadcount):
400 - offset = threadstructsize * thread
401 - threaddata = struct.unpack("<16IIIIIQIIIIIIIBBBB", data[offset:offset+threadstructsize])
402 - info = Bunch()
403 - info.id = id
404 - state = threaddata[17]
405 - info.state = libemcoredata.thread_state[state]
406 - if info.state == "THREAD_FREE":
407 - id += 1
408 - continue
409 - info.regs = Bunch()
410 - for register in range(16):
411 - info.regs["r"+str(register)] = threaddata[register]
412 - info.regs.cpsr = threaddata[16]
413 - info.nameptr = threaddata[18]
414 - if info.nameptr == 0:
415 - info.name = "Thread %d" % info.id
416 - else:
417 - info.name = self.readstring(info.nameptr)
418 - info.cputime_current = threaddata[19]
419 - info.cputime_total = threaddata[20]
420 - info.startusec = threaddata[21]
421 - info.queue_next_ptr = threaddata[22]
422 - info.timeout = threaddata[23]
423 - info.blocked_since = threaddata[24]
424 - info.blocked_by_ptr = threaddata[25]
425 - info.stackaddr = threaddata[26]
426 - info.err_no = threaddata[27]
427 - info.block_type = libemcoredata.thread_block[threaddata[28]]
428 - info.type = libemcoredata.thread_type[threaddata[29]]
429 - info.priority = threaddata[30]
430 - info.cpuload = threaddata[31]
431 - threads.append(info)
 382+ while structptr != 0:
 383+ threadstruct = scheduler_thread()
 384+ self.logger.debug("Reading thread struct of thread at 0x%x\n" % structptr)
 385+ threaddata = self.read(structptr, ctypes.sizeof(scheduler_thread))
 386+ threadstruct._from_string(threaddata)
 387+ threadstruct = threadstruct._to_bunch()
 388+ threadstruct.id = id # only for the purpose of detecting the idle thread as it is always the first one
 389+ threadstruct.addr = structptr
 390+ threadstruct.name = self.readstring(threadstruct.name)
 391+ threadstruct.state = thread_state(threadstruct.state)
 392+ threads.append(threadstruct)
432393 id += 1
 394+ structptr = threadstruct.thread_next
433395 return threads
434396
435397 @command()
@@ -963,8 +925,12 @@
964926 rcvdatatypes = "I" + rcvdatatypes # add the response
965927 data = self.dev.cin(struct.calcsize(rcvdatatypes))
966928 data = struct.unpack(rcvdatatypes, data)
967 - response = data[0]
968 - if libemcoredata.responsecodes[response] == "ok":
 929+ try:
 930+ response = responsecode(data[0])
 931+ except IndexError:
 932+ self.logger.debug("Response: UNKOWN\n")
 933+ raise DeviceError("Invalid response! This should NOT happen!")
 934+ if response == "OK":
969935 self.logger.debug("Response: OK\n")
970936 if rcvstruct:
971937 datadict = Bunch()
@@ -976,18 +942,15 @@
977943 return datadict
978944 else:
979945 return data
980 - elif libemcoredata.responsecodes[response] == "unsupported":
 946+ elif response == "UNSUPPORTED":
981947 self.logger.debug("Response: UNSUPPORTED\n")
982948 raise DeviceError("The device does not support this command.")
983 - elif libemcoredata.responsecodes[response] == "invalid":
 949+ elif response == "INVALID":
984950 self.logger.debug("Response: INVALID\n")
985951 raise DeviceError("Invalid command! This should NOT happen!")
986 - elif libemcoredata.responsecodes[response] == "busy":
 952+ elif response == "BUSY":
987953 self.logger.debug("Response: BUSY\n")
988954 raise DeviceError("Device busy")
989 - else:
990 - self.logger.debug("Response: UNKOWN\n")
991 - raise DeviceError("Invalid response! This should NOT happen!")
992955 else:
993956 return writelen
994957