targets/typemapping.py
author Edouard Tisserant
Fri, 30 Jan 2015 10:45:11 +0100
changeset 1433 4a45f6642523
parent 1075 8078c01ae464
child 1571 486f94a8032c
permissions -rw-r--r--
Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
#Copyright (C) 2011: Edouard TISSERANT and Laurent BESSARD
#
#See COPYING file for copyrights details.
#
#This library is free software; you can redistribute it and/or
#modify it under the terms of the GNU General Public
#License as published by the Free Software Foundation; either
#version 2.1 of the License, or (at your option) any later version.
#
#This library is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
#General Public License for more details.
#
#You should have received a copy of the GNU General Public
#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 ctypes
ctypes.pythonapi.PyString_AsString.argtypes = (ctypes.c_void_p,)
ctypes.pythonapi.PyString_AsString.restype = ctypes.POINTER(ctypes.c_char)


from ctypes import *
from datetime import timedelta as td

class IEC_STRING(Structure):
    """
    Must be changed according to changes in iec_types.h
    """
    _fields_ = [("len", c_uint8),
                ("body", c_char * 126)]

class IEC_TIME(Structure):
    """
    Must be changed according to changes in iec_types.h
    """
    _fields_ = [("s", c_long), #tv_sec
                ("ns", c_long)] #tv_nsec

def _t(t, u=lambda x:x.value, p=lambda t,x:t(x)): return  (t, u, p)
def _ttime(): return (IEC_TIME,
                      lambda x:td(0, x.s, x.ns/1000),
                      lambda t,x:t(x.days * 24 * 3600 + x.seconds, x.microseconds*1000))

SameEndianessTypeTranslator = {
    "BOOL" :       _t(c_uint8,  lambda x:x.value!=0),
    "STEP" :       _t(c_uint8),
    "TRANSITION" : _t(c_uint8),
    "ACTION" :     _t(c_uint8),
    "SINT" :       _t(c_int8),
    "USINT" :      _t(c_uint8),
    "BYTE" :       _t(c_uint8),
    "STRING" :     (IEC_STRING,
                      lambda x:x.body[:x.len],
                      lambda t,x:t(len(x),x)),
    "INT" :        _t(c_int16),
    "UINT" :       _t(c_uint16),
    "WORD" :       _t(c_uint16),
    "DINT" :       _t(c_int32),
    "UDINT" :      _t(c_uint32),
    "DWORD" :      _t(c_uint32),
    "LINT" :       _t(c_int64),
    "ULINT" :      _t(c_uint64),
    "LWORD" :      _t(c_uint64),
    "REAL" :       _t(c_float),
    "LREAL" :      _t(c_double),
    "TIME" :       _ttime(),
    "TOD" :        _ttime(),
    "DATE" :       _ttime(),
    "DT" :         _ttime(),
    }

SwapedEndianessTypeTranslator = {
    #TODO
    }

TypeTranslator=SameEndianessTypeTranslator

# Construct debugger natively supported types
DebugTypesSize =  dict([(key,sizeof(t)) for key,(t,p,u) in SameEndianessTypeTranslator.iteritems() if t is not None])

def UnpackDebugBuffer(buff, indexes):
    res =  []
    buffoffset = 0
    buffsize = len(buff)
    buffptr = cast(ctypes.pythonapi.PyString_AsString(id(buff)),c_void_p).value
    for iectype in indexes:
        c_type,unpack_func, pack_func = \
            TypeTranslator.get(iectype,
                                    (None,None,None))
        if c_type is not None and buffoffset < buffsize:
            cursor = c_void_p( buffptr + buffoffset)
            value = unpack_func( cast(cursor,
                         POINTER(c_type)).contents)
            buffoffset += sizeof(c_type) if iectype != "STRING" else len(value)+1
            res.append(value)
        else:
            break
    if buffoffset and buffoffset == buffsize:
        return res
    return None



LogLevels = ["CRITICAL","WARNING","INFO","DEBUG"]
LogLevelsCount = len(LogLevels)
LogLevelsDict = dict(zip(LogLevels,range(LogLevelsCount)))
LogLevelsDefault = LogLevelsDict["DEBUG"]