Laurent@2132: import os,subprocess,sys,ctypes
Laurent@2086: from threading import Thread
Edouard@2114: import ctypes,time,re
Edouard@2115: from targets.typemapping import LogLevelsDict
Laurent@2086: 
Laurent@2086: SDOAnswered = PLCBinary.SDOAnswered
Laurent@2086: SDOAnswered.restype = None
Laurent@2086: SDOAnswered.argtypes = []
Laurent@2086: 
Laurent@2086: SDOThread = None
Laurent@2132: SDOProc = None
Laurent@2086: Result = None
Laurent@2086: 
Laurent@2086: def SDOThreadProc(*params):
Laurent@2132:     global Result, SDOProc
Laurent@2086:     if params[0] == "upload":
Edouard@2115:         cmdfmt = "ethercat upload -p %d -t %s 0x%.4x 0x%.2x"
Laurent@2086:     else:
Edouard@2115:         cmdfmt = "ethercat download -p %d -t %s 0x%.4x 0x%.2x %s"
Laurent@2086:     
Edouard@2115:     command = cmdfmt % params[1:]
Laurent@2132:     SDOProc = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True)
Laurent@2132:     res = SDOProc.wait()
Laurent@2132:     output = SDOProc.communicate()[0]
Laurent@2086:     
Laurent@2086:     if params[0] == "upload":
Laurent@2086:         Result = None
Laurent@2086:         if res == 0:
Laurent@2086:             if params[2] in ["float", "double"]:
Laurent@2086:                 Result = float(output)
Laurent@2086:             elif params[2] in ["string", "octet_string", "unicode_string"]:
Laurent@2086:                 Result = output
Laurent@2086:             else:
Laurent@2086:                 hex_value, dec_value = output.split()
Laurent@2086:                 if int(hex_value, 16) == int(dec_value):
Laurent@2086:                     Result = int(dec_value)
Laurent@2086:     else:
Laurent@2086:         Result = res == 0
Laurent@2086:     
Laurent@2086:     SDOAnswered()
Edouard@2115:     if res != 0 :
Edouard@2115:         PLCObject.LogMessage(
Edouard@2115:             LogLevelsDict["WARNING"], 
Edouard@2115:             "%s : %s"%(command,output))
Laurent@2086:     
Laurent@2086: def EthercatSDOUpload(pos, index, subindex, var_type):
Laurent@2086:     global SDOThread
Laurent@2086:     SDOThread = Thread(target=SDOThreadProc, args=["upload", pos, var_type, index, subindex])
Laurent@2086:     SDOThread.start()
Laurent@2086:     
Laurent@2086: def EthercatSDODownload(pos, index, subindex, var_type, value):
Laurent@2086:     global SDOThread
Laurent@2086:     SDOThread = Thread(target=SDOThreadProc, args=["download", pos, var_type, index, subindex, value])
Laurent@2086:     SDOThread.start()
Laurent@2086: 
Laurent@2086: def GetResult():
Laurent@2086:     global Result
Laurent@2086:     return Result
Edouard@2114: 
Edouard@2114: KMSGPollThread=None
Edouard@2114: StopKMSGThread=False
Edouard@2114: def KMSGPollThreadProc():
Edouard@2114:     """
Edouard@2114:     Logs Kernel messages starting with EtherCAT
Edouard@2114:     Uses GLibc wrapper to Linux syscall "klogctl"
Edouard@2114:     Last 4 KB are polled, and lines compared to last 
Edouard@2114:     captured line to detect new lines
Edouard@2114:     """
Edouard@2114:     global StopKMSGThread
Edouard@2114:     libc=ctypes.CDLL("libc.so.6")
Edouard@2114:     klog = libc.klogctl
Edouard@2114:     klog.argtypes = [ctypes.c_int, ctypes.c_char_p, ctypes.c_int]
Edouard@2114:     klog.restype = ctypes.c_int
Edouard@2114:     s=ctypes.create_string_buffer(4*1024)
Edouard@2114:     last = None
Edouard@2114:     while not StopKMSGThread:
Edouard@2114:         l = klog(3,s,len(s)-1)
Edouard@2114:         log = s.value[:l-1]
Edouard@2114:         if last :
Edouard@2114:             log = log.rpartition(last)[2]
Edouard@2114:         if log : 
Edouard@2114:             last = log.rpartition('\n')[2]
Edouard@2116:             for lvl,msg in re.findall(
Edouard@2116:                             r'<(\d)>\[\s*\d*\.\d*\]\s*(EtherCAT\s*.*)$',
Edouard@2116:                             log, re.MULTILINE):
Edouard@2116:                 PLCObject.LogMessage(
Edouard@2116:                     LogLevelsDict[{
Edouard@2116:                         "4":"WARNING",
Edouard@2116:                         "3":"CRITICAL"}.get(lvl,"DEBUG")],
Edouard@2116:                     msg)
Edouard@2114:         time.sleep(0.5) 
Edouard@2114: 
Edouard@2114: def _runtime_etherlab_init():
Edouard@2114:     global KMSGPollThread, StopKMSGThread
Edouard@2114:     StopKMSGThread = False
Edouard@2114:     KMSGPollThread = Thread(target = KMSGPollThreadProc)
Edouard@2114:     KMSGPollThread.start()
Edouard@2114: 
Edouard@2114: def _runtime_etherlab_cleanup():
Laurent@2132:     global KMSGPollThread, StopKMSGThread, SDOProc, SDOThread
Laurent@2132:     try:
Laurent@2132:         os.kill(SDOProc.pid, SIGTERM)
Laurent@2132:     except:
Laurent@2132:         pass
Laurent@2132:     SDOThread = None
Edouard@2114:     StopKMSGThread = True
Edouard@2114:     KMSGPollThread = None
Edouard@2114: