- Some improovements in debug data feedback data
authoretisserant
Thu, 28 Aug 2008 14:53:11 +0200
changeset 227 48c13b84505c
parent 226 f301f4ed4717
child 228 848da15cf513
- Some improovements in debug data feedback data
- Added "LOCAL://" uri support for local runtime support on randomized port
Beremiz.py
connectors/__init__.py
plugger.py
runtime/PLCObject.py
targets/Linux/plc_Linux_main.c
--- a/Beremiz.py	Thu Aug 28 14:51:46 2008 +0200
+++ b/Beremiz.py	Thu Aug 28 14:53:11 2008 +0200
@@ -27,6 +27,7 @@
 import os, sys, getopt, wx
 import tempfile
 import shutil
+import random
 
 _local_path = os.path.split(os.path.realpath(__file__))[0]
 def Bpath(*args):
@@ -359,16 +360,21 @@
         
         self.Log = LogPseudoFile(self.LogConsole)
         
+        # create temporary directory for runtime working directory
         self.local_runtime_tmpdir = tempfile.mkdtemp()
+        # choose an arbitrary random port for runtime
+        runtime_port = int(random.random() * 1000) + 61131
+        # launch local runtime
         self.local_runtime = ProcessLogger(self.Log,
-                                           "%s %s -i localhost %s"%(sys.executable,
+                                           "%s %s -p %s -i localhost %s"%(sys.executable,
                                                        Bpath("Beremiz_service.py"),
+                                                       runtime_port,
                                                        self.local_runtime_tmpdir))
         
         # Add beremiz's icon in top left corner of the frame
         self.SetIcon(wx.Icon(Bpath( "images", "brz.ico"), wx.BITMAP_TYPE_ICO))
         
-        self.PluginRoot = PluginsRoot(self, self.Log)
+        self.PluginRoot = PluginsRoot(self, self.Log, runtime_port)
         self.DisableEvents = False
         
         self.PluginInfos = {}
--- a/connectors/__init__.py	Thu Aug 28 14:51:46 2008 +0200
+++ b/connectors/__init__.py	Thu Aug 28 14:53:11 2008 +0200
@@ -38,6 +38,11 @@
         connectormodule = getattr(__import__("connectors."+servicetype), servicetype)
         factoryname = servicetype + "_connector_factory"
         return getattr(connectormodule, factoryname)(uri, pluginsroot)
+    elif servicetype == "LOCAL":
+        import PYRO
+        return PYRO.PYRO_connector_factory(
+                       "PYRO://127.0.0.1:"+str(pluginsroot.runtime_port), 
+                       pluginsroot)
     else :
         return None    
 
--- a/plugger.py	Thu Aug 28 14:51:46 2008 +0200
+++ b/plugger.py	Thu Aug 28 14:53:11 2008 +0200
@@ -652,9 +652,10 @@
     </xsd:schema>
     """
 
-    def __init__(self, frame, logger):
+    def __init__(self, frame, logger, runtime_port):
         PLCControler.__init__(self)
-        
+
+        self.runtime_port = runtime_port
         self.MandatoryParams = None
         self.AppFrame = frame
         self.logger = logger
@@ -662,8 +663,8 @@
         self._connector = None
         
         # Setup debug information
-        self.IECdebug_callables = {}
-        self.IECdebug_callables_lock = Lock()
+        self.IECdebug_datas = {}
+        self.IECdebug_lock = Lock()
 
         # Timer to prevent rapid-fire when registering many variables
         self.DebugTimer=Timer(0.5,self.RegisterDebugVarToConnector)
@@ -1060,12 +1061,15 @@
     def RegisterDebugVarToConnector(self):
         Idxs = []
         if self._connector is not None:
-            self.IECdebug_callables_lock.acquire()
-            for IECPath,WeakCallableDict in self.IECdebug_callables:
+            self.IECdebug_lock.acquire()
+            for IECPath,data_tuple in self.IECdebug_datas:
+                WeakCallableDict, data_log, status = data_tuple
                 if len(WeakCallableDict) == 0:
                     # Callable Dict is empty.
                     # This variable is not needed anymore!
-                    self.IECdebug_callables.pop(IECPath)
+                    # self.IECdebug_callables.pop(IECPath)
+                    # TODO
+                    pass
                 else:
                     # Convert 
                     Idx = self._IECPathToIdx.get(IECPath,None)
@@ -1073,7 +1077,7 @@
                         Idxs.append(Idx)
                     else:
                         self.logger.write_warning("Debug : Unknown variable %s\n"%IECPath)
-            self.IECdebug_callables_lock.release()
+            self.IECdebug_lock.release()
             self._connector.TraceVariables(Idxs)
         
     def SubscribeDebugIECVariable(self, IECPath, callable, *args, **kwargs):
@@ -1082,12 +1086,19 @@
         to a WeakKeyDictionary linking 
         weakly referenced callables to optionnal args
         """
-        self.IECdebug_callables_lock.acquire()
+        self.IECdebug_lock.acquire()
         # If no entry exist, create a new one with a fresh WeakKeyDictionary
-        self.IECdebug_callables.setdefault(
-                   IECPath, 
-                   WeakKeyDictionary())[callable]=(args, kwargs)
-        self.IECdebug_callables_lock.release()
+        IECdebug_data = self.IECdebug_datas.get(IECPath, None)
+        if IECdebug_data is None:
+            IECdebug_data  = [
+                    WeakKeyDictionary(), # Callables
+                    [],                  # Data storage [(tick, data),...]
+                    "Registered"]        # Variable status
+            self.IECdebug_datas[IECPath] = IECdebug_data
+        
+        IECdebug_data[0][callable]=(args, kwargs)
+
+        self.IECdebug_lock.release()
         # Rearm anti-rapid-fire timer
         self.DebugTimer.cancel()
         self.DebugTimer.start()
--- a/runtime/PLCObject.py	Thu Aug 28 14:51:46 2008 +0200
+++ b/runtime/PLCObject.py	Thu Aug 28 14:53:11 2008 +0200
@@ -95,6 +95,9 @@
     
             self._FreeDebugData = self.PLClibraryHandle.FreeDebugData
             self._FreeDebugData.restype = None
+            
+            self._WaitDebugData = self.PLClibraryHandle.WaitDebugData
+            self._WaitDebugData.restype = ctypes.c_int  
             return True
         except:
             print traceback.format_exc()
@@ -246,17 +249,47 @@
         self._ResetDebugVariables()
         for idx in idxs:
             self._RegisterDebugVariable(idx)
-
+    
+    TypeTranslator = {"BOOL" :       ctypes.c_uint8,
+                      "STEP" :       ctypes.c_uint8,
+                      "TRANSITION" : ctypes.c_uint8,
+                      "ACTION" :     ctypes.c_uint8,
+                      "SINT" :       ctypes.c_int8,
+                      "USINT" :      ctypes.c_uint8,
+                      "BYTE" :       ctypes.c_uint8,
+                      "STRING" :     None, #TODO
+                      "INT" :        ctypes.c_int16,
+                      "UINT" :       ctypes.c_uint16,
+                      "WORD" :       ctypes.c_uint16,
+                      "WSTRING" :    None, #TODO
+                      "DINT" :       ctypes.c_int32,
+                      "UDINT" :      ctypes.c_uint32,
+                      "DWORD" :      ctypes.c_uint32,
+                      "LINT" :       ctypes.c_int64,
+                      "ULINT" :      ctypes.c_uint64,
+                      "LWORD" :      ctypes.c_uint64,
+                      "REAL" :       ctypes.c_float,
+                      "LREAL" :      ctypes.c_double,
+                      } 
+                           
     def GetTraceVariables(self):
         """
         Return a list of variables, corresponding to the list of requiered idx
         """
-        self._WaitDebugData()
+        tick = self._WaitDebugData()
+        idx = ctypes.c_int()
+        typename = ctypes.c_char_p()
+        res = []
 
         for idx in self._Idxs:
-            buffer=self._IterDebugData()
+            buffer=self._IterDebugData(ctypes.byref(idx), ctypes.byref(typename))
+            c_type = TypeTranslator.get(s.value, None)
+            if c_type is not None:
+                res += cast(buffer, POINTER(c_type)).value
+            else:
+                res += None
         self._FreeDebugData()
-        
-        
-
-
+        return res
+        
+
+
--- a/targets/Linux/plc_Linux_main.c	Thu Aug 28 14:51:46 2008 +0200
+++ b/targets/Linux/plc_Linux_main.c	Thu Aug 28 14:53:11 2008 +0200
@@ -96,11 +96,14 @@
 
 pthread_mutex_t DebugLock = PTHREAD_MUTEX_INITIALIZER;
 
+static int __debug_tick;
+extern int __tick;
 /* from plc_debugger.c */
-void WaitDebugData()
+int WaitDebugData()
 {
     /* Wait signal from PLC thread */
     pthread_mutex_lock(&DebugLock);
+    return __debug_tick;
 }
  
 /* Called by PLC thread when debug_publish finished
@@ -108,5 +111,6 @@
 void InitiateDebugTransfer()
 {
     /* signal debugger thread to continue*/
+    __debug_tick = __tick;
     pthread_mutex_unlock(&DebugLock);
 }