38 "linux2":".so", |
38 "linux2":".so", |
39 "win32":".dll", |
39 "win32":".dll", |
40 }.get(sys.platform, "") |
40 }.get(sys.platform, "") |
41 |
41 |
42 class PLCObject(pyro.ObjBase): |
42 class PLCObject(pyro.ObjBase): |
|
43 _Idxs = [] |
43 def __init__(self, workingdir, daemon, argv): |
44 def __init__(self, workingdir, daemon, argv): |
44 pyro.ObjBase.__init__(self) |
45 pyro.ObjBase.__init__(self) |
45 self.argv = [workingdir] + argv # force argv[0] to be "path" to exec... |
46 self.argv = [workingdir] + argv # force argv[0] to be "path" to exec... |
46 self.workingdir = workingdir |
47 self.workingdir = workingdir |
47 self.PLCStatus = "Stopped" |
48 self.PLCStatus = "Stopped" |
84 self._stopPLC.restype = None |
85 self._stopPLC.restype = None |
85 |
86 |
86 self._ResetDebugVariables = self.PLClibraryHandle.ResetDebugVariables |
87 self._ResetDebugVariables = self.PLClibraryHandle.ResetDebugVariables |
87 self._ResetDebugVariables.restype = None |
88 self._ResetDebugVariables.restype = None |
88 |
89 |
89 self._RegisterDebugVariable = self.PLClibraryHandle.ResetDebugVariables |
90 self._RegisterDebugVariable = self.PLClibraryHandle.RegisterDebugVariable |
90 self._RegisterDebugVariable.restype = None |
91 self._RegisterDebugVariable.restype = None |
|
92 self._RegisterDebugVariable.argtypes = [ctypes.c_int] |
91 |
93 |
92 self._IterDebugData = self.PLClibraryHandle.IterDebugData |
94 self._IterDebugData = self.PLClibraryHandle.IterDebugData |
93 self._IterDebugData.restype = ctypes.c_void_p |
95 self._IterDebugData.restype = ctypes.c_void_p |
94 self._IterDebugData.argtypes = [ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.c_char_p)] |
96 self._IterDebugData.argtypes = [ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.c_char_p)] |
95 |
97 |
96 self._FreeDebugData = self.PLClibraryHandle.FreeDebugData |
98 self._FreeDebugData = self.PLClibraryHandle.FreeDebugData |
97 self._FreeDebugData.restype = None |
99 self._FreeDebugData.restype = None |
98 |
100 |
99 self._WaitDebugData = self.PLClibraryHandle.WaitDebugData |
101 self._WaitDebugData = self.PLClibraryHandle.WaitDebugData |
100 self._WaitDebugData.restype = ctypes.c_int |
102 self._WaitDebugData.restype = ctypes.c_int |
|
103 |
|
104 self._suspendDebug = self.PLClibraryHandle.suspendDebug |
|
105 self._suspendDebug.restype = None |
|
106 |
|
107 self._resumeDebug = self.PLClibraryHandle.resumeDebug |
|
108 self._resumeDebug.restype = None |
|
109 |
101 return True |
110 return True |
102 except: |
111 except: |
103 print traceback.format_exc() |
112 print traceback.format_exc() |
104 return False |
113 return False |
105 |
114 |
113 self._stopPLC = lambda:None |
122 self._stopPLC = lambda:None |
114 self._ResetDebugVariables = lambda:None |
123 self._ResetDebugVariables = lambda:None |
115 self._RegisterDebugVariable = lambda x:None |
124 self._RegisterDebugVariable = lambda x:None |
116 self._IterDebugData = lambda x,y:None |
125 self._IterDebugData = lambda x,y:None |
117 self._FreeDebugData = lambda:None |
126 self._FreeDebugData = lambda:None |
|
127 self._WaitDebugData = lambda:-1 |
|
128 self._suspendDebug = lambda:None |
|
129 self._resumeDebug = lambda:None |
118 self.PLClibraryHandle = None |
130 self.PLClibraryHandle = None |
119 # Unload library explicitely |
131 # Unload library explicitely |
120 if getattr(self,"_PLClibraryHandle",None) is not None: |
132 if getattr(self,"_PLClibraryHandle",None) is not None: |
121 print "Unload PLC" |
133 print "Unload PLC" |
122 dlclose(self._PLClibraryHandle) |
134 dlclose(self._PLClibraryHandle) |
149 #dlclose(badhandle) |
161 #dlclose(badhandle) |
150 return True |
162 return True |
151 return False |
163 return False |
152 |
164 |
153 |
165 |
154 def StartPLC(self): |
166 def StartPLC(self, debug=False): |
155 print "StartPLC" |
167 print "StartPLC" |
156 if self.CurrentPLCFilename is not None and self.PLCStatus == "Stopped": |
168 if self.CurrentPLCFilename is not None and self.PLCStatus == "Stopped": |
157 c_argv = ctypes.c_char_p * len(self.argv) |
169 c_argv = ctypes.c_char_p * len(self.argv) |
158 if self._LoadNewPLC() and self._startPLC(len(self.argv),c_argv(*self.argv)) == 0: |
170 if self._LoadNewPLC() and self._startPLC(len(self.argv),c_argv(*self.argv)) == 0: |
|
171 if debug: |
|
172 self._resumeDebug() |
159 self.PLCStatus = "Started" |
173 self.PLCStatus = "Started" |
160 return True |
174 return True |
161 else: |
175 else: |
162 print "_StartPLC did not return 0 !" |
176 print "_StartPLC did not return 0 !" |
163 self._DoStopPLC() |
177 self._DoStopPLC() |
242 def SetTraceVariablesList(self, idxs): |
256 def SetTraceVariablesList(self, idxs): |
243 """ |
257 """ |
244 Call ctype imported function to append |
258 Call ctype imported function to append |
245 these indexes to registred variables in PLC debugger |
259 these indexes to registred variables in PLC debugger |
246 """ |
260 """ |
|
261 self._suspendDebug() |
247 # keep a copy of requested idx |
262 # keep a copy of requested idx |
248 self._Idxs = idxs[:] |
263 self._Idxs = idxs[:] |
249 self._ResetDebugVariables() |
264 self._ResetDebugVariables() |
250 for idx in idxs: |
265 for idx in idxs: |
251 self._RegisterDebugVariable(idx) |
266 self._RegisterDebugVariable(idx) |
|
267 self._resumeDebug() |
252 |
268 |
253 TypeTranslator = {"BOOL" : ctypes.c_uint8, |
269 TypeTranslator = {"BOOL" : ctypes.c_uint8, |
254 "STEP" : ctypes.c_uint8, |
270 "STEP" : ctypes.c_uint8, |
255 "TRANSITION" : ctypes.c_uint8, |
271 "TRANSITION" : ctypes.c_uint8, |
256 "ACTION" : ctypes.c_uint8, |
272 "ACTION" : ctypes.c_uint8, |
275 def GetTraceVariables(self): |
291 def GetTraceVariables(self): |
276 """ |
292 """ |
277 Return a list of variables, corresponding to the list of requiered idx |
293 Return a list of variables, corresponding to the list of requiered idx |
278 """ |
294 """ |
279 tick = self._WaitDebugData() |
295 tick = self._WaitDebugData() |
|
296 if tick == -1: |
|
297 return -1,None |
280 idx = ctypes.c_int() |
298 idx = ctypes.c_int() |
281 typename = ctypes.c_char_p() |
299 typename = ctypes.c_char_p() |
282 res = [] |
300 res = [] |
283 |
301 |
284 for idx in self._Idxs: |
302 for given_idx in self._Idxs: |
285 buffer=self._IterDebugData(ctypes.byref(idx), ctypes.byref(typename)) |
303 buffer=self._IterDebugData(ctypes.byref(idx), ctypes.byref(typename)) |
286 c_type = TypeTranslator.get(s.value, None) |
304 c_type = self.TypeTranslator.get(typename.value, None) |
287 if c_type is not None: |
305 if c_type is not None and given_idx == idx.value: |
288 res += cast(buffer, POINTER(c_type)).value |
306 res.append(ctypes.cast(buffer, |
|
307 ctypes.POINTER(c_type)).contents.value) |
289 else: |
308 else: |
290 res += None |
309 print "Debug error idx : %d, expected_idx %d, type : %s"%(idx.value, given_idx,typename.value) |
|
310 res.append(None) |
291 self._FreeDebugData() |
311 self._FreeDebugData() |
292 return res |
312 return tick, res |
293 |
313 |
294 |
314 |
295 |
315 |