108 def ResetLogCount(self): |
108 def ResetLogCount(self): |
109 if self._ResetLogCount is not None: |
109 if self._ResetLogCount is not None: |
110 self._ResetLogCount() |
110 self._ResetLogCount() |
111 |
111 |
112 def GetLogCount(self, level): |
112 def GetLogCount(self, level): |
113 if self._GetLogCount is not None : |
113 if self._GetLogCount is not None: |
114 return int(self._GetLogCount(level)) |
114 return int(self._GetLogCount(level)) |
115 elif self._loading_error is not None and level==0: |
115 elif self._loading_error is not None and level==0: |
116 return 1 |
116 return 1 |
117 |
117 |
118 def GetLogMessage(self, level, msgid): |
118 def GetLogMessage(self, level, msgid): |
149 try: |
149 try: |
150 self._PLClibraryHandle = dlopen(self._GetLibFileName()) |
150 self._PLClibraryHandle = dlopen(self._GetLibFileName()) |
151 self.PLClibraryHandle = ctypes.CDLL(self.CurrentPLCFilename, handle=self._PLClibraryHandle) |
151 self.PLClibraryHandle = ctypes.CDLL(self.CurrentPLCFilename, handle=self._PLClibraryHandle) |
152 |
152 |
153 self.PLC_ID = ctypes.c_char_p.in_dll(self.PLClibraryHandle, "PLC_ID") |
153 self.PLC_ID = ctypes.c_char_p.in_dll(self.PLClibraryHandle, "PLC_ID") |
154 if len(md5) == 32 : |
154 if len(md5) == 32: |
155 self.PLC_ID.value = md5 |
155 self.PLC_ID.value = md5 |
156 |
156 |
157 self._startPLC = self.PLClibraryHandle.startPLC |
157 self._startPLC = self.PLClibraryHandle.startPLC |
158 self._startPLC.restype = ctypes.c_int |
158 self._startPLC.restype = ctypes.c_int |
159 self._startPLC.argtypes = [ctypes.c_int, ctypes.POINTER(ctypes.c_char_p)] |
159 self._startPLC.argtypes = [ctypes.c_int, ctypes.POINTER(ctypes.c_char_p)] |
278 self.python_runtime_vars = globals().copy() |
278 self.python_runtime_vars = globals().copy() |
279 self.python_runtime_vars.update(self.pyruntimevars) |
279 self.python_runtime_vars.update(self.pyruntimevars) |
280 |
280 |
281 class PLCSafeGlobals: |
281 class PLCSafeGlobals: |
282 def __getattr__(_self, name): |
282 def __getattr__(_self, name): |
283 try : |
283 try: |
284 t = self.python_runtime_vars["_"+name+"_ctype"] |
284 t = self.python_runtime_vars["_"+name+"_ctype"] |
285 except KeyError: |
285 except KeyError: |
286 raise KeyError("Try to get unknown shared global variable : %s" % name) |
286 raise KeyError("Try to get unknown shared global variable : %s" % name) |
287 v = t() |
287 v = t() |
288 r = self.python_runtime_vars["_PySafeGetPLCGlob_"+name](ctypes.byref(v)) |
288 r = self.python_runtime_vars["_PySafeGetPLCGlob_"+name](ctypes.byref(v)) |
289 return self.python_runtime_vars["_"+name+"_unpack"](v) |
289 return self.python_runtime_vars["_"+name+"_unpack"](v) |
290 def __setattr__(_self, name, value): |
290 def __setattr__(_self, name, value): |
291 try : |
291 try: |
292 t = self.python_runtime_vars["_"+name+"_ctype"] |
292 t = self.python_runtime_vars["_"+name+"_ctype"] |
293 except KeyError: |
293 except KeyError: |
294 raise KeyError("Try to set unknown shared global variable : %s" % name) |
294 raise KeyError("Try to set unknown shared global variable : %s" % name) |
295 v = self.python_runtime_vars["_"+name+"_pack"](t,value) |
295 v = self.python_runtime_vars["_"+name+"_pack"](t,value) |
296 self.python_runtime_vars["_PySafeSetPLCGlob_"+name](ctypes.byref(v)) |
296 self.python_runtime_vars["_PySafeSetPLCGlob_"+name](ctypes.byref(v)) |
297 |
297 |
298 self.python_runtime_vars.update({ |
298 self.python_runtime_vars.update({ |
299 "PLCGlobals" : PLCSafeGlobals(), |
299 "PLCGlobals": PLCSafeGlobals(), |
300 "WorkingDir" : self.workingdir, |
300 "WorkingDir": self.workingdir, |
301 "PLCObject" : self, |
301 "PLCObject": self, |
302 "PLCBinary" : self.PLClibraryHandle, |
302 "PLCBinary": self.PLClibraryHandle, |
303 "PLCGlobalsDesc" : []}) |
303 "PLCGlobalsDesc": []}) |
304 |
304 |
305 for methodname in MethodNames : |
305 for methodname in MethodNames: |
306 self.python_runtime_vars["_runtime_%s" % methodname] = [] |
306 self.python_runtime_vars["_runtime_%s" % methodname] = [] |
307 |
307 |
308 try: |
308 try: |
309 filenames = os.listdir(self.workingdir) |
309 filenames = os.listdir(self.workingdir) |
310 filenames.sort() |
310 filenames.sort() |
339 cmd = self._PythonIterator(res,blkid) |
339 cmd = self._PythonIterator(res,blkid) |
340 FBID = blkid.value |
340 FBID = blkid.value |
341 # print " -> ", cmd, blkid |
341 # print " -> ", cmd, blkid |
342 if cmd is None: |
342 if cmd is None: |
343 break |
343 break |
344 try : |
344 try: |
345 self.python_runtime_vars["FBID"]=FBID |
345 self.python_runtime_vars["FBID"]=FBID |
346 ccmd,AST =compile_cache.get(FBID, (None,None)) |
346 ccmd,AST =compile_cache.get(FBID, (None,None)) |
347 if ccmd is None or ccmd!=cmd: |
347 if ccmd is None or ccmd!=cmd: |
348 AST = compile(cmd, '<plc>', 'eval') |
348 AST = compile(cmd, '<plc>', 'eval') |
349 compile_cache[FBID]=(cmd,AST) |
349 compile_cache[FBID]=(cmd,AST) |
384 self._stopPLC() |
384 self._stopPLC() |
385 self.PythonThread.join() |
385 self.PythonThread.join() |
386 self.PLCStatus = "Stopped" |
386 self.PLCStatus = "Stopped" |
387 self.StatusChange() |
387 self.StatusChange() |
388 self.PythonRuntimeCall("stop") |
388 self.PythonRuntimeCall("stop") |
389 if self.TraceThread is not None : |
389 if self.TraceThread is not None: |
390 self.TraceWakeup.set() |
390 self.TraceWakeup.set() |
391 self.TraceThread.join() |
391 self.TraceThread.join() |
392 self.TraceThread = None |
392 self.TraceThread = None |
393 return True |
393 return True |
394 return False |
394 return False |
493 self._suspendDebug(True) |
493 self._suspendDebug(True) |
494 |
494 |
495 def _TracesPush(self, trace): |
495 def _TracesPush(self, trace): |
496 self.TraceLock.acquire() |
496 self.TraceLock.acquire() |
497 lT = len(self.Traces) |
497 lT = len(self.Traces) |
498 if lT != 0 and lT * len(self.Traces[0]) > 1024 * 1024 : |
498 if lT != 0 and lT * len(self.Traces[0]) > 1024 * 1024: |
499 self.Traces.pop(0) |
499 self.Traces.pop(0) |
500 self.Traces.append(trace) |
500 self.Traces.append(trace) |
501 self.TraceLock.release() |
501 self.TraceLock.release() |
502 |
502 |
503 def _TracesSwap(self): |
503 def _TracesSwap(self): |
534 |
534 |
535 def TraceThreadProc(self): |
535 def TraceThreadProc(self): |
536 """ |
536 """ |
537 Return a list of traces, corresponding to the list of required idx |
537 Return a list of traces, corresponding to the list of required idx |
538 """ |
538 """ |
539 while self.PLCStatus == "Started" : |
539 while self.PLCStatus == "Started": |
540 tick = ctypes.c_uint32() |
540 tick = ctypes.c_uint32() |
541 size = ctypes.c_uint32() |
541 size = ctypes.c_uint32() |
542 buff = ctypes.c_void_p() |
542 buff = ctypes.c_void_p() |
543 TraceBuffer = None |
543 TraceBuffer = None |
544 if self.PLClibraryLock.acquire(False): |
544 if self.PLClibraryLock.acquire(False): |