Subversion Repositories freemyipod

Rev

Rev 501 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 501 Rev 506
Line 26... Line 26...
26
    Provides functions to communicate with emCORE devices via the USB bus.
26
    Provides functions to communicate with emCORE devices via the USB bus.
27
"""
27
"""
28
 
28
 
29
import sys
29
import sys
30
import struct
30
import struct
-
 
31
import ctypes
31
import usb.core
32
import usb.core
32
import libemcoredata
-
 
33
 
33
 
-
 
34
from libemcoredata import *
34
from misc import Logger, Bunch, Error, gethwname
35
from misc import Logger, Bunch, Error, gethwname
35
from functools import wraps
36
from functools import wraps
36
 
37
 
37
class ArgumentError(Error):
38
class ArgumentError(Error):
38
    pass
39
    pass
Line 367... Line 368...
367
        return self.lib.monitorcommand(struct.pack("IIII", 14, bitmask, 0, 0), "III", (None, None, None))
368
        return self.lib.monitorcommand(struct.pack("IIII", 14, bitmask, 0, 0), "III", (None, None, None))
368
    
369
    
369
    @command()
370
    @command()
370
    def getprocinfo(self):
371
    def getprocinfo(self):
371
        """ Gets current state of the scheduler """
372
        """ Gets current state of the scheduler """
372
        cin_maxsize = self.lib.dev.packetsizelimit.cin - self.lib.headersize
-
 
373
        # Get the size
-
 
374
        schedulerstate = self.lockscheduler()
373
        schedulerstate = self.lockscheduler()
375
        resp = self.lib.monitorcommand(struct.pack("IIII", 15, 0, 0, 0), "III", ("structver", "tablesize", None))
374
        resp = self.lib.monitorcommand(struct.pack("IIII", 15, 0, 0, 0), "III", ("structver", "structptr", None))
376
        tablesize = resp.tablesize
-
 
377
        size = tablesize
-
 
378
        structver = resp.structver
375
        if resp.structver != 2:
379
        offset = 0
-
 
380
        data = ""
-
 
381
        while size > 0:
-
 
382
            if size > cin_maxsize:
-
 
383
                readsize = cin_maxsize
376
            raise DeviceError("Unsupported thread struct version!")
384
            else:
377
        
385
                readsize = size
-
 
386
            resp = self.lib.monitorcommand(struct.pack("IIII", 15, offset, readsize, 0), "III%ds" % readsize, ("structver", "tablesize", None, "data"))
-
 
387
            data += resp.data
-
 
388
            offset += readsize
-
 
389
            size -= readsize
-
 
390
        self.lockscheduler(schedulerstate)
-
 
391
        threadstructsize = 120
-
 
392
        registersize = 32
-
 
393
        if len(data) % threadstructsize != 0:
-
 
394
            raise DeviceError("The thread struct is not a multiple of "+str(threadsturcsize)+"!")
-
 
395
        threadcount = len(data) / threadstructsize
-
 
396
        threads = []
378
        threads = []
-
 
379
        structptr = resp.structptr
397
        id = 0
380
        id = 0
398
        for thread in range(threadcount):
381
        while structptr != 0:
399
            offset = threadstructsize * thread
382
            threadstruct = scheduler_thread()
400
            threaddata = struct.unpack("<16IIIIIQIIIIIIIBBBB", data[offset:offset+threadstructsize])
-
 
401
            info = Bunch()
-
 
402
            info.id = id
-
 
403
            state = threaddata[17]
-
 
404
            info.state = libemcoredata.thread_state[state]
-
 
405
            if info.state == "THREAD_FREE":
-
 
406
                id += 1
-
 
407
                continue
-
 
408
            info.regs = Bunch()
-
 
409
            for register in range(16):
-
 
410
                info.regs["r"+str(register)] = threaddata[register]
383
            self.logger.debug("Reading thread struct of thread at 0x%x\n" % structptr)
411
            info.regs.cpsr = threaddata[16]
-
 
412
            info.nameptr = threaddata[18]
-
 
413
            if info.nameptr == 0:
-
 
414
                info.name = "Thread %d" % info.id
-
 
415
            else:
-
 
416
                info.name = self.readstring(info.nameptr)
384
            threaddata = self.read(structptr, ctypes.sizeof(scheduler_thread))
417
            info.cputime_current = threaddata[19]
-
 
418
            info.cputime_total = threaddata[20]
-
 
419
            info.startusec = threaddata[21]
-
 
420
            info.queue_next_ptr = threaddata[22]
385
            threadstruct._from_string(threaddata)
421
            info.timeout = threaddata[23]
386
            threadstruct = threadstruct._to_bunch()
422
            info.blocked_since = threaddata[24]
387
            threadstruct.id = id # only for the purpose of detecting the idle thread as it is always the first one
423
            info.blocked_by_ptr = threaddata[25]
-
 
424
            info.stackaddr = threaddata[26]
388
            threadstruct.addr = structptr
425
            info.err_no = threaddata[27]
-
 
426
            info.block_type = libemcoredata.thread_block[threaddata[28]]
389
            threadstruct.name = self.readstring(threadstruct.name)
427
            info.type = libemcoredata.thread_type[threaddata[29]]
390
            threadstruct.state = thread_state(threadstruct.state)
428
            info.priority = threaddata[30]
-
 
429
            info.cpuload = threaddata[31]
-
 
430
            threads.append(info)
391
            threads.append(threadstruct)
431
            id += 1
392
            id += 1
-
 
393
            structptr = threadstruct.thread_next
432
        return threads
394
        return threads
433
    
395
    
434
    @command()
396
    @command()
435
    def lockscheduler(self, freeze=True):
397
    def lockscheduler(self, freeze=True):
436
        """ Freezes/Unfreezes the scheduler """
398
        """ Freezes/Unfreezes the scheduler """
Line 961... Line 923...
961
        writelen = self.dev.cout(cmd)
923
        writelen = self.dev.cout(cmd)
962
        if rcvdatatypes:
924
        if rcvdatatypes:
963
            rcvdatatypes = "I" + rcvdatatypes # add the response
925
            rcvdatatypes = "I" + rcvdatatypes # add the response
964
            data = self.dev.cin(struct.calcsize(rcvdatatypes))
926
            data = self.dev.cin(struct.calcsize(rcvdatatypes))
965
            data = struct.unpack(rcvdatatypes, data)
927
            data = struct.unpack(rcvdatatypes, data)
-
 
928
            try:
966
            response = data[0]
929
                response = responsecode(data[0])
-
 
930
            except IndexError:
967
            if libemcoredata.responsecodes[response] == "ok":
931
                self.logger.debug("Response: UNKOWN\n")
-
 
932
                raise DeviceError("Invalid response! This should NOT happen!")
-
 
933
            if response == "OK":
968
                self.logger.debug("Response: OK\n")
934
                self.logger.debug("Response: OK\n")
969
                if rcvstruct:
935
                if rcvstruct:
970
                    datadict = Bunch()
936
                    datadict = Bunch()
971
                    counter = 1 # start with 1, 0 is the id
937
                    counter = 1 # start with 1, 0 is the id
972
                    for item in rcvstruct:
938
                    for item in rcvstruct:
Line 974... Line 940...
974
                            datadict[item] = data[counter]
940
                            datadict[item] = data[counter]
975
                        counter += 1
941
                        counter += 1
976
                    return datadict
942
                    return datadict
977
                else:
943
                else:
978
                    return data
944
                    return data
979
            elif libemcoredata.responsecodes[response] == "unsupported":
945
            elif response == "UNSUPPORTED":
980
                self.logger.debug("Response: UNSUPPORTED\n")
946
                self.logger.debug("Response: UNSUPPORTED\n")
981
                raise DeviceError("The device does not support this command.")
947
                raise DeviceError("The device does not support this command.")
982
            elif libemcoredata.responsecodes[response] == "invalid":
948
            elif response == "INVALID":
983
                self.logger.debug("Response: INVALID\n")
949
                self.logger.debug("Response: INVALID\n")
984
                raise DeviceError("Invalid command! This should NOT happen!")
950
                raise DeviceError("Invalid command! This should NOT happen!")
985
            elif libemcoredata.responsecodes[response] == "busy":
951
            elif response == "BUSY":
986
                self.logger.debug("Response: BUSY\n")
952
                self.logger.debug("Response: BUSY\n")
987
                raise DeviceError("Device busy")
953
                raise DeviceError("Device busy")
988
            else:
-
 
989
                self.logger.debug("Response: UNKOWN\n")
-
 
990
                raise DeviceError("Invalid response! This should NOT happen!")
-
 
991
        else:
954
        else:
992
            return writelen
955
            return writelen
993
 
956
 
994
 
957
 
995
class Dev(object):
958
class Dev(object):