# HG changeset patch # User edouard # Date 1260453447 -3600 # Node ID 5343ae43f6d0cda32c99fac1862580b952d9428f # Parent d7bf56b036a8c1dc1c052df78e2605277851822c LPC connector - one step further diff -r d7bf56b036a8 -r 5343ae43f6d0 connectors/LPC/LPCObject.py --- 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 diff -r d7bf56b036a8 -r 5343ae43f6d0 connectors/LPC/LPCProto.py --- 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()) - while True: - #time.sleep(0.5) - 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( + "\x05\x00\x00\x00"+ + "\x01\x00\x00\x00"+ + "\x04"+ + "\x01\x02\x02\x04")) + #status,res = TestConnection.HandleTransaction(GET_TRACE_VARIABLETransaction()) + #print len(res) + #print "GOT : ", map(hex, map(ord, res)) #TestConnection.HandleTransaction(STOPTransaction()) diff -r d7bf56b036a8 -r 5343ae43f6d0 connectors/LPC/__init__.py --- 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() diff -r d7bf56b036a8 -r 5343ae43f6d0 targets/LPC/plc_LPC_main.c --- 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) { - return 0; + return __DEBUG; } void LeaveDebugSection(void) @@ -48,49 +48,29 @@ } extern unsigned long __tick; +int _DebugDataAvailable = 0; /* from plc_debugger.c */ int WaitDebugData(unsigned long *tick) { *tick = __tick; - return 0; + 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(void) +void suspendDebug(int disable) { + __DEBUG = !disable; } void resumeDebug(void) { -} - -/* from plc_python.c */ -int WaitPythonCommands(void) -{ - return 0; -} - -/* Called by PLC thread on each new python command*/ -void UnBlockPythonCommands(void) -{ -} - -int TryLockPython(void) -{ - return 0; -} - -void UnLockPython(void) -{ -} - -void LockPython(void) -{ + __DEBUG = 1; } void Retain(unsigned int offset, unsigned int count, void *p) diff -r d7bf56b036a8 -r 5343ae43f6d0 targets/plc_debug.c --- 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; + if(res){ + *size = buffer_cursor - debug_buffer; + *buffer = debug_buffer; + } return res; }