connectors/LPC/LPCObject.py
changeset 453 923d036dfa90
parent 448 8ef035de86de
child 502 5343ae43f6d0
equal deleted inserted replaced
452:2d0718a05cc7 453:923d036dfa90
    23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    24 
    24 
    25 from threading import Timer, Thread, Lock
    25 from threading import Timer, Thread, Lock
    26 import ctypes, os, commands, types, sys
    26 import ctypes, os, commands, types, sys
    27 import traceback
    27 import traceback
       
    28 from LPCProto import *
    28 
    29 
    29 class LPCObject():
    30 class LPCObject():
    30     _Idxs = []
       
    31     def __init__(self,pluginsroot):
    31     def __init__(self,pluginsroot):
    32         self.PLCStatus = "Stopped"
    32         self.PLCStatus = "Stopped"
    33         self.pluginsroot = pluginsroot
    33         self.pluginsroot = pluginsroot
    34         self.PLCprint = pluginsroot.logger.write
    34         self.PLCprint = pluginsroot.logger.write
    35     
    35         self.SerialConnection = None
       
    36         self._Idxs = []
       
    37         
       
    38     def HandleSerialTransaction(self, transaction):
       
    39         if self.SerialConnection is None:
       
    40             try:
       
    41                 self.SerialConnection = LPCProto(6,115200,2)
       
    42             except Exception,e:
       
    43                 self.pluginsroot.logger.write_error(str(e)+"\n")
       
    44                 self.SerialConnection = None
       
    45                 return "Disconnected", res
       
    46         try:
       
    47             return self.SerialConnection.HandleTransaction(transaction)
       
    48         except LPCError,e:
       
    49             #pluginsroot.logger.write_error(traceback.format_exc())
       
    50             self.pluginsroot.logger.write_error(str(e)+"\n")
       
    51             self.SerialConnection = None
       
    52             return "Disconnected", res
       
    53 
    36     def StartPLC(self, debug=False):
    54     def StartPLC(self, debug=False):
    37         PLCprint("StartPLC")
    55         PLCprint("StartPLC")
    38         if self.CurrentPLCFilename is not None:
    56         self.HandleSerialTransaction(STARTTransaction())
    39             self.PLCStatus = "Started"
       
    40             self.PythonThread = Thread(target=self.PythonThreadProc, args=[debug])
       
    41             self.PythonThread.start()
       
    42             
    57             
    43     def StopPLC(self):
    58     def StopPLC(self):
    44         PLCprint("StopPLC")
    59         PLCprint("StopPLC")
    45         if self.PLCStatus == "Started":
    60         self.HandleSerialTransaction(STOPTransaction())
    46             self._stopPLC()
       
    47             return True
       
    48         return False
       
    49 
    61 
    50     def ForceReload(self):
    62     def ForceReload(self):
    51         # respawn python interpreter
    63         pass
    52         Timer(0.1,self._Reload).start()
       
    53         return True
       
    54 
    64 
    55     def GetPLCstatus(self):
    65     def GetPLCstatus(self):
    56         return self.PLCStatus
    66         status,data = self.HandleSerialTransaction(IDLETransaction())
       
    67         return status
    57     
    68     
    58     def NewPLC(self, md5sum, data, extrafiles):
    69     def NewPLC(self, md5sum, data, extrafiles):
    59         PLCprint("NewPLC (%s)"%md5sum)
    70         pass
    60         if self.PLCStatus in ["Stopped", "Empty", "Broken"]:
       
    61             NewFileName = md5sum + lib_ext
       
    62             extra_files_log = os.path.join(self.workingdir,"extra_files.txt")
       
    63             try:
       
    64                 os.remove(os.path.join(self.workingdir,
       
    65                                        self.CurrentPLCFilename))
       
    66                 for filename in file(extra_files_log, "r").readlines() + [extra_files_log]:
       
    67                     try:
       
    68                         os.remove(os.path.join(self.workingdir, filename.strip()))
       
    69                     except:
       
    70                         pass
       
    71             except:
       
    72                 pass
       
    73                         
       
    74             try:
       
    75                 # Create new PLC file
       
    76                 open(os.path.join(self.workingdir,NewFileName),
       
    77                      'wb').write(data)
       
    78         
       
    79                 # Store new PLC filename based on md5 key
       
    80                 open(self._GetMD5FileName(), "w").write(md5sum)
       
    81         
       
    82                 # Then write the files
       
    83                 log = file(extra_files_log, "w")
       
    84                 for fname,fdata in extrafiles:
       
    85                     fpath = os.path.join(self.workingdir,fname)
       
    86                     open(fpath, "wb").write(fdata)
       
    87                     log.write(fname+'\n')
       
    88 
       
    89                 # Store new PLC filename
       
    90                 self.CurrentPLCFilename = NewFileName
       
    91             except:
       
    92                 PLCprint(traceback.format_exc())
       
    93                 return False
       
    94             if self.PLCStatus == "Empty":
       
    95                 self.PLCStatus = "Stopped"
       
    96             return True
       
    97         return False
       
    98 
    71 
    99     def MatchMD5(self, MD5):
    72     def MatchMD5(self, MD5):
   100         try:
    73         status,data = self.HandleSerialTransaction(PLCIDTransaction())
   101             last_md5 = open(self._GetMD5FileName(), "r").read()
    74         return data == MD5
   102             return last_md5 == MD5
       
   103         except:
       
   104             return False
       
   105     
    75     
   106     def SetTraceVariablesList(self, idxs):
    76     def SetTraceVariablesList(self, idxs):
   107         """
    77         self._Idxs = idxs[]
   108         Call ctype imported function to append 
    78         status,data = self.HandleSerialTransaction(
   109         these indexes to registred variables in PLC debugger
    79                SET_TRACE_VARIABLETransaction(
   110         """
    80                      ''.join(map(chr,idx))))
   111         self._suspendDebug()
       
   112         # keep a copy of requested idx
       
   113         self._Idxs = idxs[:]
       
   114         self._ResetDebugVariables()
       
   115         for idx in idxs:
       
   116             self._RegisterDebugVariable(idx)
       
   117         self._resumeDebug()
       
   118 
    81 
   119     class IEC_STRING(ctypes.Structure):
    82     class IEC_STRING(ctypes.Structure):
   120         """
    83         """
   121         Must be changed according to changes in iec_types.h
    84         Must be changed according to changes in iec_types.h
   122         """
    85         """
   147                            
   110                            
   148     def GetTraceVariables(self):
   111     def GetTraceVariables(self):
   149         """
   112         """
   150         Return a list of variables, corresponding to the list of required idx
   113         Return a list of variables, corresponding to the list of required idx
   151         """
   114         """
   152         if self.PLCStatus == "Started":
   115         status,data = self.HandleSerialTransaction(GET_TRACE_VARIABLETransaction())
   153             self.PLClibraryLock.acquire()
   116         if data is not None:
   154             tick = self._WaitDebugData()
   117             # transform serial string to real byte string in memory 
   155             #PLCprint("Debug tick : %d"%tick)
   118             buffer = ctypes.c_char_p(data)
   156             if tick == 2**32 - 1:
   119             # tick is first value in buffer
   157                 tick = -1
   120             tick = ctypes.cast(buffer,ctypes.POINTER(ctypes.c_uint32)).contents
   158                 res = None
   121             # variable data starts just after tick 
   159             else:
   122             cursorp = ctypes.addressof(buffer) = ctypes.sizeof(ctypes.c_uint32)
   160                 idx = ctypes.c_int()
   123             endp = offset + len(data)
   161                 typename = ctypes.c_char_p()
   124             for idx, iectype in self._Idxs:
   162                 res = []
   125                 cursor = ctypes.c_void_p(cursorp)
   163         
   126                 c_type,unpack_func = self.TypeTranslator.get(iectype, (None,None))
   164                 for given_idx in self._Idxs:
   127                 if c_type is not None and cursorp < endp:
   165                     buffer=self._IterDebugData(ctypes.byref(idx), ctypes.byref(typename))
   128                     res.append(unpack_func(ctypes.cast(cursor,
   166                     c_type,unpack_func = self.TypeTranslator.get(typename.value, (None,None))
   129                                                        ctypes.POINTER(c_type)).contents))
   167                     if c_type is not None and given_idx == idx.value:
   130                     cursorp += ctypes.sizeof(c_type) 
   168                         res.append(unpack_func(ctypes.cast(buffer,
   131                 else:
   169                                                            ctypes.POINTER(c_type)).contents))
   132                     PLCprint("Debug error !")
   170                     else:
   133                         break
   171                         PLCprint("Debug error idx : %d, expected_idx %d, type : %s"%(idx.value, given_idx,typename.value))
   134             return self.PLCStatus, tick, res
   172                         res.append(None)
   135         return self.PLCStatus, None, None
   173             self._FreeDebugData()
       
   174             self.PLClibraryLock.release()
       
   175             return tick, res
       
   176         return -1, None
       
   177 
   136