runtime/PLCObject.py
author Edouard Tisserant
Fri, 20 Jun 2014 21:36:23 +0200
changeset 1420 71b1545d746f
parent 1288 adc79fc44079
child 1433 4a45f6642523
permissions -rwxr-xr-x
Enable overloading of task triggerring source cell editor (SINGLE) in resource editor. PLCGenerator now generates MULTI keywork instead of SINGLE when task's activation is surroundes with square brackets
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
     1
#!/usr/bin/env python
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
     2
# -*- coding: utf-8 -*-
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
     3
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
     4
#This file is part of Beremiz, a Integrated Development Environment for
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
     5
#programming IEC 61131-3 automates supporting plcopen standard and CanFestival. 
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
     6
#
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
     7
#Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
     8
#
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
     9
#See COPYING file for copyrights details.
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    10
#
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    11
#This library is free software; you can redistribute it and/or
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    12
#modify it under the terms of the GNU General Public
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    13
#License as published by the Free Software Foundation; either
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    14
#version 2.1 of the License, or (at your option) any later version.
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    15
#
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    16
#This library is distributed in the hope that it will be useful,
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    17
#but WITHOUT ANY WARRANTY; without even the implied warranty of
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    18
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    19
#General Public License for more details.
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    20
#
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    21
#You should have received a copy of the GNU General Public
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    22
#License along with this library; if not, write to the Free Software
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    23
#Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    24
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    25
import Pyro.core as pyro
690
ef60d7e188e6 Added a semaphore when starting runtime's python thread to make sure startPLC doesn't return before PLC is really initialized.
Edouard Tisserant
parents: 614
diff changeset
    26
from threading import Timer, Thread, Lock, Semaphore
301
87c925eaaa3a Added support for wxglade GUIs.
etisserant
parents: 299
diff changeset
    27
import ctypes, os, commands, types, sys
1075
8078c01ae464 Now Debug Buffer Unpacking is a separate function, declared in typemapping.py
Edouard Tisserant
parents: 1074
diff changeset
    28
from targets.typemapping import LogLevelsDefault, LogLevelsCount, TypeTranslator, UnpackDebugBuffer
917
401e44bae7c0 Now logging have 4 levels
Edouard Tisserant
parents: 914
diff changeset
    29
301
87c925eaaa3a Added support for wxglade GUIs.
etisserant
parents: 299
diff changeset
    30
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    31
if os.name in ("nt", "ce"):
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    32
    from _ctypes import LoadLibrary as dlopen
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    33
    from _ctypes import FreeLibrary as dlclose
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    34
elif os.name == "posix":
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    35
    from _ctypes import dlopen, dlclose
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    36
344
25b7b7f854bc Wait the debug thread has terminated before freeing PLC to avoid random segmentation fault.
greg
parents: 339
diff changeset
    37
import traceback
699
6ff64cadb1ff Adding support for executing python scripts on remote runtime
laurent
parents: 690
diff changeset
    38
def get_last_traceback(tb):
6ff64cadb1ff Adding support for executing python scripts on remote runtime
laurent
parents: 690
diff changeset
    39
    while tb.tb_next:
6ff64cadb1ff Adding support for executing python scripts on remote runtime
laurent
parents: 690
diff changeset
    40
        tb = tb.tb_next
6ff64cadb1ff Adding support for executing python scripts on remote runtime
laurent
parents: 690
diff changeset
    41
    return tb
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    42
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    43
lib_ext ={
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    44
     "linux2":".so",
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    45
     "win32":".dll",
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    46
     }.get(sys.platform, "")
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    47
291
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
    48
def PLCprint(message):
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
    49
    sys.stdout.write("PLCobject : "+message+"\n")
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
    50
    sys.stdout.flush()
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
    51
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    52
class PLCObject(pyro.ObjBase):
235
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
    53
    _Idxs = []
368
86ecd8374dae Adding support for twisted website HMI
laurent
parents: 366
diff changeset
    54
    def __init__(self, workingdir, daemon, argv, statuschange, evaluator, website):
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    55
        pyro.ObjBase.__init__(self)
301
87c925eaaa3a Added support for wxglade GUIs.
etisserant
parents: 299
diff changeset
    56
        self.evaluator = evaluator
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    57
        self.argv = [workingdir] + argv # force argv[0] to be "path" to exec...
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    58
        self.workingdir = workingdir
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    59
        self.PLCStatus = "Stopped"
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    60
        self.PLClibraryHandle = None
352
81777d4e379c fixed bug : Lock _FreePLC until _stopPLC finish
greg
parents: 350
diff changeset
    61
        self.PLClibraryLock = Lock()
366
cd90e4c10261 Move python evaluator to create a python plugin containing any related python module
laurent
parents: 365
diff changeset
    62
        self.DummyIteratorLock = None
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    63
        # Creates fake C funcs proxies
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    64
        self._FreePLC()
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    65
        self.daemon = daemon
269
d29c5f71574f add a TaskBarIcon to configure beremiz_service and display plc states (started, stopped)
greg
parents: 239
diff changeset
    66
        self.statuschange = statuschange
301
87c925eaaa3a Added support for wxglade GUIs.
etisserant
parents: 299
diff changeset
    67
        self.hmi_frame = None
368
86ecd8374dae Adding support for twisted website HMI
laurent
parents: 366
diff changeset
    68
        self.website = website
914
94436558f0ce More stable logging. Added small one-entry log for loading errors. Test now include python side concurrent logging
Edouard Tisserant
parents: 911
diff changeset
    69
        self._loading_error = None
1014
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
    70
        self.python_runtime_vars = None
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    71
        
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    72
        # Get the last transfered PLC if connector must be restart
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    73
        try:
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    74
            self.CurrentPLCFilename=open(
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    75
                             self._GetMD5FileName(),
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    76
                             "r").read().strip() + lib_ext
1121
d3838e8f1b90 Fixed Beremiz_service not closing on Windows
Laurent Bessard
parents: 1093
diff changeset
    77
            self.LoadPLC()
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    78
        except Exception, e:
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    79
            self.PLCStatus = "Empty"
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    80
            self.CurrentPLCFilename=None
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    81
286
a2a8a52b0d4f Minor changes to get better cleanup of debug and python_eval threads, accross multiple debug sessions and PLC runs.
etisserant
parents: 283
diff changeset
    82
    def StatusChange(self):
a2a8a52b0d4f Minor changes to get better cleanup of debug and python_eval threads, accross multiple debug sessions and PLC runs.
etisserant
parents: 283
diff changeset
    83
        if self.statuschange is not None:
a2a8a52b0d4f Minor changes to get better cleanup of debug and python_eval threads, accross multiple debug sessions and PLC runs.
etisserant
parents: 283
diff changeset
    84
            self.statuschange(self.PLCStatus)
a2a8a52b0d4f Minor changes to get better cleanup of debug and python_eval threads, accross multiple debug sessions and PLC runs.
etisserant
parents: 283
diff changeset
    85
917
401e44bae7c0 Now logging have 4 levels
Edouard Tisserant
parents: 914
diff changeset
    86
    def LogMessage(self, *args):
401e44bae7c0 Now logging have 4 levels
Edouard Tisserant
parents: 914
diff changeset
    87
        if len(args) == 2:
401e44bae7c0 Now logging have 4 levels
Edouard Tisserant
parents: 914
diff changeset
    88
            level, msg = args
401e44bae7c0 Now logging have 4 levels
Edouard Tisserant
parents: 914
diff changeset
    89
        else:
401e44bae7c0 Now logging have 4 levels
Edouard Tisserant
parents: 914
diff changeset
    90
            level = LogLevelsDefault
401e44bae7c0 Now logging have 4 levels
Edouard Tisserant
parents: 914
diff changeset
    91
            msg, = args
401e44bae7c0 Now logging have 4 levels
Edouard Tisserant
parents: 914
diff changeset
    92
        return self._LogMessage(level, msg, len(msg))
401e44bae7c0 Now logging have 4 levels
Edouard Tisserant
parents: 914
diff changeset
    93
1093
b5f78cff4459 Added support for resetting log messages
Laurent Bessard
parents: 1075
diff changeset
    94
    def ResetLogCount(self):
b5f78cff4459 Added support for resetting log messages
Laurent Bessard
parents: 1075
diff changeset
    95
        if self._ResetLogCount is not None:
b5f78cff4459 Added support for resetting log messages
Laurent Bessard
parents: 1075
diff changeset
    96
            self._ResetLogCount()
917
401e44bae7c0 Now logging have 4 levels
Edouard Tisserant
parents: 914
diff changeset
    97
401e44bae7c0 Now logging have 4 levels
Edouard Tisserant
parents: 914
diff changeset
    98
    def GetLogCount(self, level):
911
ffa24427396a Log redirected to console, dump of all available log to console when connecting to PLC
Edouard Tisserant
parents: 906
diff changeset
    99
        if self._GetLogCount is not None :
917
401e44bae7c0 Now logging have 4 levels
Edouard Tisserant
parents: 914
diff changeset
   100
            return int(self._GetLogCount(level))
401e44bae7c0 Now logging have 4 levels
Edouard Tisserant
parents: 914
diff changeset
   101
        elif self._loading_error is not None and level==0:
1093
b5f78cff4459 Added support for resetting log messages
Laurent Bessard
parents: 1075
diff changeset
   102
            return 1
914
94436558f0ce More stable logging. Added small one-entry log for loading errors. Test now include python side concurrent logging
Edouard Tisserant
parents: 911
diff changeset
   103
917
401e44bae7c0 Now logging have 4 levels
Edouard Tisserant
parents: 914
diff changeset
   104
    def GetLogMessage(self, level, msgid):
921
a8db48ec2c31 Added log messages time-stamping
Edouard Tisserant
parents: 917
diff changeset
   105
        tick = ctypes.c_uint32()
a8db48ec2c31 Added log messages time-stamping
Edouard Tisserant
parents: 917
diff changeset
   106
        tv_sec = ctypes.c_uint32()
a8db48ec2c31 Added log messages time-stamping
Edouard Tisserant
parents: 917
diff changeset
   107
        tv_nsec = ctypes.c_uint32()
914
94436558f0ce More stable logging. Added small one-entry log for loading errors. Test now include python side concurrent logging
Edouard Tisserant
parents: 911
diff changeset
   108
        if self._GetLogMessage is not None:
94436558f0ce More stable logging. Added small one-entry log for loading errors. Test now include python side concurrent logging
Edouard Tisserant
parents: 911
diff changeset
   109
            maxsz = len(self._log_read_buffer)-1
921
a8db48ec2c31 Added log messages time-stamping
Edouard Tisserant
parents: 917
diff changeset
   110
            sz = self._GetLogMessage(level, msgid, 
a8db48ec2c31 Added log messages time-stamping
Edouard Tisserant
parents: 917
diff changeset
   111
                self._log_read_buffer, maxsz,
a8db48ec2c31 Added log messages time-stamping
Edouard Tisserant
parents: 917
diff changeset
   112
                ctypes.byref(tick),
a8db48ec2c31 Added log messages time-stamping
Edouard Tisserant
parents: 917
diff changeset
   113
                ctypes.byref(tv_sec),
a8db48ec2c31 Added log messages time-stamping
Edouard Tisserant
parents: 917
diff changeset
   114
                ctypes.byref(tv_nsec))
914
94436558f0ce More stable logging. Added small one-entry log for loading errors. Test now include python side concurrent logging
Edouard Tisserant
parents: 911
diff changeset
   115
            if sz and sz <= maxsz:
94436558f0ce More stable logging. Added small one-entry log for loading errors. Test now include python side concurrent logging
Edouard Tisserant
parents: 911
diff changeset
   116
                self._log_read_buffer[sz] = '\x00'
921
a8db48ec2c31 Added log messages time-stamping
Edouard Tisserant
parents: 917
diff changeset
   117
                return self._log_read_buffer.value,tick.value,tv_sec.value,tv_nsec.value
917
401e44bae7c0 Now logging have 4 levels
Edouard Tisserant
parents: 914
diff changeset
   118
        elif self._loading_error is not None and level==0:
921
a8db48ec2c31 Added log messages time-stamping
Edouard Tisserant
parents: 917
diff changeset
   119
            return self._loading_error,0,0,0
914
94436558f0ce More stable logging. Added small one-entry log for loading errors. Test now include python side concurrent logging
Edouard Tisserant
parents: 911
diff changeset
   120
        return None
911
ffa24427396a Log redirected to console, dump of all available log to console when connecting to PLC
Edouard Tisserant
parents: 906
diff changeset
   121
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   122
    def _GetMD5FileName(self):
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   123
        return os.path.join(self.workingdir, "lasttransferedPLC.md5")
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   124
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   125
    def _GetLibFileName(self):
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   126
        return os.path.join(self.workingdir,self.CurrentPLCFilename)
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   127
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   128
1027
4e44c2c3e081 Fixed bug when starting Beremiz_runtime.py non empty (-a)
Edouard Tisserant
parents: 1014
diff changeset
   129
    def LoadPLC(self):
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   130
        """
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   131
        Load PLC library
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   132
        Declare all functions, arguments and return values
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   133
        """
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   134
        try:
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   135
            self._PLClibraryHandle = dlopen(self._GetLibFileName())
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   136
            self.PLClibraryHandle = ctypes.CDLL(self.CurrentPLCFilename, handle=self._PLClibraryHandle)
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   137
    
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   138
            self._startPLC = self.PLClibraryHandle.startPLC
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   139
            self._startPLC.restype = ctypes.c_int
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   140
            self._startPLC.argtypes = [ctypes.c_int, ctypes.POINTER(ctypes.c_char_p)]
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   141
            
455
e050ef5bd285 Refactoring in PLCobject, for PLC that do not use python plugin
ed
parents: 450
diff changeset
   142
            self._stopPLC_real = self.PLClibraryHandle.stopPLC
e050ef5bd285 Refactoring in PLCobject, for PLC that do not use python plugin
ed
parents: 450
diff changeset
   143
            self._stopPLC_real.restype = None
366
cd90e4c10261 Move python evaluator to create a python plugin containing any related python module
laurent
parents: 365
diff changeset
   144
            
cd90e4c10261 Move python evaluator to create a python plugin containing any related python module
laurent
parents: 365
diff changeset
   145
            self._PythonIterator = getattr(self.PLClibraryHandle, "PythonIterator", None)
cd90e4c10261 Move python evaluator to create a python plugin containing any related python module
laurent
parents: 365
diff changeset
   146
            if self._PythonIterator is not None:
cd90e4c10261 Move python evaluator to create a python plugin containing any related python module
laurent
parents: 365
diff changeset
   147
                self._PythonIterator.restype = ctypes.c_char_p
851
666f5bdad301 Added FBID variable to PY_EVAL evaluation context. FBID does identify uniquely py_eval block instance triggering execution
Edouard Tisserant
parents: 798
diff changeset
   148
                self._PythonIterator.argtypes = [ctypes.c_char_p, ctypes.POINTER(ctypes.c_void_p)]
366
cd90e4c10261 Move python evaluator to create a python plugin containing any related python module
laurent
parents: 365
diff changeset
   149
                
483
bc26c42d2eec fixed greg's crap in win32, enhanced debug stability, implemented preliminary retain
edouard
parents: 479
diff changeset
   150
                self._stopPLC = self._stopPLC_real
366
cd90e4c10261 Move python evaluator to create a python plugin containing any related python module
laurent
parents: 365
diff changeset
   151
            else:
717
1c23952dbde1 refactoring
Edouard Tisserant
parents: 699
diff changeset
   152
                # If python confnode is not enabled, we reuse _PythonIterator
455
e050ef5bd285 Refactoring in PLCobject, for PLC that do not use python plugin
ed
parents: 450
diff changeset
   153
                # as a call that block pythonthread until StopPLC 
e050ef5bd285 Refactoring in PLCobject, for PLC that do not use python plugin
ed
parents: 450
diff changeset
   154
                self.PythonIteratorLock = Lock()
e050ef5bd285 Refactoring in PLCobject, for PLC that do not use python plugin
ed
parents: 450
diff changeset
   155
                self.PythonIteratorLock.acquire()
868
7e5da4962bea Fix bug of PythonIterator signature in PLCObject when not using PythonLibrary
Edouard Tisserant
parents: 867
diff changeset
   156
                def PythonIterator(res, blkid):
455
e050ef5bd285 Refactoring in PLCobject, for PLC that do not use python plugin
ed
parents: 450
diff changeset
   157
                    self.PythonIteratorLock.acquire()
e050ef5bd285 Refactoring in PLCobject, for PLC that do not use python plugin
ed
parents: 450
diff changeset
   158
                    self.PythonIteratorLock.release()
366
cd90e4c10261 Move python evaluator to create a python plugin containing any related python module
laurent
parents: 365
diff changeset
   159
                    return None
455
e050ef5bd285 Refactoring in PLCobject, for PLC that do not use python plugin
ed
parents: 450
diff changeset
   160
                self._PythonIterator = PythonIterator
366
cd90e4c10261 Move python evaluator to create a python plugin containing any related python module
laurent
parents: 365
diff changeset
   161
                
483
bc26c42d2eec fixed greg's crap in win32, enhanced debug stability, implemented preliminary retain
edouard
parents: 479
diff changeset
   162
                def __StopPLC():
455
e050ef5bd285 Refactoring in PLCobject, for PLC that do not use python plugin
ed
parents: 450
diff changeset
   163
                    self._stopPLC_real()
e050ef5bd285 Refactoring in PLCobject, for PLC that do not use python plugin
ed
parents: 450
diff changeset
   164
                    self.PythonIteratorLock.release()
483
bc26c42d2eec fixed greg's crap in win32, enhanced debug stability, implemented preliminary retain
edouard
parents: 479
diff changeset
   165
                self._stopPLC = __StopPLC
bc26c42d2eec fixed greg's crap in win32, enhanced debug stability, implemented preliminary retain
edouard
parents: 479
diff changeset
   166
            
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   167
    
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   168
            self._ResetDebugVariables = self.PLClibraryHandle.ResetDebugVariables
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   169
            self._ResetDebugVariables.restype = None
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   170
    
235
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   171
            self._RegisterDebugVariable = self.PLClibraryHandle.RegisterDebugVariable
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   172
            self._RegisterDebugVariable.restype = None
477
f66a092b6e74 Arbitrary variable forcing
Edouard TISSERANT <edouard.tisserant@gmail.com>
parents: 467
diff changeset
   173
            self._RegisterDebugVariable.argtypes = [ctypes.c_int, ctypes.c_void_p]
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   174
    
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   175
            self._FreeDebugData = self.PLClibraryHandle.FreeDebugData
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   176
            self._FreeDebugData.restype = None
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   177
            
450
18583d13f0fa Preliminary accessor support for debug
Edouard TISSERANT <edouard.tisserant@gmail.com>
parents: 446
diff changeset
   178
            self._GetDebugData = self.PLClibraryHandle.GetDebugData
18583d13f0fa Preliminary accessor support for debug
Edouard TISSERANT <edouard.tisserant@gmail.com>
parents: 446
diff changeset
   179
            self._GetDebugData.restype = ctypes.c_int  
18583d13f0fa Preliminary accessor support for debug
Edouard TISSERANT <edouard.tisserant@gmail.com>
parents: 446
diff changeset
   180
            self._GetDebugData.argtypes = [ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.c_void_p)]
235
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   181
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   182
            self._suspendDebug = self.PLClibraryHandle.suspendDebug
614
eed1dcf311a1 added return type to suspendDebug
Edouard Tisserant
parents: 593
diff changeset
   183
            self._suspendDebug.restype = ctypes.c_int
462
274e83a5534e Now debug is not a button anymore
Edouard TISSERANT <edouard.tisserant@gmail.com>
parents: 461
diff changeset
   184
            self._suspendDebug.argtypes = [ctypes.c_int]
235
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   185
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   186
            self._resumeDebug = self.PLClibraryHandle.resumeDebug
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   187
            self._resumeDebug.restype = None
906
de452d65865c Python runtime now dlopens shared library immediatly after transfer, and release it only immediately before reloading a new one. This is probably going to reveal lot of dirty cleanups during start/stop cycles.
Edouard Tisserant
parents: 868
diff changeset
   188
1093
b5f78cff4459 Added support for resetting log messages
Laurent Bessard
parents: 1075
diff changeset
   189
            self._ResetLogCount = self.PLClibraryHandle.ResetLogCount
b5f78cff4459 Added support for resetting log messages
Laurent Bessard
parents: 1075
diff changeset
   190
            self._ResetLogCount.restype = None
b5f78cff4459 Added support for resetting log messages
Laurent Bessard
parents: 1075
diff changeset
   191
906
de452d65865c Python runtime now dlopens shared library immediatly after transfer, and release it only immediately before reloading a new one. This is probably going to reveal lot of dirty cleanups during start/stop cycles.
Edouard Tisserant
parents: 868
diff changeset
   192
            self._GetLogCount = self.PLClibraryHandle.GetLogCount
de452d65865c Python runtime now dlopens shared library immediatly after transfer, and release it only immediately before reloading a new one. This is probably going to reveal lot of dirty cleanups during start/stop cycles.
Edouard Tisserant
parents: 868
diff changeset
   193
            self._GetLogCount.restype = ctypes.c_uint32
917
401e44bae7c0 Now logging have 4 levels
Edouard Tisserant
parents: 914
diff changeset
   194
            self._GetLogCount.argtypes = [ctypes.c_uint8]
906
de452d65865c Python runtime now dlopens shared library immediatly after transfer, and release it only immediately before reloading a new one. This is probably going to reveal lot of dirty cleanups during start/stop cycles.
Edouard Tisserant
parents: 868
diff changeset
   195
911
ffa24427396a Log redirected to console, dump of all available log to console when connecting to PLC
Edouard Tisserant
parents: 906
diff changeset
   196
            self._LogMessage = self.PLClibraryHandle.LogMessage
ffa24427396a Log redirected to console, dump of all available log to console when connecting to PLC
Edouard Tisserant
parents: 906
diff changeset
   197
            self._LogMessage.restype = ctypes.c_int
971
c4550f76ae05 reverted PLCObject.py. ctypes.POINTER(ctypes.c_uint8) != string
Edouard Tisserant
parents: 969
diff changeset
   198
            self._LogMessage.argtypes = [ctypes.c_uint8, ctypes.c_char_p, ctypes.c_uint32]
1093
b5f78cff4459 Added support for resetting log messages
Laurent Bessard
parents: 1075
diff changeset
   199
911
ffa24427396a Log redirected to console, dump of all available log to console when connecting to PLC
Edouard Tisserant
parents: 906
diff changeset
   200
            self._log_read_buffer = ctypes.create_string_buffer(1<<14) #16K
ffa24427396a Log redirected to console, dump of all available log to console when connecting to PLC
Edouard Tisserant
parents: 906
diff changeset
   201
            self._GetLogMessage = self.PLClibraryHandle.GetLogMessage
ffa24427396a Log redirected to console, dump of all available log to console when connecting to PLC
Edouard Tisserant
parents: 906
diff changeset
   202
            self._GetLogMessage.restype = ctypes.c_uint32
921
a8db48ec2c31 Added log messages time-stamping
Edouard Tisserant
parents: 917
diff changeset
   203
            self._GetLogMessage.argtypes = [ctypes.c_uint8, ctypes.c_uint32, ctypes.c_char_p, ctypes.c_uint32, ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.c_uint32)]
911
ffa24427396a Log redirected to console, dump of all available log to console when connecting to PLC
Edouard Tisserant
parents: 906
diff changeset
   204
914
94436558f0ce More stable logging. Added small one-entry log for loading errors. Test now include python side concurrent logging
Edouard Tisserant
parents: 911
diff changeset
   205
            self._loading_error = None
1035
0f905e027d18 Better mdns resolution failure signaling, added fixed bug whith runtime autostart
Edouard Tisserant
parents: 1027
diff changeset
   206
0f905e027d18 Better mdns resolution failure signaling, added fixed bug whith runtime autostart
Edouard Tisserant
parents: 1027
diff changeset
   207
            self.PythonRuntimeInit()
0f905e027d18 Better mdns resolution failure signaling, added fixed bug whith runtime autostart
Edouard Tisserant
parents: 1027
diff changeset
   208
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   209
            return True
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   210
        except:
914
94436558f0ce More stable logging. Added small one-entry log for loading errors. Test now include python side concurrent logging
Edouard Tisserant
parents: 911
diff changeset
   211
            self._loading_error = traceback.format_exc()
94436558f0ce More stable logging. Added small one-entry log for loading errors. Test now include python side concurrent logging
Edouard Tisserant
parents: 911
diff changeset
   212
            PLCprint(self._loading_error)
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   213
            return False
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   214
1045
a220a27defe5 Runtime now unloads and cleanup PLC before exit (created threads was preventing exit)
Edouard Tisserant
parents: 1035
diff changeset
   215
    def UnLoadPLC(self):
a220a27defe5 Runtime now unloads and cleanup PLC before exit (created threads was preventing exit)
Edouard Tisserant
parents: 1035
diff changeset
   216
        self.PythonRuntimeCleanup()
a220a27defe5 Runtime now unloads and cleanup PLC before exit (created threads was preventing exit)
Edouard Tisserant
parents: 1035
diff changeset
   217
        self._FreePLC()
a220a27defe5 Runtime now unloads and cleanup PLC before exit (created threads was preventing exit)
Edouard Tisserant
parents: 1035
diff changeset
   218
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   219
    def _FreePLC(self):
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   220
        """
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   221
        Unload PLC library.
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   222
        This is also called by __init__ to create dummy C func proxies
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   223
        """
352
81777d4e379c fixed bug : Lock _FreePLC until _stopPLC finish
greg
parents: 350
diff changeset
   224
        self.PLClibraryLock.acquire()
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   225
        # Forget all refs to library
1027
4e44c2c3e081 Fixed bug when starting Beremiz_runtime.py non empty (-a)
Edouard Tisserant
parents: 1014
diff changeset
   226
        self._startPLC = lambda x,y:None
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   227
        self._stopPLC = lambda:None
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   228
        self._ResetDebugVariables = lambda:None
479
c28f40b27798 Bug on RegisterDebugVariable when no PLC running fixed
laurent
parents: 477
diff changeset
   229
        self._RegisterDebugVariable = lambda x, y:None
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   230
        self._IterDebugData = lambda x,y:None
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   231
        self._FreeDebugData = lambda:None
450
18583d13f0fa Preliminary accessor support for debug
Edouard TISSERANT <edouard.tisserant@gmail.com>
parents: 446
diff changeset
   232
        self._GetDebugData = lambda:-1
614
eed1dcf311a1 added return type to suspendDebug
Edouard Tisserant
parents: 593
diff changeset
   233
        self._suspendDebug = lambda x:-1
235
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   234
        self._resumeDebug = lambda:None
280
f2ef79f3dba0 Added native (not a plugin) asynchronous python eval function block - Beta. Code cleanup in C code templates.
etisserant
parents: 269
diff changeset
   235
        self._PythonIterator = lambda:""
911
ffa24427396a Log redirected to console, dump of all available log to console when connecting to PLC
Edouard Tisserant
parents: 906
diff changeset
   236
        self._GetLogCount = None 
917
401e44bae7c0 Now logging have 4 levels
Edouard Tisserant
parents: 914
diff changeset
   237
        self._LogMessage = lambda l,m,s:PLCprint("OFF LOG :"+m)
914
94436558f0ce More stable logging. Added small one-entry log for loading errors. Test now include python side concurrent logging
Edouard Tisserant
parents: 911
diff changeset
   238
        self._GetLogMessage = None
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   239
        self.PLClibraryHandle = None
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   240
        # Unload library explicitely
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   241
        if getattr(self,"_PLClibraryHandle",None) is not None:
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   242
            dlclose(self._PLClibraryHandle)
393
af20e07e53c5 Remove dirtylibs test while freeing plc libs in PLCObject.py
laurent
parents: 368
diff changeset
   243
            self._PLClibraryHandle = None
af20e07e53c5 Remove dirtylibs test while freeing plc libs in PLCObject.py
laurent
parents: 368
diff changeset
   244
        
352
81777d4e379c fixed bug : Lock _FreePLC until _stopPLC finish
greg
parents: 350
diff changeset
   245
        self.PLClibraryLock.release()
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   246
        return False
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   247
1014
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   248
    def PythonRuntimeCall(self, methodname):
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   249
        """ 
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   250
        Calls init, start, stop or cleanup method provided by 
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   251
        runtime python files, loaded when new PLC uploaded
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   252
        """
1051
847d68c3e7ff Extended exception info from evaluator. Problems in python runtime init/cleanup code now more readable
Edouard Tisserant
parents: 1045
diff changeset
   253
        for method in self.python_runtime_vars.get("_runtime_%s"%methodname, []):
847d68c3e7ff Extended exception info from evaluator. Problems in python runtime init/cleanup code now more readable
Edouard Tisserant
parents: 1045
diff changeset
   254
            res,exp = self.evaluator(method)
847d68c3e7ff Extended exception info from evaluator. Problems in python runtime init/cleanup code now more readable
Edouard Tisserant
parents: 1045
diff changeset
   255
            if exp is not None: 
1052
fa7c5034c1d2 Better display of Python exceptions from Py_Eval
Edouard Tisserant
parents: 1051
diff changeset
   256
                self.LogMessage(0,'\n'.join(traceback.format_exception(*exp)))
1014
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   257
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   258
    def PythonRuntimeInit(self):
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   259
        MethodNames = ["init", "start", "stop", "cleanup"]
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   260
        self.python_runtime_vars = globals().copy()
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   261
        self.python_runtime_vars["WorkingDir"] = self.workingdir
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   262
        self.python_runtime_vars["website"] = self.website
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   263
        for methodname in MethodNames :
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   264
            self.python_runtime_vars["_runtime_%s"%methodname] = []
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   265
        self.python_runtime_vars["PLCObject"] = self
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   266
        self.python_runtime_vars["PLCBinary"] = self.PLClibraryHandle
1144
21475ee0e688 Added stub code and declarations for bidirectional access to PLC globals from python code (untested)
Edouard Tisserant
parents: 1132
diff changeset
   267
        class PLCSafeGlobals:
1145
203f4eff3313 Fixed PLC global var access from python. Added test in tests/python
Edouard Tisserant
parents: 1144
diff changeset
   268
            def __getattr__(_self, name):
1156
9708ed2a4ac2 Added more clear error message in case of access to non declared PLC global from python code
Edouard Tisserant
parents: 1145
diff changeset
   269
                try :
9708ed2a4ac2 Added more clear error message in case of access to non declared PLC global from python code
Edouard Tisserant
parents: 1145
diff changeset
   270
                    t = self.python_runtime_vars["_"+name+"_ctype"]
9708ed2a4ac2 Added more clear error message in case of access to non declared PLC global from python code
Edouard Tisserant
parents: 1145
diff changeset
   271
                except KeyError:
9708ed2a4ac2 Added more clear error message in case of access to non declared PLC global from python code
Edouard Tisserant
parents: 1145
diff changeset
   272
                    raise KeyError("Try to get unknown shared global variable : %s"%name)
9708ed2a4ac2 Added more clear error message in case of access to non declared PLC global from python code
Edouard Tisserant
parents: 1145
diff changeset
   273
                v = t()
1145
203f4eff3313 Fixed PLC global var access from python. Added test in tests/python
Edouard Tisserant
parents: 1144
diff changeset
   274
                r = self.python_runtime_vars["_PySafeGetPLCGlob_"+name](ctypes.byref(v))
203f4eff3313 Fixed PLC global var access from python. Added test in tests/python
Edouard Tisserant
parents: 1144
diff changeset
   275
                return self.python_runtime_vars["_"+name+"_unpack"](v)
203f4eff3313 Fixed PLC global var access from python. Added test in tests/python
Edouard Tisserant
parents: 1144
diff changeset
   276
            def __setattr__(_self, name, value):
1156
9708ed2a4ac2 Added more clear error message in case of access to non declared PLC global from python code
Edouard Tisserant
parents: 1145
diff changeset
   277
                try :
9708ed2a4ac2 Added more clear error message in case of access to non declared PLC global from python code
Edouard Tisserant
parents: 1145
diff changeset
   278
                    t = self.python_runtime_vars["_"+name+"_ctype"]
9708ed2a4ac2 Added more clear error message in case of access to non declared PLC global from python code
Edouard Tisserant
parents: 1145
diff changeset
   279
                except KeyError:
9708ed2a4ac2 Added more clear error message in case of access to non declared PLC global from python code
Edouard Tisserant
parents: 1145
diff changeset
   280
                    raise KeyError("Try to set unknown shared global variable : %s"%name)
1145
203f4eff3313 Fixed PLC global var access from python. Added test in tests/python
Edouard Tisserant
parents: 1144
diff changeset
   281
                v = self.python_runtime_vars["_"+name+"_pack"](t,value)
203f4eff3313 Fixed PLC global var access from python. Added test in tests/python
Edouard Tisserant
parents: 1144
diff changeset
   282
                self.python_runtime_vars["_PySafeSetPLCGlob_"+name](ctypes.byref(v))
1144
21475ee0e688 Added stub code and declarations for bidirectional access to PLC globals from python code (untested)
Edouard Tisserant
parents: 1132
diff changeset
   283
        self.python_runtime_vars["PLCGlobals"] = PLCSafeGlobals()
972
659198075ce4 Redirect PyEval exceptions to logging
Edouard Tisserant
parents: 971
diff changeset
   284
        try:
659198075ce4 Redirect PyEval exceptions to logging
Edouard Tisserant
parents: 971
diff changeset
   285
            for filename in os.listdir(self.workingdir):
659198075ce4 Redirect PyEval exceptions to logging
Edouard Tisserant
parents: 971
diff changeset
   286
                name, ext = os.path.splitext(filename)
659198075ce4 Redirect PyEval exceptions to logging
Edouard Tisserant
parents: 971
diff changeset
   287
                if name.upper().startswith("RUNTIME") and ext.upper() == ".PY":
1014
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   288
                    execfile(os.path.join(self.workingdir, filename), self.python_runtime_vars)
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   289
                    for methodname in MethodNames: 
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   290
                        method = self.python_runtime_vars.get("_%s_%s" % (name, methodname), None)
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   291
                        if method is not None:
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   292
                            self.python_runtime_vars["_runtime_%s"%methodname].append(method)
972
659198075ce4 Redirect PyEval exceptions to logging
Edouard Tisserant
parents: 971
diff changeset
   293
        except:
659198075ce4 Redirect PyEval exceptions to logging
Edouard Tisserant
parents: 971
diff changeset
   294
            self.LogMessage(0,traceback.format_exc())
659198075ce4 Redirect PyEval exceptions to logging
Edouard Tisserant
parents: 971
diff changeset
   295
            raise
368
86ecd8374dae Adding support for twisted website HMI
laurent
parents: 366
diff changeset
   296
            
1014
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   297
        self.PythonRuntimeCall("init")
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   298
368
86ecd8374dae Adding support for twisted website HMI
laurent
parents: 366
diff changeset
   299
        if self.website is not None:
86ecd8374dae Adding support for twisted website HMI
laurent
parents: 366
diff changeset
   300
            self.website.PLCStarted()
291
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
   301
1014
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   302
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   303
    def PythonRuntimeCleanup(self):
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   304
        if self.python_runtime_vars is not None:
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   305
            self.PythonRuntimeCall("cleanup")
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   306
368
86ecd8374dae Adding support for twisted website HMI
laurent
parents: 366
diff changeset
   307
        if self.website is not None:
86ecd8374dae Adding support for twisted website HMI
laurent
parents: 366
diff changeset
   308
            self.website.PLCStopped()
1014
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   309
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   310
        self.python_runtime_vars = None
291
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
   311
462
274e83a5534e Now debug is not a button anymore
Edouard TISSERANT <edouard.tisserant@gmail.com>
parents: 461
diff changeset
   312
    def PythonThreadProc(self):
798
0d2423f283a6 Fix bug segmentation fault while cleanup extensions
laurent
parents: 795
diff changeset
   313
        self.PLCStatus = "Started"
0d2423f283a6 Fix bug segmentation fault while cleanup extensions
laurent
parents: 795
diff changeset
   314
        self.StatusChange()
0d2423f283a6 Fix bug segmentation fault while cleanup extensions
laurent
parents: 795
diff changeset
   315
        self.StartSem.release()
1014
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   316
        self.PythonRuntimeCall("start")
851
666f5bdad301 Added FBID variable to PY_EVAL evaluation context. FBID does identify uniquely py_eval block instance triggering execution
Edouard Tisserant
parents: 798
diff changeset
   317
        res,cmd,blkid = "None","None",ctypes.c_void_p()
867
06495975e8a4 Added caching for python eval (avoid compiling when same code called, but still execute). Cleaned up some evaluator related code.
Edouard Tisserant
parents: 851
diff changeset
   318
        compile_cache={}
798
0d2423f283a6 Fix bug segmentation fault while cleanup extensions
laurent
parents: 795
diff changeset
   319
        while True:
851
666f5bdad301 Added FBID variable to PY_EVAL evaluation context. FBID does identify uniquely py_eval block instance triggering execution
Edouard Tisserant
parents: 798
diff changeset
   320
            # print "_PythonIterator(", res, ")",
666f5bdad301 Added FBID variable to PY_EVAL evaluation context. FBID does identify uniquely py_eval block instance triggering execution
Edouard Tisserant
parents: 798
diff changeset
   321
            cmd = self._PythonIterator(res,blkid)
867
06495975e8a4 Added caching for python eval (avoid compiling when same code called, but still execute). Cleaned up some evaluator related code.
Edouard Tisserant
parents: 851
diff changeset
   322
            FBID = blkid.value 
851
666f5bdad301 Added FBID variable to PY_EVAL evaluation context. FBID does identify uniquely py_eval block instance triggering execution
Edouard Tisserant
parents: 798
diff changeset
   323
            # print " -> ", cmd, blkid
798
0d2423f283a6 Fix bug segmentation fault while cleanup extensions
laurent
parents: 795
diff changeset
   324
            if cmd is None:
0d2423f283a6 Fix bug segmentation fault while cleanup extensions
laurent
parents: 795
diff changeset
   325
                break
0d2423f283a6 Fix bug segmentation fault while cleanup extensions
laurent
parents: 795
diff changeset
   326
            try :
1014
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   327
                self.python_runtime_vars["FBID"]=FBID
867
06495975e8a4 Added caching for python eval (avoid compiling when same code called, but still execute). Cleaned up some evaluator related code.
Edouard Tisserant
parents: 851
diff changeset
   328
                ccmd,AST =compile_cache.get(FBID, (None,None))
06495975e8a4 Added caching for python eval (avoid compiling when same code called, but still execute). Cleaned up some evaluator related code.
Edouard Tisserant
parents: 851
diff changeset
   329
                if ccmd is None or ccmd!=cmd:
06495975e8a4 Added caching for python eval (avoid compiling when same code called, but still execute). Cleaned up some evaluator related code.
Edouard Tisserant
parents: 851
diff changeset
   330
                    AST = compile(cmd, '<plc>', 'eval')
06495975e8a4 Added caching for python eval (avoid compiling when same code called, but still execute). Cleaned up some evaluator related code.
Edouard Tisserant
parents: 851
diff changeset
   331
                    compile_cache[FBID]=(cmd,AST)
1288
adc79fc44079 Fixed two typos in py_ext : FBID was not current but previous py_eval block FBID, and compiled AST cache was filled buy never used.
Edouard Tisserant
parents: 1156
diff changeset
   332
                result,exp = self.evaluator(eval,AST,self.python_runtime_vars)
867
06495975e8a4 Added caching for python eval (avoid compiling when same code called, but still execute). Cleaned up some evaluator related code.
Edouard Tisserant
parents: 851
diff changeset
   333
                if exp is not None: 
1052
fa7c5034c1d2 Better display of Python exceptions from Py_Eval
Edouard Tisserant
parents: 1051
diff changeset
   334
                    res = "#EXCEPTION : "+str(exp[1])
fa7c5034c1d2 Better display of Python exceptions from Py_Eval
Edouard Tisserant
parents: 1051
diff changeset
   335
                    self.LogMessage(1,('PyEval@0x%x(Code="%s") Exception "%s"')%(FBID,cmd,
fa7c5034c1d2 Better display of Python exceptions from Py_Eval
Edouard Tisserant
parents: 1051
diff changeset
   336
                        '\n'.join(traceback.format_exception(*exp))))
867
06495975e8a4 Added caching for python eval (avoid compiling when same code called, but still execute). Cleaned up some evaluator related code.
Edouard Tisserant
parents: 851
diff changeset
   337
                else:
06495975e8a4 Added caching for python eval (avoid compiling when same code called, but still execute). Cleaned up some evaluator related code.
Edouard Tisserant
parents: 851
diff changeset
   338
                    res=str(result)
1014
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   339
                self.python_runtime_vars["FBID"]=None
798
0d2423f283a6 Fix bug segmentation fault while cleanup extensions
laurent
parents: 795
diff changeset
   340
            except Exception,e:
0d2423f283a6 Fix bug segmentation fault while cleanup extensions
laurent
parents: 795
diff changeset
   341
                res = "#EXCEPTION : "+str(e)
972
659198075ce4 Redirect PyEval exceptions to logging
Edouard Tisserant
parents: 971
diff changeset
   342
                self.LogMessage(1,('PyEval@0x%x(Code="%s") Exception "%s"')%(FBID,cmd,str(e)))
798
0d2423f283a6 Fix bug segmentation fault while cleanup extensions
laurent
parents: 795
diff changeset
   343
        self.PLCStatus = "Stopped"
0d2423f283a6 Fix bug segmentation fault while cleanup extensions
laurent
parents: 795
diff changeset
   344
        self.StatusChange()
1014
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   345
        self.PythonRuntimeCall("stop")
350
a3a5561bde1d - now call load, start, free PLC from the python Thread
greg
parents: 344
diff changeset
   346
    
462
274e83a5534e Now debug is not a button anymore
Edouard TISSERANT <edouard.tisserant@gmail.com>
parents: 461
diff changeset
   347
    def StartPLC(self):
465
67d32a91d70b Fixes in debug + reconnect to running PLC
Edouard TISSERANT <edouard.tisserant@gmail.com>
parents: 462
diff changeset
   348
        if self.CurrentPLCFilename is not None and self.PLCStatus == "Stopped":
798
0d2423f283a6 Fix bug segmentation fault while cleanup extensions
laurent
parents: 795
diff changeset
   349
            c_argv = ctypes.c_char_p * len(self.argv)
0d2423f283a6 Fix bug segmentation fault while cleanup extensions
laurent
parents: 795
diff changeset
   350
            error = None
906
de452d65865c Python runtime now dlopens shared library immediatly after transfer, and release it only immediately before reloading a new one. This is probably going to reveal lot of dirty cleanups during start/stop cycles.
Edouard Tisserant
parents: 868
diff changeset
   351
            res = self._startPLC(len(self.argv),c_argv(*self.argv))
de452d65865c Python runtime now dlopens shared library immediatly after transfer, and release it only immediately before reloading a new one. This is probably going to reveal lot of dirty cleanups during start/stop cycles.
Edouard Tisserant
parents: 868
diff changeset
   352
            if res == 0:
de452d65865c Python runtime now dlopens shared library immediatly after transfer, and release it only immediately before reloading a new one. This is probably going to reveal lot of dirty cleanups during start/stop cycles.
Edouard Tisserant
parents: 868
diff changeset
   353
                self.StartSem=Semaphore(0)
de452d65865c Python runtime now dlopens shared library immediatly after transfer, and release it only immediately before reloading a new one. This is probably going to reveal lot of dirty cleanups during start/stop cycles.
Edouard Tisserant
parents: 868
diff changeset
   354
                self.PythonThread = Thread(target=self.PythonThreadProc)
de452d65865c Python runtime now dlopens shared library immediatly after transfer, and release it only immediately before reloading a new one. This is probably going to reveal lot of dirty cleanups during start/stop cycles.
Edouard Tisserant
parents: 868
diff changeset
   355
                self.PythonThread.start()
de452d65865c Python runtime now dlopens shared library immediatly after transfer, and release it only immediately before reloading a new one. This is probably going to reveal lot of dirty cleanups during start/stop cycles.
Edouard Tisserant
parents: 868
diff changeset
   356
                self.StartSem.acquire()
917
401e44bae7c0 Now logging have 4 levels
Edouard Tisserant
parents: 914
diff changeset
   357
                self.LogMessage("PLC started")
798
0d2423f283a6 Fix bug segmentation fault while cleanup extensions
laurent
parents: 795
diff changeset
   358
            else:
972
659198075ce4 Redirect PyEval exceptions to logging
Edouard Tisserant
parents: 971
diff changeset
   359
                self.LogMessage(0,_("Problem starting PLC : error %d" % res))
798
0d2423f283a6 Fix bug segmentation fault while cleanup extensions
laurent
parents: 795
diff changeset
   360
                self.PLCStatus = "Broken"
0d2423f283a6 Fix bug segmentation fault while cleanup extensions
laurent
parents: 795
diff changeset
   361
                self.StatusChange()
352
81777d4e379c fixed bug : Lock _FreePLC until _stopPLC finish
greg
parents: 350
diff changeset
   362
            
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   363
    def StopPLC(self):
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   364
        if self.PLCStatus == "Started":
917
401e44bae7c0 Now logging have 4 levels
Edouard Tisserant
parents: 914
diff changeset
   365
            self.LogMessage("PLC stopped")
352
81777d4e379c fixed bug : Lock _FreePLC until _stopPLC finish
greg
parents: 350
diff changeset
   366
            self._stopPLC()
798
0d2423f283a6 Fix bug segmentation fault while cleanup extensions
laurent
parents: 795
diff changeset
   367
            self.PythonThread.join()
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   368
            return True
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   369
        return False
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   370
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   371
    def _Reload(self):
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   372
        self.daemon.shutdown(True)
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   373
        self.daemon.sock.close()
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   374
        os.execv(sys.executable,[sys.executable]+sys.argv[:])
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   375
        # never reached
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   376
        return 0
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   377
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   378
    def ForceReload(self):
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   379
        # respawn python interpreter
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   380
        Timer(0.1,self._Reload).start()
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   381
        return True
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   382
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   383
    def GetPLCstatus(self):
917
401e44bae7c0 Now logging have 4 levels
Edouard Tisserant
parents: 914
diff changeset
   384
        return self.PLCStatus, map(self.GetLogCount,xrange(LogLevelsCount))
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   385
    
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   386
    def NewPLC(self, md5sum, data, extrafiles):
393
af20e07e53c5 Remove dirtylibs test while freeing plc libs in PLCObject.py
laurent
parents: 368
diff changeset
   387
        if self.PLCStatus in ["Stopped", "Empty", "Broken"]:
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   388
            NewFileName = md5sum + lib_ext
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   389
            extra_files_log = os.path.join(self.workingdir,"extra_files.txt")
906
de452d65865c Python runtime now dlopens shared library immediatly after transfer, and release it only immediately before reloading a new one. This is probably going to reveal lot of dirty cleanups during start/stop cycles.
Edouard Tisserant
parents: 868
diff changeset
   390
1045
a220a27defe5 Runtime now unloads and cleanup PLC before exit (created threads was preventing exit)
Edouard Tisserant
parents: 1035
diff changeset
   391
            self.UnLoadPLC()
a220a27defe5 Runtime now unloads and cleanup PLC before exit (created threads was preventing exit)
Edouard Tisserant
parents: 1035
diff changeset
   392
1011
388777d307de Fixed bug when transferring New PLC to a non-empty pyro connector
Laurent Bessard
parents: 972
diff changeset
   393
            self.LogMessage("NewPLC (%s)"%md5sum)
906
de452d65865c Python runtime now dlopens shared library immediatly after transfer, and release it only immediately before reloading a new one. This is probably going to reveal lot of dirty cleanups during start/stop cycles.
Edouard Tisserant
parents: 868
diff changeset
   394
            self.PLCStatus = "Empty"
de452d65865c Python runtime now dlopens shared library immediatly after transfer, and release it only immediately before reloading a new one. This is probably going to reveal lot of dirty cleanups during start/stop cycles.
Edouard Tisserant
parents: 868
diff changeset
   395
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   396
            try:
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   397
                os.remove(os.path.join(self.workingdir,
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   398
                                       self.CurrentPLCFilename))
364
27ea6a6747fc Bug extra_files deletion in working directory fixed
laurent
parents: 361
diff changeset
   399
                for filename in file(extra_files_log, "r").readlines() + [extra_files_log]:
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   400
                    try:
364
27ea6a6747fc Bug extra_files deletion in working directory fixed
laurent
parents: 361
diff changeset
   401
                        os.remove(os.path.join(self.workingdir, filename.strip()))
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   402
                    except:
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   403
                        pass
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   404
            except:
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   405
                pass
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   406
                        
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   407
            try:
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   408
                # Create new PLC file
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   409
                open(os.path.join(self.workingdir,NewFileName),
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   410
                     'wb').write(data)
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   411
        
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   412
                # Store new PLC filename based on md5 key
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   413
                open(self._GetMD5FileName(), "w").write(md5sum)
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   414
        
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   415
                # Then write the files
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   416
                log = file(extra_files_log, "w")
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   417
                for fname,fdata in extrafiles:
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   418
                    fpath = os.path.join(self.workingdir,fname)
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   419
                    open(fpath, "wb").write(fdata)
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   420
                    log.write(fname+'\n')
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   421
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   422
                # Store new PLC filename
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   423
                self.CurrentPLCFilename = NewFileName
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   424
            except:
906
de452d65865c Python runtime now dlopens shared library immediatly after transfer, and release it only immediately before reloading a new one. This is probably going to reveal lot of dirty cleanups during start/stop cycles.
Edouard Tisserant
parents: 868
diff changeset
   425
                self.PLCStatus = "Broken"
de452d65865c Python runtime now dlopens shared library immediatly after transfer, and release it only immediately before reloading a new one. This is probably going to reveal lot of dirty cleanups during start/stop cycles.
Edouard Tisserant
parents: 868
diff changeset
   426
                self.StatusChange()
291
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
   427
                PLCprint(traceback.format_exc())
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   428
                return False
906
de452d65865c Python runtime now dlopens shared library immediatly after transfer, and release it only immediately before reloading a new one. This is probably going to reveal lot of dirty cleanups during start/stop cycles.
Edouard Tisserant
parents: 868
diff changeset
   429
1027
4e44c2c3e081 Fixed bug when starting Beremiz_runtime.py non empty (-a)
Edouard Tisserant
parents: 1014
diff changeset
   430
            if self.LoadPLC():
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   431
                self.PLCStatus = "Stopped"
906
de452d65865c Python runtime now dlopens shared library immediatly after transfer, and release it only immediately before reloading a new one. This is probably going to reveal lot of dirty cleanups during start/stop cycles.
Edouard Tisserant
parents: 868
diff changeset
   432
            else:
1035
0f905e027d18 Better mdns resolution failure signaling, added fixed bug whith runtime autostart
Edouard Tisserant
parents: 1027
diff changeset
   433
                self.PLCStatus = "Broken"
906
de452d65865c Python runtime now dlopens shared library immediatly after transfer, and release it only immediately before reloading a new one. This is probably going to reveal lot of dirty cleanups during start/stop cycles.
Edouard Tisserant
parents: 868
diff changeset
   434
                self._FreePLC()
de452d65865c Python runtime now dlopens shared library immediatly after transfer, and release it only immediately before reloading a new one. This is probably going to reveal lot of dirty cleanups during start/stop cycles.
Edouard Tisserant
parents: 868
diff changeset
   435
            self.StatusChange()
de452d65865c Python runtime now dlopens shared library immediatly after transfer, and release it only immediately before reloading a new one. This is probably going to reveal lot of dirty cleanups during start/stop cycles.
Edouard Tisserant
parents: 868
diff changeset
   436
de452d65865c Python runtime now dlopens shared library immediatly after transfer, and release it only immediately before reloading a new one. This is probably going to reveal lot of dirty cleanups during start/stop cycles.
Edouard Tisserant
parents: 868
diff changeset
   437
            return self.PLCStatus == "Stopped"
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   438
        return False
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   439
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   440
    def MatchMD5(self, MD5):
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   441
        try:
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   442
            last_md5 = open(self._GetMD5FileName(), "r").read()
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   443
            return last_md5 == MD5
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   444
        except:
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   445
            return False
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   446
    
477
f66a092b6e74 Arbitrary variable forcing
Edouard TISSERANT <edouard.tisserant@gmail.com>
parents: 467
diff changeset
   447
592
c6408f92da0a Initial TIME support in debugger
Edouard Tisserant
parents: 504
diff changeset
   448
    
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   449
    def SetTraceVariablesList(self, idxs):
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   450
        """
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   451
        Call ctype imported function to append 
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   452
        these indexes to registred variables in PLC debugger
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   453
        """
462
274e83a5534e Now debug is not a button anymore
Edouard TISSERANT <edouard.tisserant@gmail.com>
parents: 461
diff changeset
   454
        if idxs:
274e83a5534e Now debug is not a button anymore
Edouard TISSERANT <edouard.tisserant@gmail.com>
parents: 461
diff changeset
   455
            # suspend but dont disable
614
eed1dcf311a1 added return type to suspendDebug
Edouard Tisserant
parents: 593
diff changeset
   456
            if self._suspendDebug(False) == 0:
eed1dcf311a1 added return type to suspendDebug
Edouard Tisserant
parents: 593
diff changeset
   457
                # keep a copy of requested idx
eed1dcf311a1 added return type to suspendDebug
Edouard Tisserant
parents: 593
diff changeset
   458
                self._Idxs = idxs[:]
eed1dcf311a1 added return type to suspendDebug
Edouard Tisserant
parents: 593
diff changeset
   459
                self._ResetDebugVariables()
eed1dcf311a1 added return type to suspendDebug
Edouard Tisserant
parents: 593
diff changeset
   460
                for idx,iectype,force in idxs:
eed1dcf311a1 added return type to suspendDebug
Edouard Tisserant
parents: 593
diff changeset
   461
                    if force !=None:
eed1dcf311a1 added return type to suspendDebug
Edouard Tisserant
parents: 593
diff changeset
   462
                        c_type,unpack_func, pack_func = \
eed1dcf311a1 added return type to suspendDebug
Edouard Tisserant
parents: 593
diff changeset
   463
                            TypeTranslator.get(iectype,
eed1dcf311a1 added return type to suspendDebug
Edouard Tisserant
parents: 593
diff changeset
   464
                                                    (None,None,None))
eed1dcf311a1 added return type to suspendDebug
Edouard Tisserant
parents: 593
diff changeset
   465
                        force = ctypes.byref(pack_func(c_type,force)) 
eed1dcf311a1 added return type to suspendDebug
Edouard Tisserant
parents: 593
diff changeset
   466
                    self._RegisterDebugVariable(idx, force)
eed1dcf311a1 added return type to suspendDebug
Edouard Tisserant
parents: 593
diff changeset
   467
                self._resumeDebug()
462
274e83a5534e Now debug is not a button anymore
Edouard TISSERANT <edouard.tisserant@gmail.com>
parents: 461
diff changeset
   468
        else:
274e83a5534e Now debug is not a button anymore
Edouard TISSERANT <edouard.tisserant@gmail.com>
parents: 461
diff changeset
   469
            self._suspendDebug(True)
274e83a5534e Now debug is not a button anymore
Edouard TISSERANT <edouard.tisserant@gmail.com>
parents: 461
diff changeset
   470
            self._Idxs =  []
280
f2ef79f3dba0 Added native (not a plugin) asynchronous python eval function block - Beta. Code cleanup in C code templates.
etisserant
parents: 269
diff changeset
   471
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   472
    def GetTraceVariables(self):
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   473
        """
339
6dbde4a0c31d Adding support for updating PLC status when stopping
greg
parents: 336
diff changeset
   474
        Return a list of variables, corresponding to the list of required idx
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   475
        """
286
a2a8a52b0d4f Minor changes to get better cleanup of debug and python_eval threads, accross multiple debug sessions and PLC runs.
etisserant
parents: 283
diff changeset
   476
        if self.PLCStatus == "Started":
450
18583d13f0fa Preliminary accessor support for debug
Edouard TISSERANT <edouard.tisserant@gmail.com>
parents: 446
diff changeset
   477
            tick = ctypes.c_uint32()
18583d13f0fa Preliminary accessor support for debug
Edouard TISSERANT <edouard.tisserant@gmail.com>
parents: 446
diff changeset
   478
            size = ctypes.c_uint32()
1075
8078c01ae464 Now Debug Buffer Unpacking is a separate function, declared in typemapping.py
Edouard Tisserant
parents: 1074
diff changeset
   479
            buff = ctypes.c_void_p()
8078c01ae464 Now Debug Buffer Unpacking is a separate function, declared in typemapping.py
Edouard Tisserant
parents: 1074
diff changeset
   480
            TraceVariables = None
795
afcc13faecd5 Fix bug debugger unable to restart after stopping PLC
laurent
parents: 734
diff changeset
   481
            if self.PLClibraryLock.acquire(False):
afcc13faecd5 Fix bug debugger unable to restart after stopping PLC
laurent
parents: 734
diff changeset
   482
                if self._GetDebugData(ctypes.byref(tick),
afcc13faecd5 Fix bug debugger unable to restart after stopping PLC
laurent
parents: 734
diff changeset
   483
                                      ctypes.byref(size),
1075
8078c01ae464 Now Debug Buffer Unpacking is a separate function, declared in typemapping.py
Edouard Tisserant
parents: 1074
diff changeset
   484
                                      ctypes.byref(buff)) == 0:
795
afcc13faecd5 Fix bug debugger unable to restart after stopping PLC
laurent
parents: 734
diff changeset
   485
                    if size.value:
1075
8078c01ae464 Now Debug Buffer Unpacking is a separate function, declared in typemapping.py
Edouard Tisserant
parents: 1074
diff changeset
   486
                        TraceVariables = UnpackDebugBuffer(buff, size.value, self._Idxs)
795
afcc13faecd5 Fix bug debugger unable to restart after stopping PLC
laurent
parents: 734
diff changeset
   487
                    self._FreeDebugData()
483
bc26c42d2eec fixed greg's crap in win32, enhanced debug stability, implemented preliminary retain
edouard
parents: 479
diff changeset
   488
                self.PLClibraryLock.release()
1075
8078c01ae464 Now Debug Buffer Unpacking is a separate function, declared in typemapping.py
Edouard Tisserant
parents: 1074
diff changeset
   489
            if TraceVariables is not None:
8078c01ae464 Now Debug Buffer Unpacking is a separate function, declared in typemapping.py
Edouard Tisserant
parents: 1074
diff changeset
   490
                return self.PLCStatus, tick.value, TraceVariables
917
401e44bae7c0 Now logging have 4 levels
Edouard Tisserant
parents: 914
diff changeset
   491
        return self.PLCStatus, None, []
592
c6408f92da0a Initial TIME support in debugger
Edouard Tisserant
parents: 504
diff changeset
   492
699
6ff64cadb1ff Adding support for executing python scripts on remote runtime
laurent
parents: 690
diff changeset
   493
    def RemoteExec(self, script, **kwargs):
6ff64cadb1ff Adding support for executing python scripts on remote runtime
laurent
parents: 690
diff changeset
   494
        try:
6ff64cadb1ff Adding support for executing python scripts on remote runtime
laurent
parents: 690
diff changeset
   495
            exec script in kwargs
6ff64cadb1ff Adding support for executing python scripts on remote runtime
laurent
parents: 690
diff changeset
   496
        except:
6ff64cadb1ff Adding support for executing python scripts on remote runtime
laurent
parents: 690
diff changeset
   497
            e_type, e_value, e_traceback = sys.exc_info()
6ff64cadb1ff Adding support for executing python scripts on remote runtime
laurent
parents: 690
diff changeset
   498
            line_no = traceback.tb_lineno(get_last_traceback(e_traceback))
6ff64cadb1ff Adding support for executing python scripts on remote runtime
laurent
parents: 690
diff changeset
   499
            return (-1, "RemoteExec script failed!\n\nLine %d: %s\n\t%s" % 
6ff64cadb1ff Adding support for executing python scripts on remote runtime
laurent
parents: 690
diff changeset
   500
                        (line_no, e_value, script.splitlines()[line_no - 1]))
6ff64cadb1ff Adding support for executing python scripts on remote runtime
laurent
parents: 690
diff changeset
   501
        return (0, kwargs.get("returnVal", None))
6ff64cadb1ff Adding support for executing python scripts on remote runtime
laurent
parents: 690
diff changeset
   502
    
6ff64cadb1ff Adding support for executing python scripts on remote runtime
laurent
parents: 690
diff changeset
   503