# HG changeset patch # User Edouard Tisserant # Date 1350584651 -7200 # Node ID dbf82971f09d39e1c00e6a295173fe338567a5ca # Parent daafaa8a28fda78b7b71b8ba7a142e944388a672 More pedagogical tests/python. Should be renamed python_ctypes_and_C_pragmas_in_ST or something diff -r daafaa8a28fd -r dbf82971f09d tests/python/beremiz.xml --- a/tests/python/beremiz.xml Thu Oct 18 17:42:29 2012 +0200 +++ b/tests/python/beremiz.xml Thu Oct 18 20:24:11 2012 +0200 @@ -1,4 +1,4 @@ <?xml version="1.0" encoding="UTF-8"?> -<BeremizRoot> +<BeremizRoot URI_location="LOCAL://"> <TargetType/> </BeremizRoot> diff -r daafaa8a28fd -r dbf82971f09d tests/python/c_code@c_ext/cfile.xml --- a/tests/python/c_code@c_ext/cfile.xml Thu Oct 18 17:42:29 2012 +0200 +++ b/tests/python/c_code@c_ext/cfile.xml Thu Oct 18 20:24:11 2012 +0200 @@ -3,14 +3,48 @@ <includes> <![CDATA[]]> </includes> - <variables/> + <variables> + <variable name="TestInput" type="SINT" class="input"/> + <variable name="TestOutput" type="SINT" class="input"/> + </variables> <globals> -<![CDATA[void Python_to_C_Call(int value){ - /* That code should never touch to - variables modified by PLC thread */ - printf("C code called by Python: %d\n",value); +<![CDATA[volatile long Lock=0; +volatile char PtoC=1,CtoP=2; + +int Simple_C_Call(int val){ + return val+1; } -]]> + +int Python_to_C_Call(int toC, int *fromC){ + /* Code called by python should never touch to + variables modified by PLC thread directly + + AtomicCompareExchange comes from + beremiz' runtime implementation */ + + int res = 0; + if(!AtomicCompareExchange(&Lock, 0, 1)){ + PtoC=toC; + *fromC=CtoP; + AtomicCompareExchange(&Lock, 1, 0); + res=1; + } + printf("C code called by Python: toC %d fromC %d\n",toC,*fromC); + return res; +} + +int PLC_C_Call(int fromPLC, int *toPLC){ + /* PLC also have to be realy carefull not to + conflict with asynchronous python access */ + int res; + if(!AtomicCompareExchange(&Lock, 0, 1)){ + CtoP = fromPLC; + *toPLC = PtoC; + AtomicCompareExchange(&Lock, 1, 0); + return 1; + } + return 0; +}]]> </globals> <initFunction> <![CDATA[]]> diff -r daafaa8a28fd -r dbf82971f09d tests/python/plc.xml --- a/tests/python/plc.xml Thu Oct 18 17:42:29 2012 +0200 +++ b/tests/python/plc.xml Thu Oct 18 20:24:11 2012 +0200 @@ -8,7 +8,7 @@ productVersion="0.0" creationDateTime="2008-12-14T16:21:19"/> <contentHeader name="Beremiz Python Support Tests" - modificationDateTime="2012-06-08T23:11:45"> + modificationDateTime="2012-10-18T20:21:28"> <coordinateInfo> <pageSize x="1024" y="1024"/> <fbd> @@ -63,6 +63,16 @@ <BOOL/> </type> </variable> + <variable name="FromC"> + <type> + <SINT/> + </type> + </variable> + <variable name="C_Pragma0"> + <type> + <derived name="C_Pragma"/> + </type> + </variable> </localVars> </interface> <body> @@ -202,7 +212,7 @@ <connectionPointOut> <relPosition x="290" y="15"/> </connectionPointOut> - <expression>'PLCBinary.Python_to_C_Call(5678)'</expression> + <expression>'PLCBinary.Simple_C_Call(5678)'</expression> </inVariable> <block localId="12" width="125" height="80" typeName="python_eval" instanceName="Block2"> <position x="650" y="417"/> @@ -457,9 +467,79 @@ </connectionPointIn> <expression>pytest_var3</expression> </outVariable> + <outVariable localId="25" height="30" width="60"> + <position x="820" y="750"/> + <connectionPointIn> + <relPosition x="0" y="15"/> + <connection refLocalId="26" formalParameter="OUT"> + <position x="820" y="765"/> + <position x="765" y="765"/> + </connection> + </connectionPointIn> + <expression>FromC</expression> + </outVariable> + <inVariable localId="1" height="30" width="30"> + <position x="605" y="750"/> + <connectionPointOut> + <relPosition x="30" y="15"/> + </connectionPointOut> + <expression>23</expression> + </inVariable> + <block localId="26" width="80" height="45" typeName="C_Pragma" instanceName="C_Pragma0"> + <position x="685" y="735"/> + <inputVariables> + <variable formalParameter="IN"> + <connectionPointIn> + <relPosition x="0" y="30"/> + <connection refLocalId="1"> + <position x="685" y="765"/> + <position x="635" y="765"/> + </connection> + </connectionPointIn> + </variable> + </inputVariables> + <inOutVariables/> + <outputVariables> + <variable formalParameter="OUT"> + <connectionPointOut> + <relPosition x="80" y="30"/> + </connectionPointOut> + </variable> + </outputVariables> + </block> </FBD> </body> </pou> + <pou name="C_Pragma" pouType="functionBlock"> + <interface> + <outputVars> + <variable name="OUT"> + <type> + <SINT/> + </type> + </variable> + </outputVars> + <inputVars> + <variable name="IN"> + <type> + <SINT/> + </type> + </variable> + </inputVars> + </interface> + <body> + <ST> +<![CDATA[(* hereafter is a C pragma accessing FB interface in a clean way *) +{ + int toPLC; + int fromPLC = __GET_VAR(data__->IN); + if(PLC_C_Call(fromPLC, &toPLC))__SET_VAR(data__->,OUT,toPLC); +} +(* If you do not use __GET_VAR and _SET_VAR macro, expect unexpected *) +]]> + </ST> + </body> + </pou> </pous> </types> <instances> diff -r daafaa8a28fd -r dbf82971f09d tests/python/python@py_ext/py_ext.xml --- a/tests/python/python@py_ext/py_ext.xml Thu Oct 18 17:42:29 2012 +0200 +++ b/tests/python/python@py_ext/py_ext.xml Thu Oct 18 20:24:11 2012 +0200 @@ -1,11 +1,19 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <Python xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.w3.org/2001/XMLSchema" xsi:schemaLocation="py_ext_xsd.xsd"> -<![CDATA[import time,sys +<![CDATA[import time,sys,ctypes +Python_to_C_Call = PLCBinary.Python_to_C_Call +Python_to_C_Call.restype = ctypes.c_int +Python_to_C_Call.argtypes = [ctypes.c_int, ctypes.POINTER(ctypes.c_int)] def MyPythonFunc(arg): - print arg - PLCBinary.Python_to_C_Call(arg) + i = ctypes.c_int() + if(Python_to_C_Call(arg, i)): + res = i.value + print "toC:", arg, "from C:", res + else: + print "Failed Python_to_C_Call failed" + res = None sys.stdout.flush() - return arg + return res ]]> </Python>