connectors/LPC/LPCObject.py
changeset 502 5343ae43f6d0
parent 453 923d036dfa90
child 508 73ecb803d8af
--- 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