diff -r 291a17b755d1 -r e15ca67197b9 py_ext/PythonFileCTNMixin.py --- a/py_ext/PythonFileCTNMixin.py Mon Feb 02 16:51:35 2015 +0100 +++ b/py_ext/PythonFileCTNMixin.py Mon Feb 02 23:11:01 2015 +0100 @@ -7,7 +7,7 @@ from PythonEditor import PythonEditor class PythonFileCTNMixin(CodeFile): - + CODEFILE_NAME = "PyFile" SECTIONS_NAMES = [ "globals", @@ -16,45 +16,45 @@ "start", "stop"] EditorType = PythonEditor - + def __init__(self): CodeFile.__init__(self) - + filepath = self.PythonFileName() - + if os.path.isfile(filepath): PythonParser = GenerateParserFromXSD( - os.path.join(os.path.dirname(__file__), "py_ext_xsd.xsd")) - + os.path.join(os.path.dirname(__file__), "py_ext_xsd.xsd")) + xmlfile = open(filepath, 'r') pythonfile_xml = xmlfile.read() xmlfile.close() - + pythonfile_xml = pythonfile_xml.replace( - 'xmlns="http://www.w3.org/2001/XMLSchema"', + 'xmlns="http://www.w3.org/2001/XMLSchema"', 'xmlns:xhtml="http://www.w3.org/1999/xhtml"') for cre, repl in [ (re.compile("(?)(?:)(?!)"), "]]>")]: pythonfile_xml = cre.sub(repl, pythonfile_xml) - + try: python_code, error = PythonParser.LoadXMLString(pythonfile_xml) - if error is None: + if error is None: self.CodeFile.globals.setanyText(python_code.getanyText()) os.remove(filepath) self.CreateCodeFileBuffer(False) self.OnCTNSave() except Exception, exc: error = unicode(exc) - + if error is not None: self.GetCTRoot().logger.write_error( - _("Couldn't import old %s file.") % CTNName) - + _("Couldn't import old %s file.") % self.CTNName()) + def CodeFileName(self): return os.path.join(self.CTNPath(), "pyfile.xml") - + def PythonFileName(self): return os.path.join(self.CTNPath(), "py_ext.xml") @@ -64,25 +64,26 @@ return self.PreSectionsTexts.get(section,"") + "\n" + \ getattr(self.CodeFile, section).getanyText() + "\n" + \ self.PostSectionsTexts.get(section,"") - + def CTNGenerate_C(self, buildpath, locations): - # location string for that CTN - location_str = "_".join(map(lambda x:str(x), + # location string for that CTN + location_str = "_".join(map(lambda x:str(x), self.GetCurrentLocation())) configname = self.GetCTRoot().GetProjectConfigNames()[0] - - + + # python side PLC global variables access stub globalstubs = "\n".join(["""\ _%(name)s_ctype, _%(name)s_unpack, _%(name)s_pack = \\ TypeTranslator["%(IECtype)s"] _PySafeGetPLCGlob_%(name)s = PLCBinary.__SafeGetPLCGlob_%(name)s _PySafeGetPLCGlob_%(name)s.restype = None -_PySafeGetPLCGlob_%(name)s.argtypes = [ctypes.POINTER(_%(name)s_ctype)] +_PySafeGetPLCGlob_%(name)s.argtypes = [ctypes.POINTER(_%(name)s_ctype)] _PySafeSetPLCGlob_%(name)s = PLCBinary.__SafeSetPLCGlob_%(name)s _PySafeSetPLCGlob_%(name)s.restype = None _PySafeSetPLCGlob_%(name)s.argtypes = [ctypes.POINTER(_%(name)s_ctype)] +_PySafePLCGlobals.append(("%(name)s","%(IECtype)s")) """ % { "name": variable.getname(), "configname": configname.upper(), "uppername": variable.getname().upper(), @@ -101,19 +102,23 @@ else: rtcalls += " pass\n\n" - globalsection = self.GetSection("globals") + globalsection = self.GetSection("globals") + + pyextname = self.CTNName() PyFileContent = """\ #!/usr/bin/env python # -*- coding: utf-8 -*- ## Code generated by Beremiz python mixin confnode -## - +## + ## Code for PLC global variable access from targets.typemapping import TypeTranslator -import ctypes +import ctypes +_PyExtName = "%(pyextname)s" +_PySafePLCGlobals = [] %(globalstubs)s - + ## User code in "global" scope %(globalsection)s @@ -123,14 +128,14 @@ """ % locals() # write generated content to python file - runtimefile_path = os.path.join(buildpath, + runtimefile_path = os.path.join(buildpath, "runtime_%s.py"%location_str) runtimefile = open(runtimefile_path, 'w') runtimefile.write(PyFileContent.encode('utf-8')) runtimefile.close() # C code for safe global variables access - + vardecfmt = """\ extern __IEC_%(IECtype)s_t %(configname)s__%(uppername)s; IEC_%(IECtype)s __%(name)s_rbuffer = __INIT_%(IECtype)s; @@ -159,13 +164,13 @@ } AtomicCompareExchange((long*)&__%(name)s_wlock, 1, 0); } -""" +""" varpubfmt = """\ if(!AtomicCompareExchange(&__%(name)s_rlock, 0, 1)){ __%(name)s_rbuffer = %(configname)s__%(uppername)s.value; AtomicCompareExchange((long*)&__%(name)s_rlock, 1, 0); } -""" +""" var_str = map("\n".join, zip(*[ map(lambda f : f % varinfo, @@ -180,10 +185,10 @@ vardec, varret, varpub = var_str else: vardec = varret = varpub = "" - + PyCFileContent = """\ -/* - * Code generated by Beremiz py_ext confnode +/* + * Code generated by Beremiz py_ext confnode * for safe global variables access */ #include "iec_types_all.h" @@ -208,15 +213,15 @@ %(varpub)s } """ % locals() - + Gen_PyCfile_path = os.path.join(buildpath, "PyCFile_%s.c"%location_str) pycfile = open(Gen_PyCfile_path,'w') pycfile.write(PyCFileContent) pycfile.close() - + matiec_flags = '"-I%s"'%os.path.abspath( self.GetCTRoot().GetIECLibPath()) - + return ([(Gen_PyCfile_path, matiec_flags)], "", True,