# HG changeset patch # User greg # Date 1219934088 -7200 # Node ID 8bc65076e290e4a8afad29eaef0f621d2d6bd067 # Parent 848da15cf51363bedd4532f19cbe8ebcb96717a7 add tests for win32 fixed bug for win32 diff -r 848da15cf513 -r 8bc65076e290 Beremiz.py --- a/Beremiz.py Thu Aug 28 15:08:41 2008 +0200 +++ b/Beremiz.py Thu Aug 28 16:34:48 2008 +0200 @@ -369,7 +369,8 @@ "%s %s -p %s -i localhost %s"%(sys.executable, Bpath("Beremiz_service.py"), runtime_port, - self.local_runtime_tmpdir)) + self.local_runtime_tmpdir), + no_gui=False) # Add beremiz's icon in top left corner of the frame self.SetIcon(wx.Icon(Bpath( "images", "brz.ico"), wx.BITMAP_TYPE_ICO)) diff -r 848da15cf513 -r 8bc65076e290 plugins/svgui/svgui.py --- a/plugins/svgui/svgui.py Thu Aug 28 15:08:41 2008 +0200 +++ b/plugins/svgui/svgui.py Thu Aug 28 16:34:48 2008 +0200 @@ -201,8 +201,8 @@ Gen_C_file = os.path.join(buildpath, progname+".cpp" ) if wx.Platform == '__WXMSW__': - cxx_flags = "-I..\\..\\wxPython-src-2.8.7.1\\bld\\lib\\wx\\include\\msw-unicode-release-2.8 -I..\\..\\wxPython-src-2.8.7.1\\include -I..\\..\\wxPython-src-2.8.7.1\\contrib\\include -I..\\..\\matiec\\lib -DWXUSINGDLL -D__WXMSW__ -mthreads" - libs = "\"..\\lib\\libwxsvg.a\" \"..\\lib\\libwxsvg_agg.a\" \"..\\lib\\libagg.a\" \"..\\lib\\libaggplatformwin32.a\" \"..\\lib\\libaggfontwin32tt.a\" -L..\\..\\wxPython-src-2.8.7.1\\bld\\lib -mno-cygwin -mwindows -mthreads -mno-cygwin -mwindows -Wl,--subsystem,windows -mwindows -lwx_mswu_richtext-2.8 -lwx_mswu_aui-2.8 -lwx_mswu_xrc-2.8 -lwx_mswu_qa-2.8 -lwx_mswu_html-2.8 -lwx_mswu_adv-2.8 -lwx_mswu_core-2.8 -lwx_baseu_xml-2.8 -lwx_baseu_net-2.8 -lwx_baseu-2.8" + cxx_flags = "-I..\\..\\wxPython-src-2.8.8.1\\bld\\lib\\wx\\include\\msw-unicode-release-2.8 -I..\\..\\wxPython-src-2.8.8.1\\include -I..\\..\\wxPython-src-2.8.8.1\\contrib\\include -I..\\..\\matiec\\lib -DWXUSINGDLL -D__WXMSW__ -mthreads" + libs = "\"..\\lib\\libwxsvg.a\" \"..\\lib\\libwxsvg_agg.a\" \"..\\lib\\libagg.a\" \"..\\lib\\libaggplatformwin32.a\" \"..\\lib\\libaggfontwin32tt.a\" -L..\\..\\wxPython-src-2.8.8.1\\bld\\lib -mno-cygwin -mwindows -mthreads -mno-cygwin -mwindows -Wl,--subsystem,windows -mwindows -lwx_mswu_richtext-2.8 -lwx_mswu_aui-2.8 -lwx_mswu_xrc-2.8 -lwx_mswu_qa-2.8 -lwx_mswu_html-2.8 -lwx_mswu_adv-2.8 -lwx_mswu_core-2.8 -lwx_baseu_xml-2.8 -lwx_baseu_net-2.8 -lwx_baseu-2.8" else: status, result, err_result = ProcessLogger(self.logger, "wx-config --cxxflags", no_stdout=True).spin() if status: diff -r 848da15cf513 -r 8bc65076e290 runtime/PLCObject.py --- a/runtime/PLCObject.py Thu Aug 28 15:08:41 2008 +0200 +++ b/runtime/PLCObject.py Thu Aug 28 16:34:48 2008 +0200 @@ -1,295 +1,295 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -#This file is part of Beremiz, a Integrated Development Environment for -#programming IEC 61131-3 automates supporting plcopen standard and CanFestival. -# -#Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD -# -#See COPYING file for copyrights details. -# -#This library is free software; you can redistribute it and/or -#modify it under the terms of the GNU General Public -#License as published by the Free Software Foundation; either -#version 2.1 of the License, or (at your option) any later version. -# -#This library is distributed in the hope that it will be useful, -#but WITHOUT ANY WARRANTY; without even the implied warranty of -#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -#General Public License for more details. -# -#You should have received a copy of the GNU General Public -#License along with this library; if not, write to the Free Software -#Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -import Pyro.core as pyro -from threading import Timer -import ctypes, os, commands - -if os.name == ("nt", "ce"): - from _ctypes import LoadLibrary as dlopen - from _ctypes import FreeLibrary as dlclose -elif os.name == "posix": - from _ctypes import dlopen, dlclose - -import os,sys,traceback - -lib_ext ={ - "linux2":".so", - "win32":".dll", - }.get(sys.platform, "") - -class PLCObject(pyro.ObjBase): - def __init__(self, workingdir, daemon, argv): - pyro.ObjBase.__init__(self) - self.argv = [workingdir] + argv # force argv[0] to be "path" to exec... - self.workingdir = workingdir - self.PLCStatus = "Stopped" - self.PLClibraryHandle = None - # Creates fake C funcs proxies - self._FreePLC() - self.daemon = daemon - - # Get the last transfered PLC if connector must be restart - try: - self.CurrentPLCFilename=open( - self._GetMD5FileName(), - "r").read().strip() + lib_ext - except Exception, e: - self.PLCStatus = "Empty" - self.CurrentPLCFilename=None - - def _GetMD5FileName(self): - return os.path.join(self.workingdir, "lasttransferedPLC.md5") - - def _GetLibFileName(self): - return os.path.join(self.workingdir,self.CurrentPLCFilename) - - - def _LoadNewPLC(self): - """ - Load PLC library - Declare all functions, arguments and return values - """ - print "Load PLC" - try: - self._PLClibraryHandle = dlopen(self._GetLibFileName()) - self.PLClibraryHandle = ctypes.CDLL(self.CurrentPLCFilename, handle=self._PLClibraryHandle) - - self._startPLC = self.PLClibraryHandle.startPLC - self._startPLC.restype = ctypes.c_int - self._startPLC.argtypes = [ctypes.c_int, ctypes.POINTER(ctypes.c_char_p)] - - self._stopPLC = self.PLClibraryHandle.stopPLC - self._stopPLC.restype = None - - self._ResetDebugVariables = self.PLClibraryHandle.ResetDebugVariables - self._ResetDebugVariables.restype = None - - self._RegisterDebugVariable = self.PLClibraryHandle.ResetDebugVariables - self._RegisterDebugVariable.restype = None - - self._IterDebugData = self.PLClibraryHandle.IterDebugData - self._IterDebugData.restype = ctypes.c_void_p - self._IterDebugData.argtypes = [ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.c_char_p)] - - self._FreeDebugData = self.PLClibraryHandle.FreeDebugData - self._FreeDebugData.restype = None - - self._WaitDebugData = self.PLClibraryHandle.WaitDebugData - self._WaitDebugData.restype = ctypes.c_int - return True - except: - print traceback.format_exc() - return False - - def _FreePLC(self): - """ - Unload PLC library. - This is also called by __init__ to create dummy C func proxies - """ - # Forget all refs to library - self._startPLC = lambda:None - self._stopPLC = lambda:None - self._ResetDebugVariables = lambda:None - self._RegisterDebugVariable = lambda x:None - self._IterDebugData = lambda x,y:None - self._FreeDebugData = lambda:None - self.PLClibraryHandle = None - # Unload library explicitely - if getattr(self,"_PLClibraryHandle",None) is not None: - print "Unload PLC" - dlclose(self._PLClibraryHandle) - res = self._DetectDirtyLibs() - else: - res = False - - self._PLClibraryHandle = None - - return res - - def _DetectDirtyLibs(self): - # Detect dirty libs - # Get lib dependencies (for dirty lib detection) - if os.name == "posix": - # parasiting libs listed with ldd - badlibs = [ toks.split()[0] for toks in commands.getoutput( - "ldd "+self._GetLibFileName()).splitlines() ] - for badlib in badlibs: - if badlib[:6] in ["libwx_", - "libwxs", - "libgtk", - "libgdk", - "libatk", - "libpan", - "libX11", - ]: - #badhandle = dlopen(badlib, dl.RTLD_NOLOAD) - print "Dirty lib detected :" + badlib - #dlclose(badhandle) - return True - return False - - - def StartPLC(self): - print "StartPLC" - if self.CurrentPLCFilename is not None and self.PLCStatus == "Stopped": - c_argv = ctypes.c_char_p * len(self.argv) - if self._LoadNewPLC() and self._startPLC(len(self.argv),c_argv(*self.argv)) == 0: - self.PLCStatus = "Started" - return True - else: - print "_StartPLC did not return 0 !" - self._DoStopPLC() - return False - - def _DoStopPLC(self): - self._stopPLC() - self.PLCStatus = "Stopped" - if self._FreePLC(): - self.PLCStatus = "Dirty" - return True - - def StopPLC(self): - if self.PLCStatus == "Started": - self._DoStopPLC() - return True - return False - - def _Reload(self): - self.daemon.shutdown(True) - self.daemon.sock.close() - os.execv(sys.executable,[sys.executable]+sys.argv[:]) - # never reached - return 0 - - def ForceReload(self): - # respawn python interpreter - Timer(0.1,self._Reload).start() - return True - - def GetPLCstatus(self): - return self.PLCStatus - - def NewPLC(self, md5sum, data, extrafiles): - print "NewPLC (%s)"%md5sum - if self.PLCStatus in ["Stopped", "Empty", "Dirty"]: - NewFileName = md5sum + lib_ext - extra_files_log = os.path.join(self.workingdir,"extra_files.txt") - try: - os.remove(os.path.join(self.workingdir, - self.CurrentPLCFilename)) - for filename in file(extra_files_log, "r").readlines() + extra_files_log: - try: - os.remove(os.path.join(self.workingdir, filename)) - except: - pass - except: - pass - - try: - # Create new PLC file - open(os.path.join(self.workingdir,NewFileName), - 'wb').write(data) - - # Store new PLC filename based on md5 key - open(self._GetMD5FileName(), "w").write(md5sum) - - # Then write the files - log = file(extra_files_log, "w") - for fname,fdata in extrafiles: - fpath = os.path.join(self.workingdir,fname) - open(fpath, "wb").write(fdata) - log.write(fname+'\n') - - # Store new PLC filename - self.CurrentPLCFilename = NewFileName - except: - print traceback.format_exc() - return False - if self.PLCStatus == "Empty": - self.PLCStatus = "Stopped" - return True - return False - - def MatchMD5(self, MD5): - try: - last_md5 = open(self._GetMD5FileName(), "r").read() - return last_md5 == MD5 - except: - return False - - def SetTraceVariablesList(self, idxs): - """ - Call ctype imported function to append - these indexes to registred variables in PLC debugger - """ - # keep a copy of requested idx - self._Idxs = idxs[:] - self._ResetDebugVariables() - for idx in idxs: - self._RegisterDebugVariable(idx) - - TypeTranslator = {"BOOL" : ctypes.c_uint8, - "STEP" : ctypes.c_uint8, - "TRANSITION" : ctypes.c_uint8, - "ACTION" : ctypes.c_uint8, - "SINT" : ctypes.c_int8, - "USINT" : ctypes.c_uint8, - "BYTE" : ctypes.c_uint8, - "STRING" : None, #TODO - "INT" : ctypes.c_int16, - "UINT" : ctypes.c_uint16, - "WORD" : ctypes.c_uint16, - "WSTRING" : None, #TODO - "DINT" : ctypes.c_int32, - "UDINT" : ctypes.c_uint32, - "DWORD" : ctypes.c_uint32, - "LINT" : ctypes.c_int64, - "ULINT" : ctypes.c_uint64, - "LWORD" : ctypes.c_uint64, - "REAL" : ctypes.c_float, - "LREAL" : ctypes.c_double, - } - - def GetTraceVariables(self): - """ - Return a list of variables, corresponding to the list of requiered idx - """ - tick = self._WaitDebugData() - idx = ctypes.c_int() - typename = ctypes.c_char_p() - res = [] - - for idx in self._Idxs: - buffer=self._IterDebugData(ctypes.byref(idx), ctypes.byref(typename)) - c_type = TypeTranslator.get(s.value, None) - if c_type is not None: - res += cast(buffer, POINTER(c_type)).value - else: - res += None - self._FreeDebugData() - return res - - - +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +#This file is part of Beremiz, a Integrated Development Environment for +#programming IEC 61131-3 automates supporting plcopen standard and CanFestival. +# +#Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD +# +#See COPYING file for copyrights details. +# +#This library is free software; you can redistribute it and/or +#modify it under the terms of the GNU General Public +#License as published by the Free Software Foundation; either +#version 2.1 of the License, or (at your option) any later version. +# +#This library is distributed in the hope that it will be useful, +#but WITHOUT ANY WARRANTY; without even the implied warranty of +#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +#General Public License for more details. +# +#You should have received a copy of the GNU General Public +#License along with this library; if not, write to the Free Software +#Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +import Pyro.core as pyro +from threading import Timer +import ctypes, os, commands + +if os.name in ("nt", "ce"): + from _ctypes import LoadLibrary as dlopen + from _ctypes import FreeLibrary as dlclose +elif os.name == "posix": + from _ctypes import dlopen, dlclose + +import os,sys,traceback + +lib_ext ={ + "linux2":".so", + "win32":".dll", + }.get(sys.platform, "") + +class PLCObject(pyro.ObjBase): + def __init__(self, workingdir, daemon, argv): + pyro.ObjBase.__init__(self) + self.argv = [workingdir] + argv # force argv[0] to be "path" to exec... + self.workingdir = workingdir + self.PLCStatus = "Stopped" + self.PLClibraryHandle = None + # Creates fake C funcs proxies + self._FreePLC() + self.daemon = daemon + + # Get the last transfered PLC if connector must be restart + try: + self.CurrentPLCFilename=open( + self._GetMD5FileName(), + "r").read().strip() + lib_ext + except Exception, e: + self.PLCStatus = "Empty" + self.CurrentPLCFilename=None + + def _GetMD5FileName(self): + return os.path.join(self.workingdir, "lasttransferedPLC.md5") + + def _GetLibFileName(self): + return os.path.join(self.workingdir,self.CurrentPLCFilename) + + + def _LoadNewPLC(self): + """ + Load PLC library + Declare all functions, arguments and return values + """ + print "Load PLC" + try: + self._PLClibraryHandle = dlopen(self._GetLibFileName()) + self.PLClibraryHandle = ctypes.CDLL(self.CurrentPLCFilename, handle=self._PLClibraryHandle) + + self._startPLC = self.PLClibraryHandle.startPLC + self._startPLC.restype = ctypes.c_int + self._startPLC.argtypes = [ctypes.c_int, ctypes.POINTER(ctypes.c_char_p)] + + self._stopPLC = self.PLClibraryHandle.stopPLC + self._stopPLC.restype = None + + self._ResetDebugVariables = self.PLClibraryHandle.ResetDebugVariables + self._ResetDebugVariables.restype = None + + self._RegisterDebugVariable = self.PLClibraryHandle.ResetDebugVariables + self._RegisterDebugVariable.restype = None + + self._IterDebugData = self.PLClibraryHandle.IterDebugData + self._IterDebugData.restype = ctypes.c_void_p + self._IterDebugData.argtypes = [ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.c_char_p)] + + self._FreeDebugData = self.PLClibraryHandle.FreeDebugData + self._FreeDebugData.restype = None + + self._WaitDebugData = self.PLClibraryHandle.WaitDebugData + self._WaitDebugData.restype = ctypes.c_int + return True + except: + print traceback.format_exc() + return False + + def _FreePLC(self): + """ + Unload PLC library. + This is also called by __init__ to create dummy C func proxies + """ + # Forget all refs to library + self._startPLC = lambda:None + self._stopPLC = lambda:None + self._ResetDebugVariables = lambda:None + self._RegisterDebugVariable = lambda x:None + self._IterDebugData = lambda x,y:None + self._FreeDebugData = lambda:None + self.PLClibraryHandle = None + # Unload library explicitely + if getattr(self,"_PLClibraryHandle",None) is not None: + print "Unload PLC" + dlclose(self._PLClibraryHandle) + res = self._DetectDirtyLibs() + else: + res = False + + self._PLClibraryHandle = None + + return res + + def _DetectDirtyLibs(self): + # Detect dirty libs + # Get lib dependencies (for dirty lib detection) + if os.name == "posix": + # parasiting libs listed with ldd + badlibs = [ toks.split()[0] for toks in commands.getoutput( + "ldd "+self._GetLibFileName()).splitlines() ] + for badlib in badlibs: + if badlib[:6] in ["libwx_", + "libwxs", + "libgtk", + "libgdk", + "libatk", + "libpan", + "libX11", + ]: + #badhandle = dlopen(badlib, dl.RTLD_NOLOAD) + print "Dirty lib detected :" + badlib + #dlclose(badhandle) + return True + return False + + + def StartPLC(self): + print "StartPLC" + if self.CurrentPLCFilename is not None and self.PLCStatus == "Stopped": + c_argv = ctypes.c_char_p * len(self.argv) + if self._LoadNewPLC() and self._startPLC(len(self.argv),c_argv(*self.argv)) == 0: + self.PLCStatus = "Started" + return True + else: + print "_StartPLC did not return 0 !" + self._DoStopPLC() + return False + + def _DoStopPLC(self): + self._stopPLC() + self.PLCStatus = "Stopped" + if self._FreePLC(): + self.PLCStatus = "Dirty" + return True + + def StopPLC(self): + if self.PLCStatus == "Started": + self._DoStopPLC() + return True + return False + + def _Reload(self): + self.daemon.shutdown(True) + self.daemon.sock.close() + os.execv(sys.executable,[sys.executable]+sys.argv[:]) + # never reached + return 0 + + def ForceReload(self): + # respawn python interpreter + Timer(0.1,self._Reload).start() + return True + + def GetPLCstatus(self): + return self.PLCStatus + + def NewPLC(self, md5sum, data, extrafiles): + print "NewPLC (%s)"%md5sum + if self.PLCStatus in ["Stopped", "Empty", "Dirty"]: + NewFileName = md5sum + lib_ext + extra_files_log = os.path.join(self.workingdir,"extra_files.txt") + try: + os.remove(os.path.join(self.workingdir, + self.CurrentPLCFilename)) + for filename in file(extra_files_log, "r").readlines() + extra_files_log: + try: + os.remove(os.path.join(self.workingdir, filename)) + except: + pass + except: + pass + + try: + # Create new PLC file + open(os.path.join(self.workingdir,NewFileName), + 'wb').write(data) + + # Store new PLC filename based on md5 key + open(self._GetMD5FileName(), "w").write(md5sum) + + # Then write the files + log = file(extra_files_log, "w") + for fname,fdata in extrafiles: + fpath = os.path.join(self.workingdir,fname) + open(fpath, "wb").write(fdata) + log.write(fname+'\n') + + # Store new PLC filename + self.CurrentPLCFilename = NewFileName + except: + print traceback.format_exc() + return False + if self.PLCStatus == "Empty": + self.PLCStatus = "Stopped" + return True + return False + + def MatchMD5(self, MD5): + try: + last_md5 = open(self._GetMD5FileName(), "r").read() + return last_md5 == MD5 + except: + return False + + def SetTraceVariablesList(self, idxs): + """ + Call ctype imported function to append + these indexes to registred variables in PLC debugger + """ + # keep a copy of requested idx + self._Idxs = idxs[:] + self._ResetDebugVariables() + for idx in idxs: + self._RegisterDebugVariable(idx) + + TypeTranslator = {"BOOL" : ctypes.c_uint8, + "STEP" : ctypes.c_uint8, + "TRANSITION" : ctypes.c_uint8, + "ACTION" : ctypes.c_uint8, + "SINT" : ctypes.c_int8, + "USINT" : ctypes.c_uint8, + "BYTE" : ctypes.c_uint8, + "STRING" : None, #TODO + "INT" : ctypes.c_int16, + "UINT" : ctypes.c_uint16, + "WORD" : ctypes.c_uint16, + "WSTRING" : None, #TODO + "DINT" : ctypes.c_int32, + "UDINT" : ctypes.c_uint32, + "DWORD" : ctypes.c_uint32, + "LINT" : ctypes.c_int64, + "ULINT" : ctypes.c_uint64, + "LWORD" : ctypes.c_uint64, + "REAL" : ctypes.c_float, + "LREAL" : ctypes.c_double, + } + + def GetTraceVariables(self): + """ + Return a list of variables, corresponding to the list of requiered idx + """ + tick = self._WaitDebugData() + idx = ctypes.c_int() + typename = ctypes.c_char_p() + res = [] + + for idx in self._Idxs: + buffer=self._IterDebugData(ctypes.byref(idx), ctypes.byref(typename)) + c_type = TypeTranslator.get(s.value, None) + if c_type is not None: + res += cast(buffer, POINTER(c_type)).value + else: + res += None + self._FreeDebugData() + return res + + + diff -r 848da15cf513 -r 8bc65076e290 targets/Linux/__init__.py --- a/targets/Linux/__init__.py Thu Aug 28 15:08:41 2008 +0200 +++ b/targets/Linux/__init__.py Thu Aug 28 16:34:48 2008 +0200 @@ -2,4 +2,4 @@ class Linux_target(toolchain_gcc): extension = ".so" - CustomLDFLAGS = ["-shared"] + CustomLDFLAGS = ["-shared", "-lrt"] diff -r 848da15cf513 -r 8bc65076e290 targets/Win32/plc_Win32_main.c --- a/targets/Win32/plc_Win32_main.c Thu Aug 28 15:08:41 2008 +0200 +++ b/targets/Win32/plc_Win32_main.c Thu Aug 28 16:34:48 2008 +0200 @@ -31,7 +31,7 @@ HANDLE PLC_timer = NULL; void PLC_SetTimer(long long next, long long period) { - LARGE_INTEGER liDueTime; + LARGE_INTEGER liDueTime; /* arg 2 of SetWaitableTimer take 100 ns interval*/ liDueTime.QuadPart = next / (-100); @@ -43,18 +43,45 @@ { printf("SetWaitableTimer failed (%d)\n", GetLastError()); } +} + +/* Variable used to stop plcloop thread */ +int runplcloop; +void PlcLoop() +{ + runplcloop = 1; + while(runplcloop) + { + // Set a timer + PLC_SetTimer(Ttick,Ttick); if (WaitForSingleObject(PLC_timer, INFINITE) != WAIT_OBJECT_0) { printf("WaitForSingleObject failed (%d)\n", GetLastError()); } PLC_timer_notify(); + } } -int main(int argc,char **argv) +HANDLE DebugLock; +HANDLE PLC_thread; + +int startPLC(int argc,char **argv) { + unsigned long thread_id = 0; /* Translate PLC's microseconds to Ttick nanoseconds */ Ttick = 1000000 * maxval(common_ticktime__,1); + DebugLock = CreateMutex( + NULL, // default security attributes + FALSE, // initially not owned + NULL); // unnamed mutex + + if (DebugLock == NULL) + { + printf("CreateMutex error: %d\n", GetLastError()); + return; + } + /* Create a waitable timer */ PLC_timer = CreateWaitableTimer(NULL, FALSE, "WaitableTimer"); if(NULL == PLC_timer) @@ -62,24 +89,40 @@ printf("CreateWaitableTimer failed (%d)\n", GetLastError()); return 1; } - if( __init(argc,argv) == 0 ) { printf("Tick Time : %d ms\n", common_ticktime__); - while(1) - { - // Set a timer - PLC_SetTimer(Ttick,Ttick); - if (kbhit()) - { - printf("Finishing\n"); - break; - } - } - PLC_SetTimer(0,0); + PLC_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)PlcLoop, NULL, 0, &thread_id); } - __cleanup(); - CloseHandle(PLC_timer); - + else{ + return 1; + } return 0; } + +int stopPLC() +{ + runplcloop = 0; + WaitForSingleObject(PLC_thread, INFINITE); + CloseHandle(PLC_thread); + CloseHandle(DebugLock); + CloseHandle(PLC_timer); + __cleanup(); +} + +/* from plc_debugger.c */ +void WaitDebugData() +{ + DWORD dwWaitResult; + dwWaitResult = WaitForSingleObject( + DebugLock, // handle to mutex + INFINITE); // no time-out interval +} + +/* Called by PLC thread when debug_publish finished + * This is supposed to unlock debugger thread in WaitDebugData*/ +void InitiateDebugTransfer() +{ + /* signal debugger thread to continue*/ + ReleaseMutex(DebugLock); +}