Edouard@0: #!/usr/bin/env python Edouard@0: # -*- coding: utf-8 -*- Edouard@0: Edouard@0: #This file is part of Beremiz, a Integrated Development Environment for Edouard@0: #programming IEC 61131-3 automates supporting plcopen standard and CanFestival. Edouard@0: # Edouard@0: #Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD Edouard@0: # Edouard@0: #See COPYING file for copyrights details. Edouard@0: # Edouard@0: #This library is free software; you can redistribute it and/or Edouard@0: #modify it under the terms of the GNU General Public Edouard@0: #License as published by the Free Software Foundation; either Edouard@0: #version 2.1 of the License, or (at your option) any later version. Edouard@0: # Edouard@0: #This library is distributed in the hope that it will be useful, Edouard@0: #but WITHOUT ANY WARRANTY; without even the implied warranty of Edouard@0: #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Edouard@0: #General Public License for more details. Edouard@0: # Edouard@0: #You should have received a copy of the GNU General Public Edouard@0: #License along with this library; if not, write to the Free Software Edouard@0: #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Edouard@0: Edouard@0: import ctypes Edouard@0: from LPCAppProto import * Edouard@0: from LPCObject import * Edouard@31: from targets.typemapping import LogLevelsCount, SameEndianessTypeTranslator as TypeTranslator Edouard@0: Edouard@0: class LPCAppObject(LPCObject): Edouard@0: def connect(self,comport): Edouard@0: self.SerialConnection = LPCAppProto(comport,#number Edouard@0: 115200, #speed Edouard@0: 2) #timeout Edouard@0: Edouard@0: def StartPLC(self, debug=False): Edouard@0: self.HandleSerialTransaction(STARTTransaction()) Edouard@0: Edouard@0: def StopPLC(self): Edouard@0: self.HandleSerialTransaction(STOPTransaction()) Edouard@0: return True Edouard@0: Edouard@0: def ResetPLC(self): Edouard@0: self.HandleSerialTransaction(RESETTransaction()) Edouard@0: return self.PLCStatus Edouard@0: Edouard@0: def GetPLCstatus(self): Drauoude@29: strcounts = self.HandleSerialTransaction(GET_LOGCOUNTSTransaction()) Edouard@31: if len(strcounts) == LogLevelsCount * 4: Edouard@31: cstrcounts = ctypes.create_string_buffer(strcounts) Edouard@31: ccounts = ctypes.cast(cstrcounts, ctypes.POINTER(ctypes.c_uint32)) Edouard@31: counts = [int(ccounts[idx]) for idx in xrange(LogLevelsCount)] Edouard@31: else : Edouard@31: counts = [0]*LogLevelsCount Edouard@31: return self.PLCStatus, counts Edouard@0: Edouard@0: def MatchMD5(self, MD5): Edouard@0: data = self.HandleSerialTransaction(GET_PLCIDTransaction()) Edouard@0: if data is not None: Edouard@0: return data[:32] == MD5[:32] Edouard@0: return False Edouard@0: Edouard@0: def SetTraceVariablesList(self, idxs): Edouard@0: """ Edouard@0: Call ctype imported function to append Edouard@0: these indexes to registred variables in PLC debugger Edouard@0: """ Edouard@0: if idxs: Edouard@0: buff = "" Edouard@0: # keep a copy of requested idx Edouard@0: self._Idxs = idxs[:] Edouard@0: for idx,iectype,force in idxs: Edouard@0: idxstr = ctypes.string_at( Edouard@0: ctypes.pointer( Edouard@0: ctypes.c_uint32(idx)),4) Edouard@0: if force !=None: Edouard@0: c_type,unpack_func, pack_func = TypeTranslator.get(iectype, (None,None,None)) Edouard@0: forced_type_size = ctypes.sizeof(c_type) Edouard@0: forced_type_size_str = chr(forced_type_size) Edouard@0: forcestr = ctypes.string_at( Edouard@0: ctypes.pointer( Edouard@0: pack_func(c_type,force)), Edouard@0: forced_type_size) Edouard@0: buff += idxstr + forced_type_size_str + forcestr Edouard@0: else: Edouard@0: buff += idxstr + chr(0) Edouard@0: else: Edouard@0: buff = "" Edouard@0: self._Idxs = [] Edouard@0: Edouard@0: self.HandleSerialTransaction(SET_TRACE_VARIABLETransaction(buff)) Edouard@0: Edouard@0: def GetTraceVariables(self): Edouard@0: """ Edouard@0: Return a list of variables, corresponding to the list of required idx Edouard@0: """ Edouard@0: offset = 0 Edouard@0: strbuf = self.HandleSerialTransaction( Edouard@0: GET_TRACE_VARIABLETransaction()) Edouard@0: if strbuf is not None and len(strbuf) > 4 and self.PLCStatus == "Started": Edouard@0: res=[] Edouard@0: size = len(strbuf) - 4 Edouard@31: ctick = ctypes.create_string_buffer(strbuf[:4]) Edouard@31: tick = ctypes.cast(ctick, ctypes.POINTER(ctypes.c_int)).contents Edouard@31: cbuff = ctypes.create_string_buffer(strbuf[4:]) Edouard@31: buff = ctypes.cast(cbuff, ctypes.c_void_p) Edouard@0: for idx, iectype, forced in self._Idxs: Edouard@0: cursor = ctypes.c_void_p(buff.value + offset) Edouard@0: c_type,unpack_func, pack_func = TypeTranslator.get(iectype, (None,None,None)) Edouard@0: if c_type is not None and offset < size: Edouard@0: res.append(unpack_func(ctypes.cast(cursor, Edouard@0: ctypes.POINTER(c_type)).contents)) Edouard@0: offset += ctypes.sizeof(c_type) Edouard@0: else: Edouard@0: #if c_type is None: Edouard@0: #PLCprint("Debug error - " + iectype + " not supported !") Edouard@0: #if offset >= size: Edouard@0: #PLCprint("Debug error - buffer too small !") Edouard@0: break Edouard@0: if offset and offset == size: Edouard@0: return self.PLCStatus, tick.value, res Edouard@0: #PLCprint("Debug error - wrong buffer unpack !") Edouard@0: return self.PLCStatus, None, [] Edouard@0: Drauoude@29: def GetLogMessage(self, level, msgid): Drauoude@29: strbuf = self.HandleSerialTransaction(GET_LOGMSGTransaction(level, msgid)) Drauoude@29: if len(strbuf) > 12: Drauoude@29: cbuf = ctypes.cast( Drauoude@29: ctypes.c_char_p(strbuf[:12]), Drauoude@29: ctypes.POINTER(ctypes.c_uint32)) Drauoude@29: return (strbuf[12:],)+tuple(int(cbuf[idx]) for idx in range(3)) Drauoude@29: return None