--- a/connectors/LPC/LPCObject.py Thu Dec 10 12:31:42 2009 +0100
+++ b/connectors/LPC/LPCObject.py Thu Dec 10 14:57:27 2009 +0100
@@ -33,6 +33,7 @@
self.pluginsroot = pluginsroot
self.PLCprint = pluginsroot.logger.write
self.SerialConnection = None
+ self.StorageConnection = None def HandleSerialTransaction(self, transaction):
@@ -72,65 +73,101 @@
status,data = self.HandleSerialTransaction(PLCIDTransaction())
- def SetTraceVariablesList(self, idxs):
- status,data = self.HandleSerialTransaction(
- SET_TRACE_VARIABLETransaction(
- ''.join(map(chr,idx))))
class IEC_STRING(ctypes.Structure):
Must be changed according to changes in iec_types.h
_fields_ = [("len", ctypes.c_uint8),
- ("body", ctypes.c_char * 127)]
+ ("body", ctypes.c_char * 126)] - TypeTranslator = {"BOOL" : (ctypes.c_uint8, lambda x:x.value!=0),
- "STEP" : (ctypes.c_uint8, lambda x:x.value),
- "TRANSITION" : (ctypes.c_uint8, lambda x:x.value),
- "ACTION" : (ctypes.c_uint8, lambda x:x.value),
- "SINT" : (ctypes.c_int8, lambda x:x.value),
- "USINT" : (ctypes.c_uint8, lambda x:x.value),
- "BYTE" : (ctypes.c_uint8, lambda x:x.value),
- "STRING" : (IEC_STRING, lambda x:x.body[:x.len]),
- "INT" : (ctypes.c_int16, lambda x:x.value),
- "UINT" : (ctypes.c_uint16, lambda x:x.value),
- "WORD" : (ctypes.c_uint16, lambda x:x.value),
- "WSTRING" : (None, None),#TODO
- "DINT" : (ctypes.c_int32, lambda x:x.value),
- "UDINT" : (ctypes.c_uint32, lambda x:x.value),
- "DWORD" : (ctypes.c_uint32, lambda x:x.value),
- "LINT" : (ctypes.c_int64, lambda x:x.value),
- "ULINT" : (ctypes.c_uint64, lambda x:x.value),
- "LWORD" : (ctypes.c_uint64, lambda x:x.value),
- "REAL" : (ctypes.c_float, lambda x:x.value),
- "LREAL" : (ctypes.c_double, lambda x:x.value),
+ TypeTranslator = {"BOOL" : (ctypes.c_uint8, lambda x:x.value!=0, lambda t,x:t(x)), + "STEP" : (ctypes.c_uint8, lambda x:x.value, lambda t,x:t(x)), + "TRANSITION" : (ctypes.c_uint8, lambda x:x.value, lambda t,x:t(x)), + "ACTION" : (ctypes.c_uint8, lambda x:x.value, lambda t,x:t(x)), + "SINT" : (ctypes.c_int8, lambda x:x.value, lambda t,x:t(x)), + "USINT" : (ctypes.c_uint8, lambda x:x.value, lambda t,x:t(x)), + "BYTE" : (ctypes.c_uint8, lambda x:x.value, lambda t,x:t(x)), + "STRING" : (IEC_STRING, lambda x:x.body[:x.len], lambda t,x:t(len(x),x)), + "INT" : (ctypes.c_int16, lambda x:x.value, lambda t,x:t(x)), + "UINT" : (ctypes.c_uint16, lambda x:x.value, lambda t,x:t(x)), + "WORD" : (ctypes.c_uint16, lambda x:x.value, lambda t,x:t(x)), + "WSTRING" : (None, None, None),#TODO + "DINT" : (ctypes.c_int32, lambda x:x.value, lambda t,x:t(x)), + "UDINT" : (ctypes.c_uint32, lambda x:x.value, lambda t,x:t(x)), + "DWORD" : (ctypes.c_uint32, lambda x:x.value, lambda t,x:t(x)), + "LINT" : (ctypes.c_int64, lambda x:x.value, lambda t,x:t(x)), + "ULINT" : (ctypes.c_uint64, lambda x:x.value, lambda t,x:t(x)), + "LWORD" : (ctypes.c_uint64, lambda x:x.value, lambda t,x:t(x)), + "REAL" : (ctypes.c_float, lambda x:x.value, lambda t,x:t(x)), + "LREAL" : (ctypes.c_double, lambda x:x.value, lambda t,x:t(x)),
+ def SetTraceVariablesList(self, idxs): + status,data = self.HandleSerialTransaction( + SET_TRACE_VARIABLETransaction( + ''.join(map(chr,idx)))) + def SetTraceVariablesList(self, idxs): + Call ctype imported function to append + these indexes to registred variables in PLC debugger + # keep a copy of requested idx + for idx,iectype,force in idxs: + idxstr = ctypes.string_at( + ctypes.c_uint32(length)),4) + c_type,unpack_func, pack_func = self.TypeTranslator.get(iectype, (None,None,None)) + forcedsizestr = chr(ctypes.sizeof(c_type)) + forcestr = ctypes.string_at( + pack_func(c_type,force)), + buff += idxstr + forced_type_size_str + forcestr + buff += idxstr + chr(0) + status,data = self.HandleSerialTransaction( + SET_TRACE_VARIABLETransaction(buff)) def GetTraceVariables(self):
Return a list of variables, corresponding to the list of required idx
- status,data = self.HandleSerialTransaction(GET_TRACE_VARIABLETransaction())
- # transform serial string to real byte string in memory
- buffer = ctypes.c_char_p(data)
- # tick is first value in buffer
- tick = ctypes.cast(buffer,ctypes.POINTER(ctypes.c_uint32)).contents
- # variable data starts just after tick
- cursorp = ctypes.addressof(buffer) = ctypes.sizeof(ctypes.c_uint32)
- endp = offset + len(data)
- for idx, iectype in self._Idxs:
- cursor = ctypes.c_void_p(cursorp)
- c_type,unpack_func = self.TypeTranslator.get(iectype, (None,None))
- if c_type is not None and cursorp < endp:
- res.append(unpack_func(ctypes.cast(cursor,
- ctypes.POINTER(c_type)).contents))
- cursorp += ctypes.sizeof(c_type)
- PLCprint("Debug error !")
- return self.PLCStatus, tick, res
+ if self.PLCStatus == "Started": + tick = ctypes.c_uint32() + size = ctypes.c_uint32() + buffer = ctypes.c_void_p() + if self.PLClibraryLock.acquire(False) and \ + self._GetDebugData(ctypes.byref(tick),ctypes.byref(size),ctypes.byref(buffer)) == 0 : + for idx, iectype, forced in self._Idxs: + cursor = ctypes.c_void_p(buffer.value + offset) + c_type,unpack_func, pack_func = self.TypeTranslator.get(iectype, (None,None,None)) + if c_type is not None and offset < size: + res.append(unpack_func(ctypes.cast(cursor, + ctypes.POINTER(c_type)).contents)) + offset += ctypes.sizeof(c_type) + PLCprint("Debug error - " + iectype + " not supported !") + PLCprint("Debug error - buffer too small !") + self.PLClibraryLock.release() + if offset and offset == size.value: + return self.PLCStatus, tick.value, res + PLCprint("Debug error - wrong buffer unpack !") return self.PLCStatus, None, None
--- a/connectors/LPC/LPCProto.py Thu Dec 10 12:31:42 2009 +0100
+++ b/connectors/LPC/LPCProto.py Thu Dec 10 14:57:27 2009 +0100
@@ -150,9 +150,12 @@
# TestConnection.HandleTransaction(SET_TRACE_VARIABLETransaction(
# "\x03\x00\x00\x00"*200))
# TestConnection.HandleTransaction(STARTTransaction())
- TestConnection.HandleTransaction(SET_TRACE_VARIABLETransaction(
- "\x01\x00\x00\x00"*200))
- #print map(hex,map(ord,TestConnection.HandleTransaction(GET_TRACE_VARIABLETransaction())))
+ TestConnection.HandleTransaction(SET_TRACE_VARIABLETransaction( + #status,res = TestConnection.HandleTransaction(GET_TRACE_VARIABLETransaction()) + #print "GOT : ", map(hex, map(ord, res)) #TestConnection.HandleTransaction(STOPTransaction())
--- a/connectors/LPC/__init__.py Thu Dec 10 12:31:42 2009 +0100
+++ b/connectors/LPC/__init__.py Thu Dec 10 14:57:27 2009 +0100
@@ -19,6 +19,7 @@
#License along with this library; if not, write to the Free Software
#Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
def LPC_connector_factory(uri, pluginsroot):
@@ -26,62 +27,6 @@
This returns the connector to LPC style PLCobject
pluginsroot.logger.write(_("Connecting to URI : %s\n")%uri)
- servicetype, location = uri.split("://")
- # Try to get the proxy object
- # TODO: Open Serial Port
- RemotePLCObjectProxy = LPCObject(pluginsroot) # LPC_PLCObject_Proxy
- pluginsroot.logger.write_error(_("Couldn't connect !\n"))
- pluginsroot.logger.write_error(traceback.format_exc())
- def LPCCatcher(func, default=None):
- A function that catch a pyserial exceptions, write error to logger
- and return defaul value when it happen
- def catcher_func(*args,**kwargs):
- return func(*args,**kwargs)
- #pluginsroot.logger.write_error(traceback.format_exc())
- pluginsroot.logger.write_error(str(e)+"\n")
- pluginsroot._connector = None
- # Check connection is effective.
- # lambda is for getattr of GetPLCstatus to happen inside catcher
- if LPCCatcher(lambda:RemotePLCObjectProxy.GetPLCstatus())() == None:
- pluginsroot.logger.write_error(_("Cannot get PLC status - connection failed.\n"))
- A Serial proxy class to handle Beremiz Pyro interface specific behavior.
- And to put LPC exception catcher in between caller and pyro proxy
- def _LPCGetTraceVariables(self):
- return self.RemotePLCObjectProxy.GetTraceVariables()
- GetTraceVariables = LPCCatcher(_LPCGetTraceVariables,("Broken",None,None))
- def _LPCGetPLCstatus(self):
- return RemotePLCObjectProxy.GetPLCstatus()
- GetPLCstatus = LPCCatcher(_LPCGetPLCstatus, "Broken")
- def __getattr__(self, attrName):
- member = self.__dict__.get(attrName, None)
- def my_local_func(*args,**kwargs):
- return RemotePLCObjectProxy.__getattr__(attrName)(*args,**kwargs)
- member = LPCCatcher(my_local_func, None)
- self.__dict__[attrName] = member
--- a/targets/LPC/plc_LPC_main.c Thu Dec 10 12:31:42 2009 +0100
+++ b/targets/LPC/plc_LPC_main.c Thu Dec 10 14:57:27 2009 +0100
@@ -34,7 +34,7 @@
int TryEnterDebugSection(void)
void LeaveDebugSection(void)
@@ -48,49 +48,29 @@
extern unsigned long __tick;
+int _DebugDataAvailable = 0; /* from plc_debugger.c */
int WaitDebugData(unsigned long *tick)
+ return _DebugDataAvailable; /* Called by PLC thread when debug_publish finished
* This is supposed to unlock debugger thread in WaitDebugData*/
void InitiateDebugTransfer(void)
+ _DebugDataAvailable = 1;
+void suspendDebug(int disable)
-int WaitPythonCommands(void)
-/* Called by PLC thread on each new python command*/
-void UnBlockPythonCommands(void)
void Retain(unsigned int offset, unsigned int count, void *p)
--- a/targets/plc_debug.c Thu Dec 10 12:31:42 2009 +0100
+++ b/targets/plc_debug.c Thu Dec 10 14:57:27 2009 +0100
@@ -279,8 +279,10 @@
/* Wait until debug data ready and return pointer to it */
int GetDebugData(unsigned long *tick, unsigned long *size, void **buffer){
int res = WaitDebugData(tick);
- *size = buffer_cursor - debug_buffer;
- *buffer = debug_buffer;
+ *size = buffer_cursor - debug_buffer; + *buffer = debug_buffer;