11 from types import ListType |
11 from types import ListType |
12 from threading import Timer, Lock, Thread |
12 from threading import Timer, Lock, Thread |
13 from time import localtime |
13 from time import localtime |
14 from datetime import datetime |
14 from datetime import datetime |
15 from weakref import WeakKeyDictionary |
15 from weakref import WeakKeyDictionary |
|
16 from itertools import izip |
16 |
17 |
17 import targets |
18 import targets |
18 import connectors |
19 import connectors |
19 from util.misc import CheckPathPerm, GetClassImporter |
20 from util.misc import CheckPathPerm, GetClassImporter |
20 from util.MiniTextControler import MiniTextControler |
21 from util.MiniTextControler import MiniTextControler |
26 from editors.DebugViewer import DebugViewer, REFRESH_PERIOD |
27 from editors.DebugViewer import DebugViewer, REFRESH_PERIOD |
27 from dialogs import DiscoveryDialog |
28 from dialogs import DiscoveryDialog |
28 from PLCControler import PLCControler |
29 from PLCControler import PLCControler |
29 from plcopen.structures import IEC_KEYWORDS |
30 from plcopen.structures import IEC_KEYWORDS |
30 from targets.typemapping import DebugTypesSize, LogLevelsCount, LogLevels |
31 from targets.typemapping import DebugTypesSize, LogLevelsCount, LogLevels |
|
32 from targets.typemapping import UnpackDebugBuffer |
31 from ConfigTreeNode import ConfigTreeNode, XSDSchemaErrorMessage |
33 from ConfigTreeNode import ConfigTreeNode, XSDSchemaErrorMessage |
32 |
34 |
33 base_folder = os.path.split(sys.path[0])[0] |
35 base_folder = os.path.split(sys.path[0])[0] |
34 |
36 |
35 MATIEC_ERROR_MODEL = re.compile(".*\.st:(\d+)-(\d+)\.\.(\d+)-(\d+): (?:error)|(?:warning) : (.*)$") |
37 MATIEC_ERROR_MODEL = re.compile(".*\.st:(\d+)-(\d+)\.\.(\d+)-(\d+): (?:error)|(?:warning) : (.*)$") |
734 self._VariablesList = None |
736 self._VariablesList = None |
735 self._DbgVariablesList = None |
737 self._DbgVariablesList = None |
736 self._IECPathToIdx = {} |
738 self._IECPathToIdx = {} |
737 self._Ticktime = 0 |
739 self._Ticktime = 0 |
738 self.TracedIECPath = [] |
740 self.TracedIECPath = [] |
|
741 self.TracedIECTypes = [] |
739 |
742 |
740 def GetIECProgramsAndVariables(self): |
743 def GetIECProgramsAndVariables(self): |
741 """ |
744 """ |
742 Parse CSV-like file VARIABLES.csv resulting from IEC2C compiler. |
745 Parse CSV-like file VARIABLES.csv resulting from IEC2C compiler. |
743 Each section is marked with a line staring with '//' |
746 Each section is marked with a line staring with '//' |
1211 def PullPLCStatusProc(self, event): |
1214 def PullPLCStatusProc(self, event): |
1212 self.UpdateMethodsFromPLCStatus() |
1215 self.UpdateMethodsFromPLCStatus() |
1213 |
1216 |
1214 def SnapshotAndResetDebugValuesBuffers(self): |
1217 def SnapshotAndResetDebugValuesBuffers(self): |
1215 buffers, self.DebugValuesBuffers = (self.DebugValuesBuffers, |
1218 buffers, self.DebugValuesBuffers = (self.DebugValuesBuffers, |
1216 [list() for iec_path in self.TracedIECPath]) |
1219 [list() for n in xrange(len(self.TracedIECPath))]) |
1217 ticks, self.DebugTicks = self.DebugTicks, [] |
1220 ticks, self.DebugTicks = self.DebugTicks, [] |
1218 return ticks, buffers |
1221 return ticks, buffers |
1219 |
1222 |
1220 def RegisterDebugVarToConnector(self): |
1223 def RegisterDebugVarToConnector(self): |
1221 self.DebugTimer=None |
1224 self.DebugTimer=None |
1222 Idxs = [] |
1225 Idxs = [] |
1223 self.TracedIECPath = [] |
1226 self.TracedIECPath = [] |
|
1227 self.TracedIECTypes = [] |
1224 if self._connector is not None: |
1228 if self._connector is not None: |
1225 self.IECdebug_lock.acquire() |
1229 self.IECdebug_lock.acquire() |
1226 IECPathsToPop = [] |
1230 IECPathsToPop = [] |
1227 for IECPath,data_tuple in self.IECdebug_datas.iteritems(): |
1231 for IECPath,data_tuple in self.IECdebug_datas.iteritems(): |
1228 WeakCallableDict, data_log, status, fvalue, buffer_list = data_tuple |
1232 WeakCallableDict, data_log, status, fvalue, buffer_list = data_tuple |
1243 for IECPathToPop in IECPathsToPop: |
1247 for IECPathToPop in IECPathsToPop: |
1244 self.IECdebug_datas.pop(IECPathToPop) |
1248 self.IECdebug_datas.pop(IECPathToPop) |
1245 |
1249 |
1246 if Idxs: |
1250 if Idxs: |
1247 Idxs.sort() |
1251 Idxs.sort() |
1248 self.TracedIECPath = zip(*Idxs)[3] |
1252 IdxsT = zip(*Idxs) |
1249 self._connector.SetTraceVariablesList(zip(*zip(*Idxs)[0:3])) |
1253 self.TracedIECPath = IdxsT[3] |
|
1254 self.TracedIECTypes = IdxsT[1] |
|
1255 self._connector.SetTraceVariablesList(zip(*IdxsT[0:3])) |
1250 else: |
1256 else: |
1251 self.TracedIECPath = [] |
1257 self.TracedIECPath = [] |
1252 self._connector.SetTraceVariablesList([]) |
1258 self._connector.SetTraceVariablesList([]) |
1253 self.SnapshotAndResetDebugValuesBuffers() |
1259 self.SnapshotAndResetDebugValuesBuffers() |
1254 self.IECdebug_lock.release() |
1260 self.IECdebug_lock.release() |
1386 self.debug_break = False |
1392 self.debug_break = False |
1387 debug_getvar_retry = 0 |
1393 debug_getvar_retry = 0 |
1388 while (not self.debug_break) and (self._connector is not None): |
1394 while (not self.debug_break) and (self._connector is not None): |
1389 Trace = self._connector.GetTraceVariables() |
1395 Trace = self._connector.GetTraceVariables() |
1390 if(Trace): |
1396 if(Trace): |
1391 plc_status, debug_tick, debug_vars = Trace |
1397 plc_status, debug_tick, debug_buff = Trace |
1392 else: |
1398 else: |
1393 plc_status = None |
1399 plc_status = None |
1394 debug_getvar_retry += 1 |
1400 debug_getvar_retry += 1 |
1395 #print [dict.keys() for IECPath, (dict, log, status, fvalue) in self.IECdebug_datas.items()] |
1401 #print [dict.keys() for IECPath, (dict, log, status, fvalue) in self.IECdebug_datas.items()] |
1396 if plc_status == "Started": |
1402 if plc_status == "Started" and debug_buff is not None: |
1397 self.IECdebug_lock.acquire() |
1403 self.IECdebug_lock.acquire() |
1398 if (debug_tick is not None and |
1404 debug_vars = UnpackDebugBuffer(debug_buff, self.TracedIECTypes) |
1399 len(debug_vars) == len(self.DebugValuesBuffers) and |
1405 if (debug_tick is not None and debug_vars is not None and |
1400 len(debug_vars) == len(self.TracedIECPath)): |
1406 len(debug_vars) == len(self.TracedIECPath)): |
1401 if debug_getvar_retry > DEBUG_RETRIES_WARN: |
1407 if debug_getvar_retry > DEBUG_RETRIES_WARN: |
1402 self.logger.write(_("... debugger recovered\n")) |
1408 self.logger.write(_("... debugger recovered\n")) |
1403 debug_getvar_retry = 0 |
1409 debug_getvar_retry = 0 |
1404 for IECPath, values_buffer, value in zip(self.TracedIECPath, self.DebugValuesBuffers, debug_vars): |
1410 for IECPath, values_buffer, value in izip( |
1405 IECdebug_data = self.IECdebug_datas.get(IECPath, None) |
1411 self.TracedIECPath, |
|
1412 self.DebugValuesBuffers, |
|
1413 debug_vars): |
|
1414 IECdebug_data = self.IECdebug_datas.get(IECPath, None) #FIXME get |
1406 if IECdebug_data is not None and value is not None: |
1415 if IECdebug_data is not None and value is not None: |
1407 forced = IECdebug_data[2:4] == ["Forced", value] |
1416 forced = IECdebug_data[2:4] == ["Forced", value] |
1408 if not IECdebug_data[4] and len(values_buffer) > 0: |
1417 if not IECdebug_data[4] and len(values_buffer) > 0: |
1409 values_buffer[-1] = (value, forced) |
1418 values_buffer[-1] = (value, forced) |
1410 else: |
1419 else: |
1430 self.IECdebug_lock.acquire() |
1439 self.IECdebug_lock.acquire() |
1431 debug_ticks, buffers = self.SnapshotAndResetDebugValuesBuffers() |
1440 debug_ticks, buffers = self.SnapshotAndResetDebugValuesBuffers() |
1432 self.IECdebug_lock.release() |
1441 self.IECdebug_lock.release() |
1433 start_time = time.time() |
1442 start_time = time.time() |
1434 if len(self.TracedIECPath) == len(buffers): |
1443 if len(self.TracedIECPath) == len(buffers): |
1435 for IECPath, values in zip(self.TracedIECPath, buffers): |
1444 for IECPath, values in izip(self.TracedIECPath, buffers): |
1436 if len(values) > 0: |
1445 if len(values) > 0: |
1437 self.CallWeakcallables(IECPath, "NewValues", debug_ticks, values) |
1446 self.CallWeakcallables(IECPath, "NewValues", debug_ticks, values) |
1438 if len(debug_ticks) > 0: |
1447 if len(debug_ticks) > 0: |
1439 self.CallWeakcallables("__tick__", "NewDataAvailable", debug_ticks) |
1448 self.CallWeakcallables("__tick__", "NewDataAvailable", debug_ticks) |
1440 |
1449 |