runtime/PLCObject.py
author greg
Mon, 18 May 2009 07:47:24 +0200
changeset 344 25b7b7f854bc
parent 339 6dbde4a0c31d
child 350 a3a5561bde1d
permissions -rwxr-xr-x
Wait the debug thread has terminated before freeing PLC to avoid random segmentation fault.

Store working directory to globals copy, in order to be used in runtime.py.
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
280
f2ef79f3dba0 Added native (not a plugin) asynchronous python eval function block - Beta. Code cleanup in C code templates.
etisserant
parents: 269
diff changeset
    26
from threading import Timer, Thread
301
87c925eaaa3a Added support for wxglade GUIs.
etisserant
parents: 299
diff changeset
    27
import ctypes, os, commands, types, sys
344
25b7b7f854bc Wait the debug thread has terminated before freeing PLC to avoid random segmentation fault.
greg
parents: 339
diff changeset
    28
import time
301
87c925eaaa3a Added support for wxglade GUIs.
etisserant
parents: 299
diff changeset
    29
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    30
if os.name in ("nt", "ce"):
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    31
    from _ctypes import LoadLibrary as dlopen
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    32
    from _ctypes import FreeLibrary as dlclose
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    33
elif os.name == "posix":
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    34
    from _ctypes import dlopen, dlclose
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    35
344
25b7b7f854bc Wait the debug thread has terminated before freeing PLC to avoid random segmentation fault.
greg
parents: 339
diff changeset
    36
import traceback
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    37
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    38
lib_ext ={
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    39
     "linux2":".so",
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    40
     "win32":".dll",
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    41
     }.get(sys.platform, "")
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    42
291
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
    43
def PLCprint(message):
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
    44
    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
    45
    sys.stdout.flush()
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
    46
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    47
class PLCObject(pyro.ObjBase):
235
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
    48
    _Idxs = []
329
22e65b8e20f4 add autostart plc feature for beremiz_service
greg
parents: 327
diff changeset
    49
    def __init__(self, workingdir, daemon, argv, statuschange, evaluator):
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    50
        pyro.ObjBase.__init__(self)
301
87c925eaaa3a Added support for wxglade GUIs.
etisserant
parents: 299
diff changeset
    51
        self.evaluator = evaluator
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    52
        self.argv = [workingdir] + argv # force argv[0] to be "path" to exec...
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    53
        self.workingdir = workingdir
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    54
        self.PLCStatus = "Stopped"
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    55
        self.PLClibraryHandle = None
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    56
        # Creates fake C funcs proxies
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    57
        self._FreePLC()
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    58
        self.daemon = daemon
269
d29c5f71574f add a TaskBarIcon to configure beremiz_service and display plc states (started, stopped)
greg
parents: 239
diff changeset
    59
        self.statuschange = statuschange
301
87c925eaaa3a Added support for wxglade GUIs.
etisserant
parents: 299
diff changeset
    60
        self.hmi_frame = None
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    61
        
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    62
        # Get the last transfered PLC if connector must be restart
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    63
        try:
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    64
            self.CurrentPLCFilename=open(
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    65
                             self._GetMD5FileName(),
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    66
                             "r").read().strip() + lib_ext
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    67
        except Exception, e:
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    68
            self.PLCStatus = "Empty"
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    69
            self.CurrentPLCFilename=None
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    70
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
    71
    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
    72
        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
    73
            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
    74
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    75
    def _GetMD5FileName(self):
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    76
        return os.path.join(self.workingdir, "lasttransferedPLC.md5")
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    77
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    78
    def _GetLibFileName(self):
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    79
        return os.path.join(self.workingdir,self.CurrentPLCFilename)
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    80
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    81
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    82
    def _LoadNewPLC(self):
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    83
        """
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    84
        Load PLC library
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    85
        Declare all functions, arguments and return values
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    86
        """
291
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
    87
        PLCprint("Load PLC")
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    88
        try:
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    89
            self._PLClibraryHandle = dlopen(self._GetLibFileName())
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    90
            self.PLClibraryHandle = ctypes.CDLL(self.CurrentPLCFilename, handle=self._PLClibraryHandle)
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    91
    
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    92
            self._startPLC = self.PLClibraryHandle.startPLC
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    93
            self._startPLC.restype = ctypes.c_int
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    94
            self._startPLC.argtypes = [ctypes.c_int, ctypes.POINTER(ctypes.c_char_p)]
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    95
            
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    96
            self._stopPLC = self.PLClibraryHandle.stopPLC
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    97
            self._stopPLC.restype = None
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    98
    
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    99
            self._ResetDebugVariables = self.PLClibraryHandle.ResetDebugVariables
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   100
            self._ResetDebugVariables.restype = None
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   101
    
235
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   102
            self._RegisterDebugVariable = self.PLClibraryHandle.RegisterDebugVariable
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   103
            self._RegisterDebugVariable.restype = None
235
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   104
            self._RegisterDebugVariable.argtypes = [ctypes.c_int]
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   105
    
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   106
            self._IterDebugData = self.PLClibraryHandle.IterDebugData
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   107
            self._IterDebugData.restype = ctypes.c_void_p
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   108
            self._IterDebugData.argtypes = [ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.c_char_p)]
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   109
    
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   110
            self._FreeDebugData = self.PLClibraryHandle.FreeDebugData
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   111
            self._FreeDebugData.restype = None
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   112
            
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   113
            self._WaitDebugData = self.PLClibraryHandle.WaitDebugData
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   114
            self._WaitDebugData.restype = ctypes.c_int  
235
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   115
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   116
            self._suspendDebug = self.PLClibraryHandle.suspendDebug
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   117
            self._suspendDebug.restype = None
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   118
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   119
            self._resumeDebug = self.PLClibraryHandle.resumeDebug
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   120
            self._resumeDebug.restype = 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
   121
f2ef79f3dba0 Added native (not a plugin) asynchronous python eval function block - Beta. Code cleanup in C code templates.
etisserant
parents: 269
diff changeset
   122
            self._PythonIterator = self.PLClibraryHandle.PythonIterator
f2ef79f3dba0 Added native (not a plugin) asynchronous python eval function block - Beta. Code cleanup in C code templates.
etisserant
parents: 269
diff changeset
   123
            self._PythonIterator.restype = ctypes.c_char_p
f2ef79f3dba0 Added native (not a plugin) asynchronous python eval function block - Beta. Code cleanup in C code templates.
etisserant
parents: 269
diff changeset
   124
            self._PythonIterator.argtypes = [ctypes.c_char_p]
235
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   125
            
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   126
            return True
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   127
        except:
291
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
   128
            PLCprint(traceback.format_exc())
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   129
            return False
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   130
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   131
    def _FreePLC(self):
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   132
        """
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   133
        Unload PLC library.
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   134
        This is also called by __init__ to create dummy C func proxies
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   135
        """
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   136
        # Forget all refs to library
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   137
        self._startPLC = lambda:None
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   138
        self._stopPLC = lambda:None
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   139
        self._ResetDebugVariables = lambda:None
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   140
        self._RegisterDebugVariable = lambda x:None
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   141
        self._IterDebugData = lambda x,y:None
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   142
        self._FreeDebugData = lambda:None
235
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   143
        self._WaitDebugData = lambda:-1
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   144
        self._suspendDebug = lambda:None
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   145
        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
   146
        self._PythonIterator = lambda:""
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   147
        self.PLClibraryHandle = None
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   148
        # Unload library explicitely
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   149
        if getattr(self,"_PLClibraryHandle",None) is not None:
291
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
   150
            PLCprint("Unload PLC")
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   151
            dlclose(self._PLClibraryHandle)
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   152
            res = self._DetectDirtyLibs()
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   153
        else:
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   154
            res = False
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   155
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   156
        self._PLClibraryHandle = None
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   157
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   158
        return res
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   159
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   160
    def _DetectDirtyLibs(self):
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   161
        # Detect dirty libs
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   162
        # Get lib dependencies (for dirty lib detection)
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   163
        if os.name == "posix":
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   164
            # parasiting libs listed with ldd
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   165
            badlibs = [ toks.split()[0] for toks in commands.getoutput(
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   166
                            "ldd "+self._GetLibFileName()).splitlines() ]
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   167
            for badlib in badlibs:
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   168
                if badlib[:6] in ["libwx_",
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   169
                                  "libwxs",
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   170
                                  "libgtk",
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   171
                                  "libgdk",
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   172
                                  "libatk",
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   173
                                  "libpan",
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   174
                                  "libX11",
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   175
                                  ]:
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   176
                    #badhandle = dlopen(badlib, dl.RTLD_NOLOAD)
291
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
   177
                    PLCprint("Dirty lib detected :" + badlib)
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   178
                    #dlclose(badhandle)
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   179
                    return True
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   180
        return False
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   181
299
d7f8ffe18017 Enhanced the way "runtime.py" is executed,
etisserant
parents: 291
diff changeset
   182
    def PrepareRuntimePy(self):
290
3bd617ae7a05 Local Runtime (LOCAL://) now launched "on demand"
etisserant
parents: 286
diff changeset
   183
        self.python_threads_vars = globals().copy()
344
25b7b7f854bc Wait the debug thread has terminated before freeing PLC to avoid random segmentation fault.
greg
parents: 339
diff changeset
   184
        self.python_threads_vars["WorkingDir"] = self.workingdir
283
d0e6fc0701fb Added "runtime.py", a file that is executed in python thread in runtime, before handling python_eval FBs requests. Added small python editor taken from wxPython demo, and appropriate icon and button to launch it.
etisserant
parents: 280
diff changeset
   185
        pyfile = os.path.join(self.workingdir, "runtime.py")
301
87c925eaaa3a Added support for wxglade GUIs.
etisserant
parents: 299
diff changeset
   186
        hmifile = os.path.join(self.workingdir, "hmi.py")
322
b8ae0580565c Make 'runtime.py' and 'hmi.py' executed independantly
lbessard
parents: 319
diff changeset
   187
        if os.path.exists(hmifile):
b8ae0580565c Make 'runtime.py' and 'hmi.py' executed independantly
lbessard
parents: 319
diff changeset
   188
            try:
b8ae0580565c Make 'runtime.py' and 'hmi.py' executed independantly
lbessard
parents: 319
diff changeset
   189
                execfile(hmifile, self.python_threads_vars)
332
4f0e1d66bba5 add utf-8 and save shortcut support in PythonST
greg
parents: 331
diff changeset
   190
                if os.path.exists(pyfile):
4f0e1d66bba5 add utf-8 and save shortcut support in PythonST
greg
parents: 331
diff changeset
   191
                    try:
4f0e1d66bba5 add utf-8 and save shortcut support in PythonST
greg
parents: 331
diff changeset
   192
                        # TODO handle exceptions in runtime.py
4f0e1d66bba5 add utf-8 and save shortcut support in PythonST
greg
parents: 331
diff changeset
   193
                        # pyfile may redefine _runtime_cleanup
4f0e1d66bba5 add utf-8 and save shortcut support in PythonST
greg
parents: 331
diff changeset
   194
                        # or even call _PythonThreadProc itself.
4f0e1d66bba5 add utf-8 and save shortcut support in PythonST
greg
parents: 331
diff changeset
   195
                        execfile(pyfile, self.python_threads_vars)
4f0e1d66bba5 add utf-8 and save shortcut support in PythonST
greg
parents: 331
diff changeset
   196
                    except:
4f0e1d66bba5 add utf-8 and save shortcut support in PythonST
greg
parents: 331
diff changeset
   197
                        PLCprint(traceback.format_exc())
322
b8ae0580565c Make 'runtime.py' and 'hmi.py' executed independantly
lbessard
parents: 319
diff changeset
   198
                if self.python_threads_vars.has_key('wx'):
b8ae0580565c Make 'runtime.py' and 'hmi.py' executed independantly
lbessard
parents: 319
diff changeset
   199
                    wx = self.python_threads_vars['wx']
b8ae0580565c Make 'runtime.py' and 'hmi.py' executed independantly
lbessard
parents: 319
diff changeset
   200
                    # try to instanciate the first frame found.
b8ae0580565c Make 'runtime.py' and 'hmi.py' executed independantly
lbessard
parents: 319
diff changeset
   201
                    for name, obj in self.python_threads_vars.iteritems():
b8ae0580565c Make 'runtime.py' and 'hmi.py' executed independantly
lbessard
parents: 319
diff changeset
   202
                        # obj is a class
b8ae0580565c Make 'runtime.py' and 'hmi.py' executed independantly
lbessard
parents: 319
diff changeset
   203
                        if type(obj)==type(type) and issubclass(obj,wx.Frame):
b8ae0580565c Make 'runtime.py' and 'hmi.py' executed independantly
lbessard
parents: 319
diff changeset
   204
                            def create_frame():
b8ae0580565c Make 'runtime.py' and 'hmi.py' executed independantly
lbessard
parents: 319
diff changeset
   205
                                self.hmi_frame = obj(None)
b8ae0580565c Make 'runtime.py' and 'hmi.py' executed independantly
lbessard
parents: 319
diff changeset
   206
                                self.python_threads_vars[name] = self.hmi_frame
b8ae0580565c Make 'runtime.py' and 'hmi.py' executed independantly
lbessard
parents: 319
diff changeset
   207
                                # keep track of class... never know
b8ae0580565c Make 'runtime.py' and 'hmi.py' executed independantly
lbessard
parents: 319
diff changeset
   208
                                self.python_threads_vars['Class_'+name] = obj
b8ae0580565c Make 'runtime.py' and 'hmi.py' executed independantly
lbessard
parents: 319
diff changeset
   209
                                self.hmi_frame.Bind(wx.EVT_CLOSE, OnCloseFrame)
b8ae0580565c Make 'runtime.py' and 'hmi.py' executed independantly
lbessard
parents: 319
diff changeset
   210
                                self.hmi_frame.Show()
b8ae0580565c Make 'runtime.py' and 'hmi.py' executed independantly
lbessard
parents: 319
diff changeset
   211
                            
b8ae0580565c Make 'runtime.py' and 'hmi.py' executed independantly
lbessard
parents: 319
diff changeset
   212
                            def OnCloseFrame(evt):
b8ae0580565c Make 'runtime.py' and 'hmi.py' executed independantly
lbessard
parents: 319
diff changeset
   213
                                wx.MessageBox("Please stop PLC to close")
b8ae0580565c Make 'runtime.py' and 'hmi.py' executed independantly
lbessard
parents: 319
diff changeset
   214
                            create_frame()
b8ae0580565c Make 'runtime.py' and 'hmi.py' executed independantly
lbessard
parents: 319
diff changeset
   215
                            break
b8ae0580565c Make 'runtime.py' and 'hmi.py' executed independantly
lbessard
parents: 319
diff changeset
   216
            except:
b8ae0580565c Make 'runtime.py' and 'hmi.py' executed independantly
lbessard
parents: 319
diff changeset
   217
                PLCprint(traceback.format_exc())
332
4f0e1d66bba5 add utf-8 and save shortcut support in PythonST
greg
parents: 331
diff changeset
   218
        elif os.path.exists(pyfile):
4f0e1d66bba5 add utf-8 and save shortcut support in PythonST
greg
parents: 331
diff changeset
   219
            try:
4f0e1d66bba5 add utf-8 and save shortcut support in PythonST
greg
parents: 331
diff changeset
   220
                # TODO handle exceptions in runtime.py
4f0e1d66bba5 add utf-8 and save shortcut support in PythonST
greg
parents: 331
diff changeset
   221
                # pyfile may redefine _runtime_cleanup
4f0e1d66bba5 add utf-8 and save shortcut support in PythonST
greg
parents: 331
diff changeset
   222
                # or even call _PythonThreadProc itself.
4f0e1d66bba5 add utf-8 and save shortcut support in PythonST
greg
parents: 331
diff changeset
   223
                execfile(pyfile, self.python_threads_vars)
4f0e1d66bba5 add utf-8 and save shortcut support in PythonST
greg
parents: 331
diff changeset
   224
            except:
4f0e1d66bba5 add utf-8 and save shortcut support in PythonST
greg
parents: 331
diff changeset
   225
                PLCprint(traceback.format_exc())
299
d7f8ffe18017 Enhanced the way "runtime.py" is executed,
etisserant
parents: 291
diff changeset
   226
        runtime_begin = self.python_threads_vars.get("_runtime_begin",None)
d7f8ffe18017 Enhanced the way "runtime.py" is executed,
etisserant
parents: 291
diff changeset
   227
        if runtime_begin is not None:
329
22e65b8e20f4 add autostart plc feature for beremiz_service
greg
parents: 327
diff changeset
   228
            runtime_begin()
291
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
   229
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
   230
    def FinishRuntimePy(self):
336
ae3488c79283 Fixed bug : Segmentation fault or locks when stop PLC if no CAN network.
greg
parents: 332
diff changeset
   231
        runtime_cleanup = None
ae3488c79283 Fixed bug : Segmentation fault or locks when stop PLC if no CAN network.
greg
parents: 332
diff changeset
   232
        if self.python_threads_vars is not None:
ae3488c79283 Fixed bug : Segmentation fault or locks when stop PLC if no CAN network.
greg
parents: 332
diff changeset
   233
            runtime_cleanup = self.python_threads_vars.get("_runtime_cleanup",None)
299
d7f8ffe18017 Enhanced the way "runtime.py" is executed,
etisserant
parents: 291
diff changeset
   234
        if runtime_cleanup is not None:
329
22e65b8e20f4 add autostart plc feature for beremiz_service
greg
parents: 327
diff changeset
   235
            runtime_cleanup()
301
87c925eaaa3a Added support for wxglade GUIs.
etisserant
parents: 299
diff changeset
   236
        if self.hmi_frame is not None:
329
22e65b8e20f4 add autostart plc feature for beremiz_service
greg
parents: 327
diff changeset
   237
            self.hmi_frame.Destroy()
291
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
   238
        self.python_threads_vars = None
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
   239
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
   240
    def PythonThreadProc(self):
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
   241
        PLCprint("PythonThreadProc started")
329
22e65b8e20f4 add autostart plc feature for beremiz_service
greg
parents: 327
diff changeset
   242
        self.evaluator(self.PrepareRuntimePy)
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
   243
        res,cmd = "None","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
   244
        while self.PLCStatus == "Started":
290
3bd617ae7a05 Local Runtime (LOCAL://) now launched "on demand"
etisserant
parents: 286
diff changeset
   245
            #print "_PythonIterator(", res, ")",
280
f2ef79f3dba0 Added native (not a plugin) asynchronous python eval function block - Beta. Code cleanup in C code templates.
etisserant
parents: 269
diff changeset
   246
            cmd = self._PythonIterator(res)
290
3bd617ae7a05 Local Runtime (LOCAL://) now launched "on demand"
etisserant
parents: 286
diff changeset
   247
            #print " -> ", cmd
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
   248
            if cmd is 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
   249
                break
280
f2ef79f3dba0 Added native (not a plugin) asynchronous python eval function block - Beta. Code cleanup in C code templates.
etisserant
parents: 269
diff changeset
   250
            try :
301
87c925eaaa3a Added support for wxglade GUIs.
etisserant
parents: 299
diff changeset
   251
                res = str(self.evaluator(eval,cmd,self.python_threads_vars))
280
f2ef79f3dba0 Added native (not a plugin) asynchronous python eval function block - Beta. Code cleanup in C code templates.
etisserant
parents: 269
diff changeset
   252
            except Exception,e:
f2ef79f3dba0 Added native (not a plugin) asynchronous python eval function block - Beta. Code cleanup in C code templates.
etisserant
parents: 269
diff changeset
   253
                res = "#EXCEPTION : "+str(e)
291
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
   254
                PLCprint(res)
329
22e65b8e20f4 add autostart plc feature for beremiz_service
greg
parents: 327
diff changeset
   255
        self.evaluator(self.FinishRuntimePy)
291
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
   256
        PLCprint("PythonThreadProc interrupted")
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   257
    
235
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   258
    def StartPLC(self, debug=False):
291
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
   259
        PLCprint("StartPLC")
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   260
        if self.CurrentPLCFilename is not None and self.PLCStatus == "Stopped":
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   261
            c_argv = ctypes.c_char_p * len(self.argv)
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   262
            if self._LoadNewPLC() and self._startPLC(len(self.argv),c_argv(*self.argv)) == 0:
235
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   263
                if debug:
327
e82c422ad811 Register the current watched variable in Debug Window before starting
lbessard
parents: 322
diff changeset
   264
                    for idx in self._Idxs:
e82c422ad811 Register the current watched variable in Debug Window before starting
lbessard
parents: 322
diff changeset
   265
                        self._RegisterDebugVariable(idx)
235
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   266
                    self._resumeDebug()
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   267
                self.PLCStatus = "Started"
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
   268
                self.StatusChange()
280
f2ef79f3dba0 Added native (not a plugin) asynchronous python eval function block - Beta. Code cleanup in C code templates.
etisserant
parents: 269
diff changeset
   269
                self.PythonThread = Thread(target=self.PythonThreadProc)
f2ef79f3dba0 Added native (not a plugin) asynchronous python eval function block - Beta. Code cleanup in C code templates.
etisserant
parents: 269
diff changeset
   270
                self.PythonThread.start()
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   271
                return True
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   272
            else:
291
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
   273
                PLCprint("Problem starting PLC")
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   274
                self._DoStopPLC()
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   275
        return False
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   276
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   277
    def _DoStopPLC(self):
329
22e65b8e20f4 add autostart plc feature for beremiz_service
greg
parents: 327
diff changeset
   278
        self.PLCStatus = "Stopped"
339
6dbde4a0c31d Adding support for updating PLC status when stopping
greg
parents: 336
diff changeset
   279
        self.StatusChange()
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   280
        self._stopPLC()
344
25b7b7f854bc Wait the debug thread has terminated before freeing PLC to avoid random segmentation fault.
greg
parents: 339
diff changeset
   281
        if self.PythonThread.isAlive():
25b7b7f854bc Wait the debug thread has terminated before freeing PLC to avoid random segmentation fault.
greg
parents: 339
diff changeset
   282
            self.PythonThread.join()
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   283
        if self._FreePLC():
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   284
            self.PLCStatus = "Dirty"
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
   285
        self.StatusChange()
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   286
        return True
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   287
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   288
    def StopPLC(self):
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   289
        if self.PLCStatus == "Started":
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   290
            self._DoStopPLC()
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   291
            return True
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   292
        return False
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   293
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   294
    def _Reload(self):
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   295
        self.daemon.shutdown(True)
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   296
        self.daemon.sock.close()
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   297
        os.execv(sys.executable,[sys.executable]+sys.argv[:])
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   298
        # never reached
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   299
        return 0
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   300
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   301
    def ForceReload(self):
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   302
        # respawn python interpreter
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   303
        Timer(0.1,self._Reload).start()
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   304
        return True
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   305
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   306
    def GetPLCstatus(self):
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   307
        return self.PLCStatus
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   308
    
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   309
    def NewPLC(self, md5sum, data, extrafiles):
291
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
   310
        PLCprint("NewPLC (%s)"%md5sum)
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   311
        if self.PLCStatus in ["Stopped", "Empty", "Dirty"]:
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   312
            NewFileName = md5sum + lib_ext
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   313
            extra_files_log = os.path.join(self.workingdir,"extra_files.txt")
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   314
            try:
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   315
                os.remove(os.path.join(self.workingdir,
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   316
                                       self.CurrentPLCFilename))
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   317
                for filename in file(extra_files_log, "r").readlines() + extra_files_log:
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   318
                    try:
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   319
                        os.remove(os.path.join(self.workingdir, filename))
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   320
                    except:
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   321
                        pass
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   322
            except:
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   323
                pass
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   324
                        
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   325
            try:
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   326
                # Create new PLC file
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   327
                open(os.path.join(self.workingdir,NewFileName),
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   328
                     'wb').write(data)
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   329
        
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   330
                # Store new PLC filename based on md5 key
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   331
                open(self._GetMD5FileName(), "w").write(md5sum)
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   332
        
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   333
                # Then write the files
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   334
                log = file(extra_files_log, "w")
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   335
                for fname,fdata in extrafiles:
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   336
                    fpath = os.path.join(self.workingdir,fname)
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   337
                    open(fpath, "wb").write(fdata)
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   338
                    log.write(fname+'\n')
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   339
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   340
                # Store new PLC filename
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   341
                self.CurrentPLCFilename = NewFileName
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   342
            except:
291
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
   343
                PLCprint(traceback.format_exc())
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   344
                return False
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   345
            if self.PLCStatus == "Empty":
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   346
                self.PLCStatus = "Stopped"
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   347
            return True
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   348
        return False
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   349
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   350
    def MatchMD5(self, MD5):
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   351
        try:
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   352
            last_md5 = open(self._GetMD5FileName(), "r").read()
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   353
            return last_md5 == MD5
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   354
        except:
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   355
            return False
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   356
    
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   357
    def SetTraceVariablesList(self, idxs):
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   358
        """
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   359
        Call ctype imported function to append 
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   360
        these indexes to registred variables in PLC debugger
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   361
        """
235
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   362
        self._suspendDebug()
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   363
        # keep a copy of requested idx
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   364
        self._Idxs = idxs[:]
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   365
        self._ResetDebugVariables()
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   366
        for idx in idxs:
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   367
            self._RegisterDebugVariable(idx)
235
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   368
        self._resumeDebug()
280
f2ef79f3dba0 Added native (not a plugin) asynchronous python eval function block - Beta. Code cleanup in C code templates.
etisserant
parents: 269
diff changeset
   369
f2ef79f3dba0 Added native (not a plugin) asynchronous python eval function block - Beta. Code cleanup in C code templates.
etisserant
parents: 269
diff changeset
   370
    class IEC_STRING(ctypes.Structure):
f2ef79f3dba0 Added native (not a plugin) asynchronous python eval function block - Beta. Code cleanup in C code templates.
etisserant
parents: 269
diff changeset
   371
        """
f2ef79f3dba0 Added native (not a plugin) asynchronous python eval function block - Beta. Code cleanup in C code templates.
etisserant
parents: 269
diff changeset
   372
        Must be changed according to changes in iec_types.h
f2ef79f3dba0 Added native (not a plugin) asynchronous python eval function block - Beta. Code cleanup in C code templates.
etisserant
parents: 269
diff changeset
   373
        """
f2ef79f3dba0 Added native (not a plugin) asynchronous python eval function block - Beta. Code cleanup in C code templates.
etisserant
parents: 269
diff changeset
   374
        _fields_ = [("len", ctypes.c_uint8),
302
d962b3d503b5 Enhanced wxGlade GUI creation.
etisserant
parents: 301
diff changeset
   375
                    ("body", ctypes.c_char * 127)] 
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   376
    
238
02d0daed3e46 Debugger now reports BOOL as booleans
etisserant
parents: 237
diff changeset
   377
    TypeTranslator = {"BOOL" :       (ctypes.c_uint8, lambda x:x.value!=0),
02d0daed3e46 Debugger now reports BOOL as booleans
etisserant
parents: 237
diff changeset
   378
                      "STEP" :       (ctypes.c_uint8, lambda x:x.value),
02d0daed3e46 Debugger now reports BOOL as booleans
etisserant
parents: 237
diff changeset
   379
                      "TRANSITION" : (ctypes.c_uint8, lambda x:x.value),
02d0daed3e46 Debugger now reports BOOL as booleans
etisserant
parents: 237
diff changeset
   380
                      "ACTION" :     (ctypes.c_uint8, lambda x:x.value),
02d0daed3e46 Debugger now reports BOOL as booleans
etisserant
parents: 237
diff changeset
   381
                      "SINT" :       (ctypes.c_int8, lambda x:x.value),
02d0daed3e46 Debugger now reports BOOL as booleans
etisserant
parents: 237
diff changeset
   382
                      "USINT" :      (ctypes.c_uint8, lambda x:x.value),
02d0daed3e46 Debugger now reports BOOL as booleans
etisserant
parents: 237
diff changeset
   383
                      "BYTE" :       (ctypes.c_uint8, lambda x:x.value),
280
f2ef79f3dba0 Added native (not a plugin) asynchronous python eval function block - Beta. Code cleanup in C code templates.
etisserant
parents: 269
diff changeset
   384
                      "STRING" :     (IEC_STRING, lambda x:x.body[:x.len]),
238
02d0daed3e46 Debugger now reports BOOL as booleans
etisserant
parents: 237
diff changeset
   385
                      "INT" :        (ctypes.c_int16, lambda x:x.value),
02d0daed3e46 Debugger now reports BOOL as booleans
etisserant
parents: 237
diff changeset
   386
                      "UINT" :       (ctypes.c_uint16, lambda x:x.value),
02d0daed3e46 Debugger now reports BOOL as booleans
etisserant
parents: 237
diff changeset
   387
                      "WORD" :       (ctypes.c_uint16, lambda x:x.value),
02d0daed3e46 Debugger now reports BOOL as booleans
etisserant
parents: 237
diff changeset
   388
                      "WSTRING" :    (None, None),#TODO
02d0daed3e46 Debugger now reports BOOL as booleans
etisserant
parents: 237
diff changeset
   389
                      "DINT" :       (ctypes.c_int32, lambda x:x.value),
02d0daed3e46 Debugger now reports BOOL as booleans
etisserant
parents: 237
diff changeset
   390
                      "UDINT" :      (ctypes.c_uint32, lambda x:x.value),
02d0daed3e46 Debugger now reports BOOL as booleans
etisserant
parents: 237
diff changeset
   391
                      "DWORD" :      (ctypes.c_uint32, lambda x:x.value),
02d0daed3e46 Debugger now reports BOOL as booleans
etisserant
parents: 237
diff changeset
   392
                      "LINT" :       (ctypes.c_int64, lambda x:x.value),
02d0daed3e46 Debugger now reports BOOL as booleans
etisserant
parents: 237
diff changeset
   393
                      "ULINT" :      (ctypes.c_uint64, lambda x:x.value),
02d0daed3e46 Debugger now reports BOOL as booleans
etisserant
parents: 237
diff changeset
   394
                      "LWORD" :      (ctypes.c_uint64, lambda x:x.value),
02d0daed3e46 Debugger now reports BOOL as booleans
etisserant
parents: 237
diff changeset
   395
                      "REAL" :       (ctypes.c_float, lambda x:x.value),
02d0daed3e46 Debugger now reports BOOL as booleans
etisserant
parents: 237
diff changeset
   396
                      "LREAL" :      (ctypes.c_double, lambda x:x.value),
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   397
                      } 
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   398
                           
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   399
    def GetTraceVariables(self):
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   400
        """
339
6dbde4a0c31d Adding support for updating PLC status when stopping
greg
parents: 336
diff changeset
   401
        Return a list of variables, corresponding to the list of required idx
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   402
        """
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
   403
        if self.PLCStatus == "Started":
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
   404
            tick = self._WaitDebugData()
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
   405
            if tick == -1:
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
   406
                res = 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
   407
            else:
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
   408
                idx = ctypes.c_int()
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
   409
                typename = ctypes.c_char_p()
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
   410
                res = []
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
   411
        
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
   412
                for given_idx in self._Idxs:
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
   413
                    buffer=self._IterDebugData(ctypes.byref(idx), ctypes.byref(typename))
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
   414
                    c_type,unpack_func = self.TypeTranslator.get(typename.value, (None,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
   415
                    if c_type is not None and given_idx == idx.value:
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
   416
                        res.append(unpack_func(ctypes.cast(buffer,
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
   417
                                                           ctypes.POINTER(c_type)).contents))
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
   418
                    else:
291
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
   419
                        PLCprint("Debug error idx : %d, expected_idx %d, type : %s"%(idx.value, given_idx,typename.value))
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
   420
                        res.append(None)
344
25b7b7f854bc Wait the debug thread has terminated before freeing PLC to avoid random segmentation fault.
greg
parents: 339
diff changeset
   421
            time.sleep(0.1)
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
   422
            self._FreeDebugData()
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
   423
            return tick, res
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
   424
        return -1, 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
   425
        
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
   426
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
   427