--- 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
self._Idxs = []
def HandleSerialTransaction(self, transaction):
@@ -72,65 +73,101 @@
def MatchMD5(self, MD5):
status,data = self.HandleSerialTransaction(PLCIDTransaction())
return data == MD5
-
- def SetTraceVariablesList(self, idxs):
- self._Idxs = 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):
+ self._Idxs = 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
+ """
+ if idxs:
+ buff = ""
+ # keep a copy of requested idx
+ self._Idxs = idxs[:]
+ for idx,iectype,force in idxs:
+ idxstr = ctypes.string_at(
+ ctypes.pointer(
+ ctypes.c_uint32(length)),4)
+ if force !=None:
+ c_type,unpack_func, pack_func = self.TypeTranslator.get(iectype, (None,None,None))
+ forcedsizestr = chr(ctypes.sizeof(c_type))
+ forcestr = ctypes.string_at(
+ ctypes.pointer(
+ pack_func(c_type,force)),
+ forced_type_size)
+ buff += idxstr + forced_type_size_str + forcestr
+ else:
+ buff += idxstr + chr(0)
+ status,data = self.HandleSerialTransaction(
+ SET_TRACE_VARIABLETransaction(buff))
+ else:
+ self._Idxs = []
+
def GetTraceVariables(self):
"""
Return a list of variables, corresponding to the list of required idx
"""
- status,data = self.HandleSerialTransaction(GET_TRACE_VARIABLETransaction())
- if data is not None:
- # 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)
- else:
- PLCprint("Debug error !")
- break
- return self.PLCStatus, tick, res
+ if self.PLCStatus == "Started":
+ res=[]
+ tick = ctypes.c_uint32()
+ size = ctypes.c_uint32()
+ buffer = ctypes.c_void_p()
+ offset = 0
+ if self.PLClibraryLock.acquire(False) and \
+ self._GetDebugData(ctypes.byref(tick),ctypes.byref(size),ctypes.byref(buffer)) == 0 :
+ if size.value:
+ 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)
+ else:
+ if c_type is None:
+ PLCprint("Debug error - " + iectype + " not supported !")
+ if offset >= size:
+ PLCprint("Debug error - buffer too small !")
+ break
+ self._FreeDebugData()
+ self.PLClibraryLock.release()
+ if offset and offset == size.value:
+ return self.PLCStatus, tick.value, res
+ elif size.value:
+ PLCprint("Debug error - wrong buffer unpack !")
return self.PLCStatus, None, None
--- 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
import traceback
+import LPCObject
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
- try :
- # TODO: Open Serial Port
- RemotePLCObjectProxy = LPCObject(pluginsroot) # LPC_PLCObject_Proxy
- except Exception, msg:
- pluginsroot.logger.write_error(_("Couldn't connect !\n"))
- pluginsroot.logger.write_error(traceback.format_exc())
- return None
-
- 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):
- try:
- return func(*args,**kwargs)
- except Exception,e:
- #pluginsroot.logger.write_error(traceback.format_exc())
- pluginsroot.logger.write_error(str(e)+"\n")
- pluginsroot._connector = None
- return default
- return catcher_func
-
- # 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"))
- return None
-
-
- class LPCProxy:
- """
- 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)
- if member is None:
- def my_local_func(*args,**kwargs):
- return RemotePLCObjectProxy.__getattr__(attrName)(*args,**kwargs)
- member = LPCCatcher(my_local_func, None)
- self.__dict__[attrName] = member
- return member
-
- return LPCProxy()
+ return LPCObject()