Fix variable forcing. Now works with eRPC. PLCObject API changed.
authorEdouard Tisserant <edouard.tisserant@gmail.com>
Mon, 22 Jan 2024 21:30:23 +0100
changeset 3887 2df45e4bd500
parent 3886 2adfa4c60bff
child 3894 25e9b557f1b8
Fix variable forcing. Now works with eRPC. PLCObject API changed.
ProjectController.py
connectors/ERPC/__init__.py
erpc_interface/__init__.py
erpc_interface/erpc_PLCObject.erpc
erpc_interface/erpc_PLCObject/__init__.py
erpc_interface/erpc_PLCObject/client.py
erpc_interface/erpc_PLCObject/common.py
erpc_interface/erpc_PLCObject/interface.py
erpc_interface/erpc_PLCObject/server.py
runtime/PLCObject.py
runtime/eRPCServer.py
runtime/typemapping.py
targets/plc_debug.c
--- a/ProjectController.py	Sat Jan 20 11:41:17 2024 +0100
+++ b/ProjectController.py	Mon Jan 22 21:30:23 2024 +0100
@@ -60,7 +60,7 @@
 from plcopen.structures import IEC_KEYWORDS
 from plcopen.types_enums import ComputeConfigurationResourceName, ITEM_CONFNODE
 import targets
-from runtime.typemapping import DebugTypesSize, UnpackDebugBuffer
+from runtime.typemapping import DebugTypesSize, UnpackDebugBuffer, ValueToIECBytes
 from runtime import PlcStatus
 from ConfigTreeNode import ConfigTreeNode, XSDSchemaErrorMessage
 from POULibrary import UserAddressedException
@@ -1615,8 +1615,10 @@
         2 : _("Debug: Too many variables forced. Max 256.\n"),
         # FORCE_BUFFER_OVERFLOW
         3 : _("Debug: Cumulated forced variables size too large. Max 1KB.\n"),
+        # FORCE_INVALID
+        3 : _("Debug: Invalid forced value.\n"),
         # DEBUG_SUSPENDED
-        4 : _("Debug: suspended.\n")
+        5 : _("Debug: suspended.\n")
     }
 
     def RegisterDebugVarToConnector(self):
@@ -1637,7 +1639,9 @@
                         IECPath, (None, None))
                     if Idx is not None:
                         if IEC_Type in DebugTypesSize:
-                            Idxs.append((Idx, IEC_Type, fvalue, IECPath))
+                            Idxs.append(
+                                (Idx, IEC_Type, IECPath, 
+                                 ValueToIECBytes(IEC_Type, fvalue)))
                         else:
                             self.logger.write_warning(
                                 _("Debug: Unsupported type to debug '%s'\n") % IEC_Type)
@@ -1649,10 +1653,8 @@
 
             if Idxs:
                 Idxs.sort()
-                IdxsT = list(zip(*Idxs))
-                self.TracedIECPath = IdxsT[3]
-                self.TracedIECTypes = IdxsT[1]
-                res = self._connector.SetTraceVariablesList(list(zip(*IdxsT[0:3])))
+                Idxs, self.TracedIECTypes, self.TracedIECPath, Fvalues, = list(zip(*Idxs))
+                res = self._connector.SetTraceVariablesList(list(zip(Idxs, Fvalues)))
                 if res is not None and res > 0:
                     self.DebugToken = res
                 else:
--- a/connectors/ERPC/__init__.py	Sat Jan 20 11:41:17 2024 +0100
+++ b/connectors/ERPC/__init__.py	Mon Jan 22 21:30:23 2024 +0100
@@ -17,7 +17,7 @@
 # eRPC service code
 from erpc_interface.erpc_PLCObject.interface import IBeremizPLCObjectService
 from erpc_interface.erpc_PLCObject.client import BeremizPLCObjectServiceClient
-from erpc_interface.erpc_PLCObject.common import trace_order, extra_file, PLCstatus_enum, IECtype_enum
+from erpc_interface.erpc_PLCObject.common import trace_order, extra_file, PLCstatus_enum
 
 import PSKManagement as PSK
 from connectors.ERPC.PSK_Adapter import SSLPSKClientTransport
@@ -67,10 +67,10 @@
     "NewPLC":
         lambda md5sum, plcObjectBlobID, extrafiles: (
             md5sum, plcObjectBlobID, [extra_file(*f) for f in extrafiles]),
-    "SetTraceVariablesList": 
+    "SetTraceVariablesList":
         lambda orders : ([
-            trace_order(idx, getattr(IECtype_enum, iectype), b"" if force is None else force) 
-            for idx, iectype, force in orders],)
+            trace_order(idx, b"" if force is None else force) 
+            for idx, force in orders],)
 }
 
 def ERPC_connector_factory(uri, confnodesroot):
--- a/erpc_interface/__init__.py	Sat Jan 20 11:41:17 2024 +0100
+++ b/erpc_interface/__init__.py	Mon Jan 22 21:30:23 2024 +0100
@@ -1,5 +1,5 @@
 #
-# Generated by erpcgen 1.11.0 on Fri Jan 19 08:26:41 2024.
+# Generated by erpcgen 1.11.0 on Mon Jan 22 16:49:00 2024.
 #
 # AUTOGENERATED - DO NOT EDIT
 #
--- a/erpc_interface/erpc_PLCObject.erpc	Sat Jan 20 11:41:17 2024 +0100
+++ b/erpc_interface/erpc_PLCObject.erpc	Mon Jan 22 21:30:23 2024 +0100
@@ -19,32 +19,6 @@
     Disconnected
 }
 
-enum IECtype_enum {
-    BOOL,
-    STEP,
-    TRANSITION,
-    ACTION,
-    SINT,
-    USINT,
-    BYTE,
-    STRING,
-    INT,
-    UINT,
-    WORD,
-    DINT,
-    UDINT,
-    DWORD,
-    LINT,
-    ULINT,
-    LWORD,
-    REAL,
-    LREAL,
-    TIME,
-    TOD,
-    DATE,
-    DT,
-}
-
 struct PLCstatus {
     PLCstatus_enum PLCstatus;
     uint32[4] logcounts;
@@ -67,7 +41,6 @@
 
 struct trace_order {
     uint32 idx;
-    IECtype_enum iectype;
     binary force;
 };
 
--- a/erpc_interface/erpc_PLCObject/__init__.py	Sat Jan 20 11:41:17 2024 +0100
+++ b/erpc_interface/erpc_PLCObject/__init__.py	Mon Jan 22 21:30:23 2024 +0100
@@ -1,5 +1,5 @@
 #
-# Generated by erpcgen 1.11.0 on Fri Jan 19 08:26:41 2024.
+# Generated by erpcgen 1.11.0 on Mon Jan 22 16:49:00 2024.
 #
 # AUTOGENERATED - DO NOT EDIT
 #
--- a/erpc_interface/erpc_PLCObject/client.py	Sat Jan 20 11:41:17 2024 +0100
+++ b/erpc_interface/erpc_PLCObject/client.py	Mon Jan 22 21:30:23 2024 +0100
@@ -1,5 +1,5 @@
 #
-# Generated by erpcgen 1.11.0 on Fri Jan 19 08:26:41 2024.
+# Generated by erpcgen 1.11.0 on Mon Jan 22 16:49:00 2024.
 #
 # AUTOGENERATED - DO NOT EDIT
 #
--- a/erpc_interface/erpc_PLCObject/common.py	Sat Jan 20 11:41:17 2024 +0100
+++ b/erpc_interface/erpc_PLCObject/common.py	Mon Jan 22 21:30:23 2024 +0100
@@ -1,5 +1,5 @@
 #
-# Generated by erpcgen 1.11.0 on Fri Jan 19 08:26:41 2024.
+# Generated by erpcgen 1.11.0 on Mon Jan 22 16:49:00 2024.
 #
 # AUTOGENERATED - DO NOT EDIT
 #
@@ -13,31 +13,6 @@
     Broken = 3
     Disconnected = 4
 
-class IECtype_enum:
-    BOOL = 0
-    STEP = 1
-    TRANSITION = 2
-    ACTION = 3
-    SINT = 4
-    USINT = 5
-    BYTE = 6
-    STRING = 7
-    INT = 8
-    UINT = 9
-    WORD = 10
-    DINT = 11
-    UDINT = 12
-    DWORD = 13
-    LINT = 14
-    ULINT = 15
-    LWORD = 16
-    REAL = 17
-    LREAL = 18
-    TIME = 19
-    TOD = 20
-    DATE = 21
-    DT = 22
-
 
 # Structures data types declarations
 class log_message(object):
@@ -210,14 +185,12 @@
         return self.__str__()
 
 class trace_order(object):
-    def __init__(self, idx=None, iectype=None, force=None):
+    def __init__(self, idx=None, force=None):
         self.idx = idx # uint32
-        self.iectype = iectype # IECtype_enum
         self.force = force # binary
 
     def _read(self, codec):
         self.idx = codec.read_uint32()
-        self.iectype = codec.read_int32()
         self.force = codec.read_binary()
         return self
 
@@ -225,16 +198,13 @@
         if self.idx is None:
             raise ValueError("idx is None")
         codec.write_uint32(self.idx)
-        if self.iectype is None:
-            raise ValueError("iectype is None")
-        codec.write_int32(self.iectype)
         if self.force is None:
             raise ValueError("force is None")
         codec.write_binary(self.force)
 
     def __str__(self):
-        return "<%s@%x idx=%s iectype=%s force=%s>" % (self.__class__.__name__, id(self), self.idx, self.iectype, self.force)
-
-    def __repr__(self):
-        return self.__str__()
-
+        return "<%s@%x idx=%s force=%s>" % (self.__class__.__name__, id(self), self.idx, self.force)
+
+    def __repr__(self):
+        return self.__str__()
+
--- a/erpc_interface/erpc_PLCObject/interface.py	Sat Jan 20 11:41:17 2024 +0100
+++ b/erpc_interface/erpc_PLCObject/interface.py	Mon Jan 22 21:30:23 2024 +0100
@@ -1,5 +1,5 @@
 #
-# Generated by erpcgen 1.11.0 on Fri Jan 19 08:26:41 2024.
+# Generated by erpcgen 1.11.0 on Mon Jan 22 16:49:00 2024.
 #
 # AUTOGENERATED - DO NOT EDIT
 #
--- a/erpc_interface/erpc_PLCObject/server.py	Sat Jan 20 11:41:17 2024 +0100
+++ b/erpc_interface/erpc_PLCObject/server.py	Mon Jan 22 21:30:23 2024 +0100
@@ -1,5 +1,5 @@
 #
-# Generated by erpcgen 1.11.0 on Fri Jan 19 08:26:41 2024.
+# Generated by erpcgen 1.11.0 on Mon Jan 22 16:49:00 2024.
 #
 # AUTOGENERATED - DO NOT EDIT
 #
--- a/runtime/PLCObject.py	Sat Jan 20 11:41:17 2024 +0100
+++ b/runtime/PLCObject.py	Mon Jan 22 21:30:23 2024 +0100
@@ -224,7 +224,7 @@
 
             self._RegisterDebugVariable = self.PLClibraryHandle.RegisterDebugVariable
             self._RegisterDebugVariable.restype = ctypes.c_int
-            self._RegisterDebugVariable.argtypes = [ctypes.c_int, ctypes.c_void_p]
+            self._RegisterDebugVariable.argtypes = [ctypes.c_int, ctypes.c_void_p, ctypes.c_uint32]
 
             self._FreeDebugData = self.PLClibraryHandle.FreeDebugData
             self._FreeDebugData.restype = None
@@ -723,13 +723,8 @@
             if self._suspendDebug(False) == 0:
                 # keep a copy of requested idx
                 self._ResetDebugVariables()
-                for idx, iectype, force in idxs:
-                    if force is not None:
-                        c_type, _unpack_func, pack_func = \
-                            TypeTranslator.get(iectype,
-                                               (None, None, None))
-                        force = ctypes.byref(pack_func(c_type, force))
-                    res = self._RegisterDebugVariable(idx, force)
+                for idx, force in idxs:
+                    res = self._RegisterDebugVariable(idx, force, 0 if force is None else len(force))
                     if res != 0:
                         self._resumeDebug()
                         self._suspendDebug(True)
@@ -739,7 +734,7 @@
                 return self.DebugToken
         else:
             self._suspendDebug(True)
-        return 4 # DEBUG_SUSPENDED
+        return 5 # DEBUG_SUSPENDED
 
     def _TracesSwap(self):
         self.LastSwapTrace = time()
--- a/runtime/eRPCServer.py	Sat Jan 20 11:41:17 2024 +0100
+++ b/runtime/eRPCServer.py	Mon Jan 22 21:30:23 2024 +0100
@@ -12,7 +12,7 @@
 import erpc
 
 # eRPC service code
-from erpc_interface.erpc_PLCObject.common import PSKID, PLCstatus, TraceVariables, trace_sample, PLCstatus_enum, log_message, IECtype_enum
+from erpc_interface.erpc_PLCObject.common import PSKID, PLCstatus, TraceVariables, trace_sample, PLCstatus_enum, log_message
 from erpc_interface.erpc_PLCObject.interface import IBeremizPLCObjectService
 from erpc_interface.erpc_PLCObject.server import BeremizPLCObjectServiceService
 
@@ -23,8 +23,6 @@
 
 CRITICAL_LOG_LEVEL = LogLevelsDict["CRITICAL"]
 
-enum_to_IECtype = dict(map(lambda t:(t[1],t[0]),getmembers(IECtype_enum, lambda x:type(x)==int)))
-
 def ReturnAsLastOutput(method, args_wrapper, *args):
     args[-1].value = method(*args_wrapper(*args[:-1]))
     return 0
@@ -60,7 +58,7 @@
         lambda md5sum, plcObjectBlobID, extrafiles: (
             md5sum, bytes(plcObjectBlobID), [(f.fname, bytes(f.blobID)) for f in extrafiles]),
     "SetTraceVariablesList": 
-        lambda orders : ([(order.idx, enum_to_IECtype[order.iectype], None if len(order.force)==0 else order.force) for order in orders],)
+        lambda orders : ([(order.idx, None if len(order.force)==0 else bytes(order.force)) for order in orders],)
 }
 
 def rpc_wrapper(method_name):
--- a/runtime/typemapping.py	Sat Jan 20 11:41:17 2024 +0100
+++ b/runtime/typemapping.py	Mon Jan 22 21:30:23 2024 +0100
@@ -101,3 +101,9 @@
     if buffoffset and buffoffset == buffsize:
         return res
     return None
+
+def ValueToIECBytes(iectype, value):
+    if value is None:
+        return None
+    c_type, _unpack_func, pack_func = TypeTranslator[iectype]
+    return bytes(pack_func(c_type, value))
--- a/targets/plc_debug.c	Sat Jan 20 11:41:17 2024 +0100
+++ b/targets/plc_debug.c	Mon Jan 22 21:30:23 2024 +0100
@@ -348,9 +348,17 @@
 #define TRACE_LIST_OVERFLOW    1
 #define FORCE_LIST_OVERFLOW    2
 #define FORCE_BUFFER_OVERFLOW  3
+#define FORCE_INVALID  4
+
+#define __ForceVariable_checksize(TYPENAME)                                             \
+    if(sizeof(TYPENAME) != force_size) {                                                \
+        error_code = FORCE_BUFFER_OVERFLOW;                                             \
+        goto error_cleanup;                                                             \
+    }
 
 #define __ForceVariable_case_t(TYPENAME)                                                \
         case TYPENAME##_ENUM :                                                          \
+            __ForceVariable_checksize(TYPENAME)                                         \
             /* add to force_list*/                                                      \
             force_list_addvar_cursor->dbgvardsc_index = idx;                            \
             ((__IEC_##TYPENAME##_t *)varp)->flags |= __IEC_FORCE_FLAG;                  \
@@ -359,6 +367,7 @@
 #define __ForceVariable_case_p(TYPENAME)                                                \
         case TYPENAME##_P_ENUM :                                                        \
         case TYPENAME##_O_ENUM :                                                        \
+            __ForceVariable_checksize(TYPENAME)                                         \
             {                                                                           \
                 char *next_cursor = force_buffer_cursor + sizeof(TYPENAME);             \
                 if(next_cursor <= force_buffer_end ){                                   \
@@ -389,7 +398,7 @@
 
 void ResetDebugVariables(void);
 
-int RegisterDebugVariable(dbgvardsc_index_t idx, void* force)
+int RegisterDebugVariable(dbgvardsc_index_t idx, void* force, size_t force_size)
 {
     int error_code = 0;
     if(idx < sizeof(dbgvardsc)/sizeof(dbgvardsc_t)){