Edouard@592: #!/usr/bin/env python Edouard@592: # -*- coding: utf-8 -*- andrej@1571: andrej@1667: # This file is part of Beremiz, runtime and an Integrated Development Environment for andrej@1571: # programming IEC 61131-3 automates supporting plcopen standard and CanFestival. Edouard@592: # andrej@1571: # Copyright (C) 2011: Edouard TISSERANT and Laurent BESSARD Edouard@592: # andrej@1667: # See COPYING.Runtime file for copyrights details. Edouard@592: # andrej@1667: # This library is free software; you can redistribute it and/or andrej@1667: # modify it under the terms of the GNU Lesser General Public andrej@1667: # License as published by the Free Software Foundation; either andrej@1667: # version 2.1 of the License, or (at your option) any later version. andrej@1667: andrej@1667: # This library is distributed in the hope that it will be useful, andrej@1571: # but WITHOUT ANY WARRANTY; without even the implied warranty of andrej@1667: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU andrej@1667: # Lesser General Public License for more details. andrej@1667: andrej@1667: # You should have received a copy of the GNU Lesser General Public andrej@1667: # License along with this library; if not, write to the Free Software andrej@1667: # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Edouard@592: Edouard@1433: import ctypes Edouard@1433: ctypes.pythonapi.PyString_AsString.argtypes = (ctypes.c_void_p,) Edouard@1433: ctypes.pythonapi.PyString_AsString.restype = ctypes.POINTER(ctypes.c_char) Edouard@1433: Edouard@1433: Edouard@592: from ctypes import * edouard@593: from datetime import timedelta as td Edouard@592: andrej@1736: Edouard@592: class IEC_STRING(Structure): Edouard@592: """ Edouard@592: Must be changed according to changes in iec_types.h Edouard@592: """ Edouard@592: _fields_ = [("len", c_uint8), Edouard@1433: ("body", c_char * 126)] Edouard@592: andrej@1736: Edouard@592: class IEC_TIME(Structure): Edouard@592: """ Edouard@592: Must be changed according to changes in iec_types.h Edouard@592: """ andrej@1737: _fields_ = [("s", c_long), # tv_sec andrej@1737: ("ns", c_long)] # tv_nsec Edouard@592: andrej@1736: andrej@1740: def _t(t, u=lambda x: x.value, p=lambda t, x: t(x)): return (t, u, p) andrej@1736: andrej@1736: Edouard@1433: def _ttime(): return (IEC_TIME, andrej@1740: lambda x: td(0, x.s, x.ns/1000), andrej@1740: lambda t, x: t(x.days * 24 * 3600 + x.seconds, x.microseconds*1000)) Edouard@592: andrej@1749: Edouard@592: SameEndianessTypeTranslator = { andrej@1742: "BOOL": _t(c_uint8, lambda x: x.value != 0), andrej@1739: "STEP": _t(c_uint8), andrej@1739: "TRANSITION": _t(c_uint8), andrej@1739: "ACTION": _t(c_uint8), andrej@1739: "SINT": _t(c_int8), andrej@1739: "USINT": _t(c_uint8), andrej@1739: "BYTE": _t(c_uint8), andrej@1739: "STRING": (IEC_STRING, andrej@1740: lambda x: x.body[:x.len], andrej@1740: lambda t, x: t(len(x), x)), andrej@1739: "INT": _t(c_int16), andrej@1739: "UINT": _t(c_uint16), andrej@1739: "WORD": _t(c_uint16), andrej@1739: "DINT": _t(c_int32), andrej@1739: "UDINT": _t(c_uint32), andrej@1739: "DWORD": _t(c_uint32), andrej@1739: "LINT": _t(c_int64), andrej@1739: "ULINT": _t(c_uint64), andrej@1739: "LWORD": _t(c_uint64), andrej@1739: "REAL": _t(c_float), andrej@1739: "LREAL": _t(c_double), andrej@1739: "TIME": _ttime(), andrej@1739: "TOD": _ttime(), andrej@1739: "DATE": _ttime(), andrej@1739: "DT": _ttime(), Edouard@1433: } Edouard@592: Edouard@592: SwapedEndianessTypeTranslator = { andrej@1733: # TODO Edouard@1433: } Edouard@592: andrej@1742: TypeTranslator = SameEndianessTypeTranslator Edouard@1075: Edouard@592: # Construct debugger natively supported types andrej@1758: DebugTypesSize = dict([(key, sizeof(t)) for key, (t, p, u) in SameEndianessTypeTranslator.iteritems() if t is not None]) Edouard@592: andrej@1736: Edouard@1433: def UnpackDebugBuffer(buff, indexes): andrej@1758: res = [] Edouard@1433: buffoffset = 0 Edouard@1433: buffsize = len(buff) andrej@1740: buffptr = cast(ctypes.pythonapi.PyString_AsString(id(buff)), c_void_p).value Edouard@1433: for iectype in indexes: andrej@1740: c_type, unpack_func, pack_func = \ andrej@1767: TypeTranslator.get(iectype, (None, None, None)) Edouard@1433: if c_type is not None and buffoffset < buffsize: andrej@1747: cursor = c_void_p(buffptr + buffoffset) andrej@1747: value = unpack_func(cast(cursor, andrej@1768: POINTER(c_type)).contents) Edouard@1433: buffoffset += sizeof(c_type) if iectype != "STRING" else len(value)+1 Edouard@1433: res.append(value) Edouard@1075: else: Edouard@1075: break Edouard@1433: if buffoffset and buffoffset == buffsize: Edouard@1075: return res Edouard@1075: return None Edouard@1075: Edouard@1075: andrej@1740: LogLevels = ["CRITICAL", "WARNING", "INFO", "DEBUG"] Edouard@917: LogLevelsCount = len(LogLevels) andrej@1740: LogLevelsDict = dict(zip(LogLevels, range(LogLevelsCount))) Edouard@917: LogLevelsDefault = LogLevelsDict["DEBUG"]