# HG changeset patch # User Edouard Tisserant # Date 1705955423 -3600 # Node ID 2df45e4bd500c832906e9aadeba62b9a267d7638 # Parent 2adfa4c60bffd7cda8d7e8e0b1206bd751c620d6 Fix variable forcing. Now works with eRPC. PLCObject API changed. diff -r 2adfa4c60bff -r 2df45e4bd500 ProjectController.py --- 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: diff -r 2adfa4c60bff -r 2df45e4bd500 connectors/ERPC/__init__.py --- 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): diff -r 2adfa4c60bff -r 2df45e4bd500 erpc_interface/__init__.py --- 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 # diff -r 2adfa4c60bff -r 2df45e4bd500 erpc_interface/erpc_PLCObject.erpc --- 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; }; diff -r 2adfa4c60bff -r 2df45e4bd500 erpc_interface/erpc_PLCObject/__init__.py --- 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 # diff -r 2adfa4c60bff -r 2df45e4bd500 erpc_interface/erpc_PLCObject/client.py --- 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 # diff -r 2adfa4c60bff -r 2df45e4bd500 erpc_interface/erpc_PLCObject/common.py --- 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__() + diff -r 2adfa4c60bff -r 2df45e4bd500 erpc_interface/erpc_PLCObject/interface.py --- 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 # diff -r 2adfa4c60bff -r 2df45e4bd500 erpc_interface/erpc_PLCObject/server.py --- 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 # diff -r 2adfa4c60bff -r 2df45e4bd500 runtime/PLCObject.py --- 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() diff -r 2adfa4c60bff -r 2df45e4bd500 runtime/eRPCServer.py --- 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): diff -r 2adfa4c60bff -r 2df45e4bd500 runtime/typemapping.py --- 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)) diff -r 2adfa4c60bff -r 2df45e4bd500 targets/plc_debug.c --- 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)){