--- 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);
}