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 |