runtime/PLCObject.py
changeset 286 a2a8a52b0d4f
parent 283 d0e6fc0701fb
child 290 3bd617ae7a05
equal deleted inserted replaced
285:e5782a52dcea 286:a2a8a52b0d4f
    58                              self._GetMD5FileName(),
    58                              self._GetMD5FileName(),
    59                              "r").read().strip() + lib_ext
    59                              "r").read().strip() + lib_ext
    60         except Exception, e:
    60         except Exception, e:
    61             self.PLCStatus = "Empty"
    61             self.PLCStatus = "Empty"
    62             self.CurrentPLCFilename=None
    62             self.CurrentPLCFilename=None
       
    63 
       
    64     def StatusChange(self):
       
    65         if self.statuschange is not None:
       
    66             self.statuschange(self.PLCStatus)
    63 
    67 
    64     def _GetMD5FileName(self):
    68     def _GetMD5FileName(self):
    65         return os.path.join(self.workingdir, "lasttransferedPLC.md5")
    69         return os.path.join(self.workingdir, "lasttransferedPLC.md5")
    66 
    70 
    67     def _GetLibFileName(self):
    71     def _GetLibFileName(self):
   167                     #dlclose(badhandle)
   171                     #dlclose(badhandle)
   168                     return True
   172                     return True
   169         return False
   173         return False
   170 
   174 
   171     def PythonThreadProc(self):
   175     def PythonThreadProc(self):
       
   176         print "PythonThreadProc started"
       
   177         my_globs = globals().copy()
   172         pyfile = os.path.join(self.workingdir, "runtime.py")
   178         pyfile = os.path.join(self.workingdir, "runtime.py")
   173         if os.path.exists(pyfile):
   179         if os.path.exists(pyfile):
   174             # TODO handle exceptions in runtime.py
   180             # TODO handle exceptions in runtime.py
   175             execfile(pyfile)
   181             # pyfile may redefine _runtime_cleanup
   176         res = ""
   182             # or even call _PythonThreadProc itself.
   177         print "PythonThreadProc started"
   183             execfile(pyfile, my_globs)
       
   184         res,cmd = "None","None"
   178         while self.PLCStatus == "Started":
   185         while self.PLCStatus == "Started":
       
   186             print "_PythonIterator(", res, ")",
   179             cmd = self._PythonIterator(res)
   187             cmd = self._PythonIterator(res)
   180             #print "_PythonIterator(", res, ") -> ", cmd
   188             print " -> ", cmd
       
   189             if cmd is None:
       
   190                 break
   181             try :
   191             try :
   182                 res = eval(cmd)
   192                 res = str(eval(cmd,my_globs))
   183             except Exception,e:
   193             except Exception,e:
   184                 res = "#EXCEPTION : "+str(e)
   194                 res = "#EXCEPTION : "+str(e)
   185                 print res
   195                 print res
   186         print "PythonThreadProc finished"
   196         print "PythonThreadProc interrupted"
       
   197         if my_globs.get("_runtime_cleanup",None) is not None:
       
   198             my_globs["_runtime_cleanup"]()
       
   199         print "PythonThreadProc cleaned up"
   187     
   200     
   188     def StartPLC(self, debug=False):
   201     def StartPLC(self, debug=False):
   189         print "StartPLC"
   202         print "StartPLC"
   190         if self.CurrentPLCFilename is not None and self.PLCStatus == "Stopped":
   203         if self.CurrentPLCFilename is not None and self.PLCStatus == "Stopped":
   191             c_argv = ctypes.c_char_p * len(self.argv)
   204             c_argv = ctypes.c_char_p * len(self.argv)
   192             if self._LoadNewPLC() and self._startPLC(len(self.argv),c_argv(*self.argv)) == 0:
   205             if self._LoadNewPLC() and self._startPLC(len(self.argv),c_argv(*self.argv)) == 0:
   193                 if debug:
   206                 if debug:
   194                     self._resumeDebug()
   207                     self._resumeDebug()
   195                 self.PLCStatus = "Started"
   208                 self.PLCStatus = "Started"
   196                 if self.statuschange is not None:
   209                 self.StatusChange()
   197                     self.statuschange(self.PLCStatus)
       
   198                 self.PythonThread = Thread(target=self.PythonThreadProc)
   210                 self.PythonThread = Thread(target=self.PythonThreadProc)
   199                 self.PythonThread.start()
   211                 self.PythonThread.start()
   200                 return True
   212                 return True
   201             else:
   213             else:
   202                 print "_StartPLC did not return 0 !"
   214                 print "_StartPLC did not return 0 !"
   204         return False
   216         return False
   205 
   217 
   206     def _DoStopPLC(self):
   218     def _DoStopPLC(self):
   207         self._stopPLC()
   219         self._stopPLC()
   208         self.PLCStatus = "Stopped"
   220         self.PLCStatus = "Stopped"
   209         if self.statuschange is not None:
   221         self.PythonThread.join(timeout=1)
   210             self.statuschange(self.PLCStatus)
   222         if self.PythonThread.isAlive():
       
   223             print "Python thread couldn't be killed"
   211         if self._FreePLC():
   224         if self._FreePLC():
   212             self.PLCStatus = "Dirty"
   225             self.PLCStatus = "Dirty"
       
   226         self.StatusChange()
   213         return True
   227         return True
   214 
   228 
   215     def StopPLC(self):
   229     def StopPLC(self):
   216         if self.PLCStatus == "Started":
   230         if self.PLCStatus == "Started":
   217             self._DoStopPLC()
   231             self._DoStopPLC()
   325                            
   339                            
   326     def GetTraceVariables(self):
   340     def GetTraceVariables(self):
   327         """
   341         """
   328         Return a list of variables, corresponding to the list of requiered idx
   342         Return a list of variables, corresponding to the list of requiered idx
   329         """
   343         """
   330         tick = self._WaitDebugData()
   344         if self.PLCStatus == "Started":
   331         if tick == -1:
   345             tick = self._WaitDebugData()
   332             res = None
   346             if tick == -1:
   333         else:
   347                 res = None
   334             idx = ctypes.c_int()
   348             else:
   335             typename = ctypes.c_char_p()
   349                 idx = ctypes.c_int()
   336             res = []
   350                 typename = ctypes.c_char_p()
   337     
   351                 res = []
   338             for given_idx in self._Idxs:
   352         
   339                 buffer=self._IterDebugData(ctypes.byref(idx), ctypes.byref(typename))
   353                 for given_idx in self._Idxs:
   340                 c_type,unpack_func = self.TypeTranslator.get(typename.value, (None,None))
   354                     buffer=self._IterDebugData(ctypes.byref(idx), ctypes.byref(typename))
   341                 if c_type is not None and given_idx == idx.value:
   355                     c_type,unpack_func = self.TypeTranslator.get(typename.value, (None,None))
   342                     res.append(unpack_func(ctypes.cast(buffer,
   356                     if c_type is not None and given_idx == idx.value:
   343                                                        ctypes.POINTER(c_type)).contents))
   357                         res.append(unpack_func(ctypes.cast(buffer,
   344                 else:
   358                                                            ctypes.POINTER(c_type)).contents))
   345                     print "Debug error idx : %d, expected_idx %d, type : %s"%(idx.value, given_idx,typename.value)
   359                     else:
   346                     res.append(None)
   360                         print "Debug error idx : %d, expected_idx %d, type : %s"%(idx.value, given_idx,typename.value)
   347         self._FreeDebugData()
   361                         res.append(None)
   348         return tick, res
   362             self._FreeDebugData()
   349         
   363             return tick, res
   350 
   364         return -1, None
   351 
   365         
       
   366 
       
   367