--- 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
_local_path = os.path.split(os.path.realpath(__file__))[0]
@@ -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 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"),
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
--- 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": + return PYRO.PYRO_connector_factory( + "PYRO://127.0.0.1:"+str(pluginsroot.runtime_port), --- 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 @@
- def __init__(self, frame, logger):
+ def __init__(self, frame, logger, runtime_port): PLCControler.__init__(self)
+ self.runtime_port = runtime_port self.MandatoryParams = None
@@ -662,8 +663,8 @@
# 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):
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) Idx = self._IECPathToIdx.get(IECPath,None)
@@ -1073,7 +1077,7 @@
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(
- WeakKeyDictionary())[callable]=(args, kwargs)
- self.IECdebug_callables_lock.release()
+ IECdebug_data = self.IECdebug_datas.get(IECPath, None) + if IECdebug_data is None: + 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
--- 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 print traceback.format_exc()
@@ -246,17 +249,47 @@
self._ResetDebugVariables()
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, + "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
+ tick = self._WaitDebugData() + typename = ctypes.c_char_p() - buffer=self._IterDebugData()
+ buffer=self._IterDebugData(ctypes.byref(idx), ctypes.byref(typename)) + c_type = TypeTranslator.get(s.value, None) + res += cast(buffer, POINTER(c_type)).value
--- 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; /* from plc_debugger.c */
/* Wait signal from PLC thread */
pthread_mutex_lock(&DebugLock);
/* Called by PLC thread when debug_publish finished
@@ -108,5 +111,6 @@
void InitiateDebugTransfer()
/* signal debugger thread to continue*/
pthread_mutex_unlock(&DebugLock);