Merged
authorLaurent Bessard
Tue, 14 May 2013 18:43:52 +0200
changeset 1137 c37f8d379ab0
parent 1136 5fac491d3a0e (current diff)
parent 1132 28f96aa9c070 (diff)
child 1138 cf2a6a7c87e8
Merged
--- a/py_ext/PythonFileCTNMixin.py	Tue May 14 18:42:29 2013 +0200
+++ b/py_ext/PythonFileCTNMixin.py	Tue May 14 18:43:52 2013 +0200
@@ -46,7 +46,19 @@
     def PythonFileName(self):
         return os.path.join(self.CTNPath(), "py_ext.xml")
 
-    def GetSectionsCode(self):
+    PreSectionsTexts = {}
+    PostSectionsTexts = {}
+    def GetSection(self,section):
+        return self.PreSectionsTexts.get(section,"") + "\n" + \
+               getattr(self.CodeFile, section).gettext() + "\n" + \
+               self.PostSectionsTexts.get(section,"")
+        
+
+    def CTNGenerate_C(self, buildpath, locations):
+        current_location = self.GetCurrentLocation()
+        # define a unique name for the generated C file
+        location_str = "_".join(map(lambda x:str(x), current_location))
+        
         
         # Generate Beremiz python runtime variables code
         config = self.GetCTRoot().GetProjectConfigNames()[0]
@@ -58,23 +70,95 @@
                 variable.getname(),
                 variable.gettype(),
                 str(variable.getinitial()))
-        
-        sections_code = {
-            "variables": variables_str,
-            "globals": self.CodeFile.globals.gettext().strip()
-        }
-        
-        # Generate Beremiz python runtime functions code
+
+        # Runtime calls (start, stop, init, and cleanup)
+        rtcalls = ""
         for section in self.SECTIONS_NAMES:
             if section != "globals":
-                code_object = getattr(self.CodeFile, section)
-                section_str = ""
-                lines = code_object.gettext().strip().splitlines()
-                if len(lines) > 0:
-                    for line in lines:
-                        section_str += "    " + line + "\n"
-                    section_str += "\n"
-                sections_code[section] = section_str
-            
-        return sections_code
+                rtcalls += "def _runtime_%s_%s():\n" % (location_str, section)
+                sectiontext = self.GetSection(section).strip()
+                if sectiontext:
+                    rtcalls += '    ' + \
+                        sectiontext.strip().replace('\n', '\n    ')+"\n"
+                else:
+                    rtcalls += "    pass\n\n"
+        
+        text = """\
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+## Code generated by Beremiz python mixin confnode
+##        
+        
+## Code for PLC global variable access
+%s
+        
+## User code in "global" scope
+%s
 
+## Beremiz python runtime calls
+%s
+
+"""%(   # variables
+        variables_str,
+        # globals
+        self.GetSection("globals"),
+        # Beremiz python runtime functions
+        rtcalls)
+
+        runtimefile_path = os.path.join(buildpath, 
+            "runtime_%s.py"%location_str)
+        runtimefile = open(runtimefile_path, 'w')
+        runtimefile.write(text.encode('utf-8'))
+        runtimefile.close()
+
+        text = """\
+/* 
+ * Code generated by Beremiz py_ext confnode 
+ * for safe global variables access
+ */
+#include "iec_types_all.h"
+"""
+        
+        # Adding variables
+        text += "/* User variables reference */\n"
+        for variable in self.CodeFile.variables.variable:
+            var_infos = {
+                "name": variable.getname(),
+                "global": "%s__%s" % (config.upper(),
+                                      variable.getname().upper()),
+                "type": "__IEC_%s_t" % variable.gettype()}
+            text += "extern %(type)s %(global)s;\n" % var_infos
+            text += "%(type)s __buffer_%(name)s;\n" % var_infos
+        text += "\n"
+        
+        # Adding Beremiz confnode functions
+        text += "/* Beremiz confnode functions */\n"
+        text += "int __init_%s(int argc,char **argv)\n{\n"%location_str
+        text += "/*TODO*/\n"
+        text += "  return 0;\n}\n\n"
+        
+        text += "void __cleanup_%s(void)\n{\n"%location_str
+        text += "/*TODO*/\n"
+        text += "\n}\n\n"
+        
+        text += "void __retrieve_%s(void)\n{\n"%location_str
+        text += "/*TODO*/\n"
+        text += "\n}\n\n"
+        
+        text += "void __publish_%s(void)\n{\n"%location_str
+        text += "/*TODO*/\n"
+        text += "\n}\n\n"
+        
+        Gen_PyCfile_path = os.path.join(buildpath, "PyCFile_%s.c"%location_str)
+        pycfile = open(Gen_PyCfile_path,'w')
+        pycfile.write(text)
+        pycfile.close()
+        
+        matiec_flags = '"-I%s"'%os.path.abspath(
+            self.GetCTRoot().GetIECLibPath())
+        
+        return ([(Gen_PyCfile_path, matiec_flags)],
+                "",
+                False,
+                ("runtime_%s.py"%location_str, file(runtimefile_path,"rb")))
+
--- a/py_ext/py_ext.py	Tue May 14 18:42:29 2013 +0200
+++ b/py_ext/py_ext.py	Tue May 14 18:43:52 2013 +0200
@@ -8,18 +8,21 @@
 
     def Generate_C(self, buildpath, varlist, IECCFLAGS):
         
-        plc_python_filepath = os.path.join(os.path.split(__file__)[0], "plc_python.c")
+        plc_python_filepath = os.path.join(
+            os.path.split(__file__)[0], "plc_python.c")
         plc_python_file = open(plc_python_filepath, 'r')
         plc_python_code = plc_python_file.read()
         plc_python_file.close()
         python_eval_fb_list = []
         for v in varlist:
-            if v["vartype"] == "FB" and v["type"] in ["PYTHON_EVAL","PYTHON_POLL"]:
+            if v["vartype"] == "FB" and v["type"] in ["PYTHON_EVAL",
+                                                      "PYTHON_POLL"]:
                 python_eval_fb_list.append(v)
         python_eval_fb_count = max(1, len(python_eval_fb_list))
         
         # prepare python code
-        plc_python_code = plc_python_code % { "python_eval_fb_count": python_eval_fb_count }
+        plc_python_code = plc_python_code % {
+            "python_eval_fb_count": python_eval_fb_count }
         
         Gen_Pythonfile_path = os.path.join(buildpath, "py_ext.c")
         pythonfile = open(Gen_Pythonfile_path,'w')
@@ -33,41 +36,4 @@
     def GetIconName(self):
         return "Pyfile"
     
-    def CTNGenerate_C(self, buildpath, locations):
-        current_location = self.GetCurrentLocation()
-        # define a unique name for the generated C file
-        location_str = "_".join(map(lambda x:str(x), current_location))
-        
-        sections_code = self.GetSectionsCode()
-        
-        text = "## Code generated by Beremiz python mixin confnode\n\n"
-        
-        # Adding variables
-        text += "## User variables reference\n"
-        text += sections_code["variables"]
-        text += "\n"
-        
-        # Adding user global variables and routines
-        text += "## User internal user variables and routines\n"
-        text += sections_code["globals"]
-        text += "\n"
-        
-        # Adding Beremiz python runtime functions
-        text += "## Beremiz python runtime functions\n"
-        for section in self.SECTIONS_NAMES:
-            if section != "globals":
-                code_object = getattr(self.CodeFile, section)
-                text += "def _runtime_%s_%s():\n" % (location_str, section)
-                section_code = sections_code.get(section)
-                if section_code:
-                    text += section_code
-                else:
-                    text += "    pass\n\n"
-        
-        runtimefile_path = os.path.join(buildpath, "runtime_%s.py"%location_str)
-        runtimefile = open(runtimefile_path, 'w')
-        runtimefile.write(text)
-        runtimefile.close()
-        
-        return [], "", False, ("runtime_%s.py"%location_str, file(runtimefile_path,"rb"))
 
--- a/runtime/PLCObject.py	Tue May 14 18:42:29 2013 +0200
+++ b/runtime/PLCObject.py	Tue May 14 18:43:52 2013 +0200
@@ -264,7 +264,6 @@
             self.python_runtime_vars["_runtime_%s"%methodname] = []
         self.python_runtime_vars["PLCObject"] = self
         self.python_runtime_vars["PLCBinary"] = self.PLClibraryHandle
-        
         try:
             for filename in os.listdir(self.workingdir):
                 name, ext = os.path.splitext(filename)
@@ -274,7 +273,6 @@
                         method = self.python_runtime_vars.get("_%s_%s" % (name, methodname), None)
                         if method is not None:
                             self.python_runtime_vars["_runtime_%s"%methodname].append(method)
-            
         except:
             self.LogMessage(0,traceback.format_exc())
             raise
--- a/wxglade_hmi/wxglade_hmi.py	Tue May 14 18:42:29 2013 +0200
+++ b/wxglade_hmi/wxglade_hmi.py	Tue May 14 18:43:52 2013 +0200
@@ -38,19 +38,6 @@
         return PythonFileCTNMixin.OnCTNSave(self, from_project_path)
 
     def CTNGenerate_C(self, buildpath, locations):
-        """
-        Return C code generated by iec2c compiler 
-        when _generate_softPLC have been called
-        @param locations: ignored
-        @return: [(C_file_name, CFLAGS),...] , LDFLAGS_TO_APPEND
-        """
-        
-        current_location = self.GetCurrentLocation()
-        # define a unique name for the generated C file
-        location_str = "_".join(map(lambda x:str(x), current_location))
-        
-        runtimefile_path = os.path.join(buildpath, "runtime_%s.py"%location_str)
-        runtimefile = open(runtimefile_path, 'w')
         
         hmi_frames = {}
         
@@ -73,65 +60,32 @@
             self.launch_wxglade(['-o', wxghmipyfile_path, '-g', 'python', wxgfile_path], wait=True)
             
             hmipyfile = open(hmipyfile_path, 'r')
-            runtimefile.write(hmipyfile.read())
+            define_hmi = hmipyfile.read().decode('utf-8')
             hmipyfile.close()
         
-        sections_code = self.GetSectionsCode()
+        declare_hmi = "\n".join(map(lambda x:"%s = None" % x,
+                                hmi_frames.keys()))
+        global_hmi = "global "+",".join(hmi_frames.keys())
+        init_hmi = "\n".join(map(lambda x: """\
+def OnCloseFrame(evt):
+    wx.MessageBox(_("Please stop PLC to close"))
+
+%(name)s = %(class)s(None)
+%(name)s.Bind(wx.EVT_CLOSE, OnCloseFrame)
+%(name)s.Show()
+""" % {"name": x[0], "class": x[1]}, hmi_frames.items()))
+        cleanup_hmi = "\n".join(map(lambda x:"if %s is not None: %s.Destroy()" % (x,x), hmi_frames.keys()))
         
-        # Adding variables
-        runtimefile.write("## User variables reference\n" +
-                          sections_code["variables"] + "\n")
-        
-        # Adding user global variables and routines
-        runtimefile.write("## User internal user variables and routines\n" +
-                          sections_code["globals"] + "\n")
-        
-        for section in ["init", "cleanup"]:
-            if not sections_code[section]:
-                sections_code[section] = "    pass"
-        
-        sections_code.update({
-            "location": location_str,
-            "declare_hmi": "\n".join(map(lambda x:"%s = None" % x, hmi_frames.keys())),
-            "global_hmi": ",".join(hmi_frames.keys()),
-            "init_hmi": "\n".join(map(lambda x: """
-    %(name)s = %(class)s(None)
-    %(name)s.Bind(wx.EVT_CLOSE, OnCloseFrame)
-    %(name)s.Show()
-""" % {"name": x[0], "class": x[1]},
-                             hmi_frames.items())),
-            "cleanup_hmi": "\n    ".join(map(lambda x:"if %s is not None: %s.Destroy()" % (x,x), hmi_frames.keys()))})
-        
-        runtimefile.write("""
-%(declare_hmi)s
+        self.PreSectionsTexts = {
+            "globals":define_hmi + declare_hmi,
+            "start":global_hmi,
+            "stop":global_hmi
+        }
+        self.PostSectionsTexts = {
+            "start":init_hmi,
+        }
 
-def _runtime_%(location)s_init():
-%(init)s
-
-def _runtime_%(location)s_cleanup():
-%(cleanup)s
-
-def _runtime_%(location)s_start():
-    global %(global_hmi)s
-    
-%(start)s
-
-    def OnCloseFrame(evt):
-        wx.MessageBox(_("Please stop PLC to close"))
-    
-    %(init_hmi)s
-    
-def _runtime_%(location)s_stop():
-    global %(global_hmi)s
-    
-    %(cleanup_hmi)s
-
-%(stop)s
-
-""" % sections_code)
-        runtimefile.close()
-        
-        return [], "", False, ("runtime_%s.py"%location_str, file(runtimefile_path,"rb"))
+        return PythonFileCTNMixin.CTNGenerate_C(self, buildpath, locations)
 
     def _editWXGLADE(self):
         wxg_filename = self._getWXGLADEpath()