--- a/py_ext/PythonFileCTNMixin.py Wed May 15 08:20:17 2013 +0200
+++ b/py_ext/PythonFileCTNMixin.py Wed May 15 17:13:49 2013 +0900
@@ -55,21 +55,28 @@
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))
+ # location string for that CTN + location_str = "_".join(map(lambda x:str(x), + self.GetCurrentLocation())) + configname = self.GetCTRoot().GetProjectConfigNames()[0] - # Generate Beremiz python runtime variables code
- config = self.GetCTRoot().GetProjectConfigNames()[0]
- for variable in self.CodeFile.variables.variable:
- global_name = "%s_%s" % (config.upper(), variable.getname().upper())
- variables_str += "# global_var:%s python_var:%s type:%s initial:%s\n" % (
- str(variable.getinitial()))
+ # 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 = _%(name)s_ctype +_PySafeGetPLCGlob_%(name)s.argtypes = [] +_PySafeSetPLCGlob_%(name)s = PLCBinary.__SafeSetPLCGlob_%(name)s +_PySafeSetPLCGlob_%(name)s.restype = None +_PySafeSetPLCGlob_%(name)s.argtypes = [ctypes.POINTER(_%(name)s_ctype)] +""" % { "name": variable.getname(), + "configname": configname.upper(), + "uppername": variable.getname().upper(), + "IECtype": variable.gettype(), + "initial" : str(variable.getinitial())} + for variable in self.CodeFile.variables.variable]) # Runtime calls (start, stop, init, and cleanup)
@@ -82,76 +89,117 @@
sectiontext.strip().replace('\n', '\n ')+"\n"
+ globalsection = self.GetSection("globals") ## Code generated by Beremiz python mixin confnode
## Code for PLC global variable access
+from targets.typemapping import TypeTranslator ## User code in "global" scope
## Beremiz python runtime calls
- self.GetSection("globals"),
- # Beremiz python runtime functions
+ # write generated content to python file runtimefile_path = os.path.join(buildpath,
"runtime_%s.py"%location_str)
runtimefile = open(runtimefile_path, 'w')
- runtimefile.write(text.encode('utf-8'))
+ runtimefile.write(PyFileContent.encode('utf-8'))
+ # C code for safe global variables access +extern __%(IECtype)s_t %(configname)s__%(uppername)s; +%(IECtype)s __%(name)s_rbuffer = %(initial)s; +%(IECtype)s __%(name)s_wbuffer; +long __%(name)s_rlock = 0; +long __%(name)s_wlock = 0; +int __%(name)s_wbuffer_written = 0; +%(IECtype)s __SafeGetPLCGlob_%(name)s(){ + while(AtomicCompareExchange(&__%(name)s_rlock, 0, 1)); + res = __%(name)s_rbuffer; + AtomicCompareExchange((long*)&__%(name)s_rlock, 1, 0); +__SafeSetPLCGlob_%(name)s(%(IECtype)s *value){ + while(AtomicCompareExchange(&__%(name)s_wlock, 0, 1)); + __%(name)s_wbuffer = *value; + __%(name)s_wbuffer_written = 1; + AtomicCompareExchange((long*)&__%(name)s_wlock, 1, 0); + if(!AtomicCompareExchange(&__%(name)s_wlock, 0, 1)){ + if(__%(name)s_wbuffer_written == 1){ + %(configname)s__%(uppername)s.value = __%(name)s_wbuffer; + __%(name)s_wbuffer_written = 0; + AtomicCompareExchange((long*)&__%(name)s_wlock, 1, 0); + if(!AtomicCompareExchange(&__%(name)s_rlock, 0, 1)){ + __%(name)s_rbuffer = %(configname)s__%(uppername)s.value; + AtomicCompareExchange((long*)&__%(name)s_rlock, 1, 0); + vardec, varret, varpub = map("\n".join, zip(*[ + map(lambda f : f % varinfo, + (vardecfmt, varretfmt, varpubfmt)) + for varinfo in map(lambda variable : { + "name": variable.getname(), + "configname": configname.upper(), + "uppername": variable.getname().upper(), + "IECtype": "IEC_%s"%variable.gettype(), + "initial" : str(variable.getinitial())}, + self.CodeFile.variables.variable)])) * Code generated by Beremiz py_ext confnode
* for safe global variables access
#include "iec_types_all.h"
- text += "/* User variables reference */\n"
- for variable in self.CodeFile.variables.variable:
- "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
- # Adding Beremiz confnode functions
- text += "/* Beremiz confnode functions */\n"
- text += "int __init_%s(int argc,char **argv)\n{\n"%location_str
- text += " return 0;\n}\n\n"
- text += "void __cleanup_%s(void)\n{\n"%location_str
- text += "void __retrieve_%s(void)\n{\n"%location_str
- text += "void __publish_%s(void)\n{\n"%location_str
+/* User variables reference */ +/* Beremiz confnode functions */ +int __init_%(location_str)s(int argc,char **argv){ +void __cleanup_%(location_str)s(void){ +void __retrieve_%(location_str)s(void){ +void __publish_%(location_str)s(void){ Gen_PyCfile_path = os.path.join(buildpath, "PyCFile_%s.c"%location_str)
pycfile = open(Gen_PyCfile_path,'w')
+ pycfile.write(PyCFileContent) matiec_flags = '"-I%s"'%os.path.abspath(
--- a/runtime/PLCObject.py Wed May 15 08:20:17 2013 +0200
+++ b/runtime/PLCObject.py Wed May 15 17:13:49 2013 +0900
@@ -264,6 +264,14 @@
self.python_runtime_vars["_runtime_%s"%methodname] = []
self.python_runtime_vars["PLCObject"] = self
self.python_runtime_vars["PLCBinary"] = self.PLClibraryHandle
+ def __getattr__(self, name): + r = globals()["_PySafeGetPLCGlob_"+name]() + return globals()["_"+name+"_unpack"](r) + def __setattr__(self, name, value): + v = globals()["_"+name+"_pack"](c_type,value) + globals()["_PySafeSetPLCGlob_"+name](ctypes.byref(v)) + self.python_runtime_vars["PLCGlobals"] = PLCSafeGlobals() for filename in os.listdir(self.workingdir):
name, ext = os.path.splitext(filename)