diff -r b579e2155d02 -r 09d5d1456616 etherlab/runtime_etherlab.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/etherlab/runtime_etherlab.py Sat Jun 23 09:17:20 2018 +0200 @@ -0,0 +1,108 @@ +import os,subprocess,sys,ctypes +from threading import Thread +import ctypes,time,re +from targets.typemapping import LogLevelsDict + +SDOAnswered = PLCBinary.SDOAnswered +SDOAnswered.restype = None +SDOAnswered.argtypes = [] + +SDOThread = None +SDOProc = None +Result = None + +def SDOThreadProc(*params): + global Result, SDOProc + if params[0] == "upload": + cmdfmt = "ethercat upload -p %d -t %s 0x%.4x 0x%.2x" + else: + cmdfmt = "ethercat download -p %d -t %s 0x%.4x 0x%.2x %s" + + command = cmdfmt % params[1:] + SDOProc = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True) + res = SDOProc.wait() + output = SDOProc.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() + if res != 0 : + PLCObject.LogMessage( + LogLevelsDict["WARNING"], + "%s : %s"%(command,output)) + +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 + +KMSGPollThread=None +StopKMSGThread=False +def KMSGPollThreadProc(): + """ + Logs Kernel messages starting with EtherCAT + Uses GLibc wrapper to Linux syscall "klogctl" + Last 4 KB are polled, and lines compared to last + captured line to detect new lines + """ + global StopKMSGThread + libc=ctypes.CDLL("libc.so.6") + klog = libc.klogctl + klog.argtypes = [ctypes.c_int, ctypes.c_char_p, ctypes.c_int] + klog.restype = ctypes.c_int + s=ctypes.create_string_buffer(4*1024) + last = None + while not StopKMSGThread: + l = klog(3,s,len(s)-1) + log = s.value[:l-1] + if last : + log = log.rpartition(last)[2] + if log : + last = log.rpartition('\n')[2] + for lvl,msg in re.findall( + r'<(\d)>\[\s*\d*\.\d*\]\s*(EtherCAT\s*.*)$', + log, re.MULTILINE): + PLCObject.LogMessage( + LogLevelsDict[{ + "4":"WARNING", + "3":"CRITICAL"}.get(lvl,"DEBUG")], + msg) + time.sleep(0.5) + +def _runtime_etherlab_init(): + global KMSGPollThread, StopKMSGThread + StopKMSGThread = False + KMSGPollThread = Thread(target = KMSGPollThreadProc) + KMSGPollThread.start() + +def _runtime_etherlab_cleanup(): + global KMSGPollThread, StopKMSGThread, SDOProc, SDOThread + try: + os.kill(SDOProc.pid, SIGTERM) + except: + pass + SDOThread = None + StopKMSGThread = True + KMSGPollThread = None +