py_ext/PythonFileCTNMixin.py
changeset 1448 20ff66dcc31d
parent 1447 d6b878525ceb
child 1449 5f09fa31d7b0
equal deleted inserted replaced
1447:d6b878525ceb 1448:20ff66dcc31d
    63     def GetSection(self,section):
    63     def GetSection(self,section):
    64         return self.PreSectionsTexts.get(section,"") + "\n" + \
    64         return self.PreSectionsTexts.get(section,"") + "\n" + \
    65                getattr(self.CodeFile, section).getanyText() + "\n" + \
    65                getattr(self.CodeFile, section).getanyText() + "\n" + \
    66                self.PostSectionsTexts.get(section,"")
    66                self.PostSectionsTexts.get(section,"")
    67 
    67 
    68 
       
    69     def CTNGenerate_C(self, buildpath, locations):
    68     def CTNGenerate_C(self, buildpath, locations):
    70         # location string for that CTN
    69         # location string for that CTN
    71         location_str = "_".join(map(lambda x:str(x),
    70         location_str = "_".join(map(lambda x:str(x),
    72                                 self.GetCurrentLocation()))
    71                                 self.GetCurrentLocation()))
    73         configname = self.GetCTRoot().GetProjectConfigNames()[0]
    72         configname = self.GetCTRoot().GetProjectConfigNames()[0]
    74 
    73 
    75         pyextname = self.CTNName()
    74         pyextname = self.CTNName()
    76 
    75         varinfos = map(lambda variable : {
       
    76                     "name": variable.getname(),
       
    77                     "desc" : repr(variable.getdesc()),   
       
    78                     "onchange" : '"'+variable.getonchange()+"('"+variable.getname()+"')\"" \
       
    79                                  if variable.getonchange() else "",
       
    80                     "opts" : repr(variable.getopts()),
       
    81                     "configname" : configname.upper(),
       
    82                     "uppername" : variable.getname().upper(),
       
    83                     "IECtype" : variable.gettype(),
       
    84                     "pyextname" :pyextname},
       
    85                     self.CodeFile.variables.variable)
    77         # python side PLC global variables access stub
    86         # python side PLC global variables access stub
    78         globalstubs = "\n".join(["""\
    87         globalstubs = "\n".join(["""\
    79 _%(name)s_ctype, _%(name)s_unpack, _%(name)s_pack = \\
    88 _%(name)s_ctype, _%(name)s_unpack, _%(name)s_pack = \\
    80     TypeTranslator["%(IECtype)s"]
    89     TypeTranslator["%(IECtype)s"]
    81 _PySafeGetPLCGlob_%(name)s = PLCBinary.__SafeGetPLCGlob_%(name)s
    90 _PySafeGetPLCGlob_%(name)s = PLCBinary.__SafeGetPLCGlob_%(name)s
    82 _PySafeGetPLCGlob_%(name)s.restype = None
    91 _PySafeGetPLCGlob_%(name)s.restype = None
    83 _PySafeGetPLCGlob_%(name)s.argtypes = [ctypes.POINTER(_%(name)s_ctype)]
    92 _PySafeGetPLCGlob_%(name)s.argtypes = [ctypes.POINTER(_%(name)s_ctype)]
    84 _PySafeSetPLCGlob_%(name)s = PLCBinary.__SafeSetPLCGlob_%(name)s
    93 _PySafeSetPLCGlob_%(name)s = PLCBinary.__SafeSetPLCGlob_%(name)s
    85 _PySafeSetPLCGlob_%(name)s.restype = None
    94 _PySafeSetPLCGlob_%(name)s.restype = None
    86 _PySafeSetPLCGlob_%(name)s.argtypes = [ctypes.POINTER(_%(name)s_ctype)]
    95 _PySafeSetPLCGlob_%(name)s.argtypes = [ctypes.POINTER(_%(name)s_ctype)]
    87 _%(pyextname)sGlobalsDesc.append(("%(name)s","%(IECtype)s"))
    96 _%(pyextname)sGlobalsDesc.append((
    88 """ % { "name": variable.getname(),
    97     "%(name)s",
    89         "configname": configname.upper(),
    98     "%(IECtype)s",
    90         "uppername": variable.getname().upper(),
    99     %(desc)s,
    91         "IECtype": variable.gettype(),
   100     %(opts)s))
    92         "pyextname":pyextname}
   101 """ % varinfo for varinfo in varinfos])
    93             for variable in self.CodeFile.variables.variable])
       
    94 
   102 
    95         # Runtime calls (start, stop, init, and cleanup)
   103         # Runtime calls (start, stop, init, and cleanup)
    96         rtcalls = ""
   104         rtcalls = ""
    97         for section in self.SECTIONS_NAMES:
   105         for section in self.SECTIONS_NAMES:
    98             if section != "globals":
   106             if section != "globals":
   154     __%(name)s_wbuffer_written = 1;
   162     __%(name)s_wbuffer_written = 1;
   155     AtomicCompareExchange((long*)&__%(name)s_wlock, 1, 0);
   163     AtomicCompareExchange((long*)&__%(name)s_wlock, 1, 0);
   156 }
   164 }
   157 
   165 
   158 """
   166 """
       
   167 
       
   168         vardeconchangefmt = """\
       
   169 PYTHON_POLL* __%(name)s_notifier;
       
   170 """
       
   171 
   159         varretfmt = """\
   172         varretfmt = """\
   160     if(!AtomicCompareExchange(&__%(name)s_wlock, 0, 1)){
   173     if(!AtomicCompareExchange(&__%(name)s_wlock, 0, 1)){
   161         if(__%(name)s_wbuffer_written == 1){
   174         if(__%(name)s_wbuffer_written == 1){
   162             %(configname)s__%(uppername)s.value = __%(name)s_wbuffer;
   175             %(configname)s__%(uppername)s.value = __%(name)s_wbuffer;
   163             __%(name)s_wbuffer_written = 0;
   176             __%(name)s_wbuffer_written = 0;
   165         AtomicCompareExchange((long*)&__%(name)s_wlock, 1, 0);
   178         AtomicCompareExchange((long*)&__%(name)s_wlock, 1, 0);
   166     }
   179     }
   167 """
   180 """
   168         varpubfmt = """\
   181         varpubfmt = """\
   169     if(!AtomicCompareExchange(&__%(name)s_rlock, 0, 1)){
   182     if(!AtomicCompareExchange(&__%(name)s_rlock, 0, 1)){
   170         __%(name)s_rbuffer = %(configname)s__%(uppername)s.value;
   183         __%(name)s_rbuffer = __GET_VAR(%(configname)s__%(uppername)s);
   171         AtomicCompareExchange((long*)&__%(name)s_rlock, 1, 0);
   184         AtomicCompareExchange((long*)&__%(name)s_rlock, 1, 0);
   172     }
   185     }
   173 """
   186 """
   174 
   187 
   175         var_str = map("\n".join, zip(*[
   188         varpubonchangefmt = """\
   176             map(lambda f : f % varinfo,
   189     if(!AtomicCompareExchange(&__%(name)s_rlock, 0, 1)){
   177                 (vardecfmt, varretfmt, varpubfmt))
   190         IEC_%(IECtype)s tmp = __GET_VAR(%(configname)s__%(uppername)s);
   178                 for varinfo in map(lambda variable : {
   191         if(__%(name)s_rbuffer != tmp){
   179                     "name": variable.getname(),
   192             __%(name)s_rbuffer = %(configname)s__%(uppername)s.value;
   180                     "configname": configname.upper(),
   193             PYTHON_POLL_body__(__%(name)s_notifier);
   181                     "uppername": variable.getname().upper(),
   194         }
   182                     "IECtype": variable.gettype()},
   195         AtomicCompareExchange((long*)&__%(name)s_rlock, 1, 0);
   183                     self.CodeFile.variables.variable)]))
   196     }
   184         if len(var_str) > 0:
   197 """
   185             vardec, varret, varpub = var_str
   198         varinitonchangefmt = """\
   186         else:
   199     __%(name)s_notifier = __GET_GLOBAL_ON%(uppername)sCHANGE();
   187             vardec = varret = varpub = ""
   200     __SET_VAR(__%(name)s_notifier->,TRIG,,__BOOL_LITERAL(TRUE));
       
   201     __SET_VAR(__%(name)s_notifier->,CODE,,__STRING_LITERAL(%(onchangelen)d,%(onchange)s));
       
   202 """
       
   203         vardec = "\n".join([(vardecfmt + vardeconchangefmt 
       
   204                              if varinfo["onchange"] else vardecfmt)% varinfo 
       
   205                             for varinfo in varinfos])
       
   206         varret = "\n".join([varretfmt % varinfo for varinfo in varinfos])
       
   207         varpub = "\n".join([(varpubonchangefmt if varinfo["onchange"] else
       
   208                              varpubfmt) % varinfo
       
   209                             for varinfo in varinfos])
       
   210         varinit = "\n".join([varinitonchangefmt % dict(
       
   211                                 onchangelen = len(varinfo["onchange"]),**varinfo)
       
   212                             for varinfo in varinfos if varinfo["onchange"]])
   188 
   213 
   189         PyCFileContent = """\
   214         PyCFileContent = """\
   190 /*
   215 /*
   191  * Code generated by Beremiz py_ext confnode
   216  * Code generated by Beremiz py_ext confnode
   192  * for safe global variables access
   217  * for safe global variables access
   193  */
   218  */
   194 #include "iec_types_all.h"
   219 #include "iec_types_all.h"
       
   220 #include "POUS.h"
       
   221 #include "config.h"
   195 #include "beremiz.h"
   222 #include "beremiz.h"
   196 
   223 
   197 /* User variables reference */
   224 /* User variables reference */
   198 %(vardec)s
   225 %(vardec)s
   199 
   226 
   200 /* Beremiz confnode functions */
   227 /* Beremiz confnode functions */
   201 int __init_%(location_str)s(int argc,char **argv){
   228 int __init_%(location_str)s(int argc,char **argv){
       
   229 %(varinit)s
   202     return 0;
   230     return 0;
   203 }
   231 }
   204 
   232 
   205 void __cleanup_%(location_str)s(void){
   233 void __cleanup_%(location_str)s(void){
   206 }
   234 }