Index: emcore/trunk/tools/emcore.py |
— | — | @@ -464,23 +464,23 @@ |
465 | 465 | self.logger.info("Thread dump:\n")
|
466 | 466 | for thread in threads:
|
467 | 467 | 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)
|
473 | 473 | self.logger.info("Priority: " + str(thread.priority)+"/255\n", 4)
|
474 | 474 | self.logger.info("Current CPU load: %.1f%%\n" % ((thread.cpuload * 100) / 255.), 4)
|
475 | 475 | 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)
|
477 | 477 | self.logger.info("Registers:\n", 4)
|
478 | 478 | for registerrange in range(4):
|
479 | 479 | self.logger.info(" ")
|
480 | 480 | for register in range(registerrange, 16, 4):
|
481 | 481 | 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]))
|
483 | 483 | 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)
|
485 | 485 | self.logger.info("\n")
|
486 | 486 |
|
487 | 487 | @command
|
Index: emcore/trunk/tools/libemcoredata.py |
— | — | @@ -21,39 +21,63 @@ |
22 | 22 | #
|
23 | 23 | #
|
24 | 24 |
|
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
|
34 | 27 |
|
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 | | -)
|
43 | 28 |
|
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 | + ]
|
49 | 34 |
|
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 | + ]
|
57 | 44 |
|
| 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 | +
|
58 | 82 | swtypes = {
|
59 | 83 | 0: "invalid",
|
60 | 84 | 1: "emBIOS Debugger",
|
— | — | @@ -60,9 +84,10 @@ |
61 | 85 | 2: "emCORE Debugger"
|
62 | 86 | }
|
63 | 87 |
|
64 | | -responsecodes = {
|
| 88 | +hwtypes = {
|
65 | 89 | 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"
|
69 | 94 | }
|
Index: emcore/trunk/tools/libemcore.py |
— | — | @@ -28,9 +28,10 @@ |
29 | 29 |
|
30 | 30 | import sys
|
31 | 31 | import struct
|
| 32 | +import ctypes
|
32 | 33 | import usb.core
|
33 | | -import libemcoredata
|
34 | 34 |
|
| 35 | +from libemcoredata import *
|
35 | 36 | from misc import Logger, Bunch, Error, gethwname
|
36 | 37 | from functools import wraps
|
37 | 38 |
|
— | — | @@ -369,66 +370,27 @@ |
370 | 371 | @command()
|
371 | 372 | def getprocinfo(self):
|
372 | 373 | """ Gets current state of the scheduler """
|
373 | | - cin_maxsize = self.lib.dev.packetsizelimit.cin - self.lib.headersize
|
374 | | - # Get the size
|
375 | 374 | 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 | +
|
397 | 379 | threads = []
|
| 380 | + structptr = resp.structptr
|
398 | 381 | 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)
|
432 | 393 | id += 1
|
| 394 | + structptr = threadstruct.thread_next
|
433 | 395 | return threads
|
434 | 396 |
|
435 | 397 | @command()
|
— | — | @@ -963,8 +925,12 @@ |
964 | 926 | rcvdatatypes = "I" + rcvdatatypes # add the response
|
965 | 927 | data = self.dev.cin(struct.calcsize(rcvdatatypes))
|
966 | 928 | 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":
|
969 | 935 | self.logger.debug("Response: OK\n")
|
970 | 936 | if rcvstruct:
|
971 | 937 | datadict = Bunch()
|
— | — | @@ -976,18 +942,15 @@ |
977 | 943 | return datadict
|
978 | 944 | else:
|
979 | 945 | return data
|
980 | | - elif libemcoredata.responsecodes[response] == "unsupported":
|
| 946 | + elif response == "UNSUPPORTED":
|
981 | 947 | self.logger.debug("Response: UNSUPPORTED\n")
|
982 | 948 | raise DeviceError("The device does not support this command.")
|
983 | | - elif libemcoredata.responsecodes[response] == "invalid":
|
| 949 | + elif response == "INVALID":
|
984 | 950 | self.logger.debug("Response: INVALID\n")
|
985 | 951 | raise DeviceError("Invalid command! This should NOT happen!")
|
986 | | - elif libemcoredata.responsecodes[response] == "busy":
|
| 952 | + elif response == "BUSY":
|
987 | 953 | self.logger.debug("Response: BUSY\n")
|
988 | 954 | raise DeviceError("Device busy")
|
989 | | - else:
|
990 | | - self.logger.debug("Response: UNKOWN\n")
|
991 | | - raise DeviceError("Invalid response! This should NOT happen!")
|
992 | 955 | else:
|
993 | 956 | return writelen
|
994 | 957 |
|