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 } |