# HG changeset patch # User Laurent Bessard # Date 1351187702 -7200 # Node ID 8e4992e0f14789b36539b4462e10580854ec6f93 # Parent ae263886ae929ed5c7bbdd28a2f1f32ccb66bac1 Adding block library for SDO download and SDO upload diff -r ae263886ae92 -r 8e4992e0f147 etherlab/etherlab.py --- a/etherlab/etherlab.py Fri Oct 19 16:37:54 2012 +0200 +++ b/etherlab/etherlab.py Thu Oct 25 19:55:02 2012 +0200 @@ -5,6 +5,7 @@ import wx from xmlclass import * +from POULibrary import POULibrary from ConfigTreeNode import ConfigTreeNode from PLCControler import UndoBuffer, LOCATION_CONFNODE, LOCATION_MODULE, LOCATION_GROUP, LOCATION_VAR_INPUT, LOCATION_VAR_OUTPUT, LOCATION_VAR_MEMORY from ConfigEditor import NodeEditor, CIA402NodeEditor, ETHERCAT_VENDOR, ETHERCAT_GROUP, ETHERCAT_DEVICE @@ -56,6 +57,31 @@ """ #-------------------------------------------------- +# Etherlab Specific Blocks Library +#-------------------------------------------------- + +def GetLocalPath(filename): + return os.path.join(os.path.split(__file__)[0], filename) + +class EtherlabLibrary(POULibrary): + def GetLibraryPath(self): + return GetLocalPath("pous.xml") + + def Generate_C(self, buildpath, varlist, IECCFLAGS): + etherlab_ext_file = open(GetLocalPath("etherlab_ext.c"), 'r') + etherlab_ext_code = etherlab_ext_file.read() + etherlab_ext_file.close() + + Gen_etherlabfile_path = os.path.join(buildpath, "etherlab_ext.c") + ethelabfile = open(Gen_etherlabfile_path,'w') + ethelabfile.write(etherlab_ext_code) + ethelabfile.close() + + runtimefile_path = os.path.join(os.path.split(__file__)[0], "runtime_etherlab.py") + return ((["etherlab_ext"], [(Gen_etherlabfile_path, IECCFLAGS)], True), "", + ("runtime_etherlab.py", file(GetLocalPath("runtime_etherlab.py")))) + +#-------------------------------------------------- # Ethercat Node #-------------------------------------------------- diff -r ae263886ae92 -r 8e4992e0f147 etherlab/etherlab_ext.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/etherlab/etherlab_ext.c Thu Oct 25 19:55:02 2012 +0200 @@ -0,0 +1,42 @@ +#include "iec_types_all.h" + +#define FREE 0 +#define ACQUIRED 1 +#define ANSWERED 2 + +long SDOLock = FREE; +extern long AtomicCompareExchange(long* atomicvar,long compared, long exchange); + +int AcquireSDOLock() { + return AtomicCompareExchange(&SDOLock, FREE, ACQUIRED) == FREE; +} + +void SDOAnswered() { + AtomicCompareExchange(&SDOLock, ACQUIRED, ANSWERED); +} + +int HasAnswer() { + return SDOLock == ANSWERED; +} + +void ReleaseSDOLock() { + AtomicCompareExchange(&SDOLock, ANSWERED, FREE); +} + +int __init_etherlab_ext() +{ + SDOLock = FREE; + return 0; +} + +void __cleanup_etherlab_ext() +{ +} + +void __retrieve_etherlab_ext() +{ +} + +void __publish_etherlab_ext() +{ +} diff -r ae263886ae92 -r 8e4992e0f147 etherlab/extension.py --- a/etherlab/extension.py Fri Oct 19 16:37:54 2012 +0200 +++ b/etherlab/extension.py Thu Oct 25 19:55:02 2012 +0200 @@ -1,5 +1,12 @@ import features +def GetEtherLabLibClass(): + from etherlab import EtherlabLibrary + return EtherlabLibrary + +features.libraries.append( + ('Etherlab', GetEtherLabLibClass)) + def GetEtherLabClass(): from etherlab import RootClass return RootClass diff -r ae263886ae92 -r 8e4992e0f147 etherlab/pous.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/etherlab/pous.xml Thu Oct 25 19:55:02 2012 +0200 @@ -0,0 +1,276 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +,STATE, 2)} + 2: + IF PY0.ACK THEN + STATE := 3; + END_IF; + 3: + {if (HasAnswer()) __SET_VAR(data__->,STATE, 4)} + 4: + IF PY1.ACK THEN + ACK := 1; + VALUE := PY1.RESULT; + VALID := NE(VALUE, 'None'); + STATE := 0; + {ReleaseSDOLock();} + END_IF; +ELSE + STATE := 0; +END_CASE; + +EXECUTE0 := EXECUTE; +PY0(TRIG := STATE = 2, + CODE := CONCAT('EthercatSDOUpload(', + INT_TO_STRING(POS), + ',', + UINT_TO_STRING(INDEX), + ',', + USINT_TO_STRING(SUBINDEX), + ',"', + VARTYPE, + '")')); +PY1(TRIG := STATE = 4, + CODE := 'GetResult()'); +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +,STATE, 2)} + 2: + IF PY0.ACK THEN + STATE := 3; + END_IF; + 3: + {if (HasAnswer()) __SET_VAR(data__->,STATE, 4)} + 4: + IF PY1.ACK THEN + ACK := 1; + VALUE := PY1.RESULT; + ERROR := EQ(PY1.RESULT, 'False'); + STATE := 0; + {ReleaseSDOLock();} + END_IF; +ELSE + STATE := 0; +END_CASE; +EXECUTE0 := EXECUTE; +PY0(TRIG := STATE = 2, + CODE := CONCAT('EthercatSDODownload(', + INT_TO_STRING(POS), + ',', + UINT_TO_STRING(INDEX), + ',', + USINT_TO_STRING(SUBINDEX), + ',"', + VARTYPE, + '",', + VALUE, + ')')); +PY1(TRIG := STATE = 4, + CODE := 'GetResult()'); +]]> + + + + + + + + + diff -r ae263886ae92 -r 8e4992e0f147 etherlab/runtime_etherlab.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/etherlab/runtime_etherlab.py Thu Oct 25 19:55:02 2012 +0200 @@ -0,0 +1,50 @@ +import subprocess,sys,ctypes +from threading import Thread + +SDOAnswered = PLCBinary.SDOAnswered +SDOAnswered.restype = None +SDOAnswered.argtypes = [] + +SDOThread = None +Result = None + +def SDOThreadProc(*params): + global Result + if params[0] == "upload": + command = "ethercat upload -p %d -t %s 0x%.4x 0x%.2x" + else: + command = "ethercat download -p %d -t %s 0x%.4x 0x%.2x %s" + + proc = subprocess.Popen(command % params[1:], stdout=subprocess.PIPE, shell=True) + res = proc.wait() + output = proc.communicate()[0] + + if params[0] == "upload": + Result = None + if res == 0: + if params[2] in ["float", "double"]: + Result = float(output) + elif params[2] in ["string", "octet_string", "unicode_string"]: + Result = output + else: + hex_value, dec_value = output.split() + if int(hex_value, 16) == int(dec_value): + Result = int(dec_value) + else: + Result = res == 0 + + SDOAnswered() + +def EthercatSDOUpload(pos, index, subindex, var_type): + global SDOThread + SDOThread = Thread(target=SDOThreadProc, args=["upload", pos, var_type, index, subindex]) + SDOThread.start() + +def EthercatSDODownload(pos, index, subindex, var_type, value): + global SDOThread + SDOThread = Thread(target=SDOThreadProc, args=["download", pos, var_type, index, subindex, value]) + SDOThread.start() + +def GetResult(): + global Result + return Result