etherlab/runtime_etherlab.py
changeset 2192 09d5d1456616
parent 2132 9f5e4dc43053
child 2353 8f1a2846b2f5
child 2641 c9deff128c37
equal deleted inserted replaced
2191:b579e2155d02 2192:09d5d1456616
       
     1 import os,subprocess,sys,ctypes
       
     2 from threading import Thread
       
     3 import ctypes,time,re
       
     4 from targets.typemapping import LogLevelsDict
       
     5 
       
     6 SDOAnswered = PLCBinary.SDOAnswered
       
     7 SDOAnswered.restype = None
       
     8 SDOAnswered.argtypes = []
       
     9 
       
    10 SDOThread = None
       
    11 SDOProc = None
       
    12 Result = None
       
    13 
       
    14 def SDOThreadProc(*params):
       
    15     global Result, SDOProc
       
    16     if params[0] == "upload":
       
    17         cmdfmt = "ethercat upload -p %d -t %s 0x%.4x 0x%.2x"
       
    18     else:
       
    19         cmdfmt = "ethercat download -p %d -t %s 0x%.4x 0x%.2x %s"
       
    20     
       
    21     command = cmdfmt % params[1:]
       
    22     SDOProc = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True)
       
    23     res = SDOProc.wait()
       
    24     output = SDOProc.communicate()[0]
       
    25     
       
    26     if params[0] == "upload":
       
    27         Result = None
       
    28         if res == 0:
       
    29             if params[2] in ["float", "double"]:
       
    30                 Result = float(output)
       
    31             elif params[2] in ["string", "octet_string", "unicode_string"]:
       
    32                 Result = output
       
    33             else:
       
    34                 hex_value, dec_value = output.split()
       
    35                 if int(hex_value, 16) == int(dec_value):
       
    36                     Result = int(dec_value)
       
    37     else:
       
    38         Result = res == 0
       
    39     
       
    40     SDOAnswered()
       
    41     if res != 0 :
       
    42         PLCObject.LogMessage(
       
    43             LogLevelsDict["WARNING"], 
       
    44             "%s : %s"%(command,output))
       
    45     
       
    46 def EthercatSDOUpload(pos, index, subindex, var_type):
       
    47     global SDOThread
       
    48     SDOThread = Thread(target=SDOThreadProc, args=["upload", pos, var_type, index, subindex])
       
    49     SDOThread.start()
       
    50     
       
    51 def EthercatSDODownload(pos, index, subindex, var_type, value):
       
    52     global SDOThread
       
    53     SDOThread = Thread(target=SDOThreadProc, args=["download", pos, var_type, index, subindex, value])
       
    54     SDOThread.start()
       
    55 
       
    56 def GetResult():
       
    57     global Result
       
    58     return Result
       
    59 
       
    60 KMSGPollThread=None
       
    61 StopKMSGThread=False
       
    62 def KMSGPollThreadProc():
       
    63     """
       
    64     Logs Kernel messages starting with EtherCAT
       
    65     Uses GLibc wrapper to Linux syscall "klogctl"
       
    66     Last 4 KB are polled, and lines compared to last 
       
    67     captured line to detect new lines
       
    68     """
       
    69     global StopKMSGThread
       
    70     libc=ctypes.CDLL("libc.so.6")
       
    71     klog = libc.klogctl
       
    72     klog.argtypes = [ctypes.c_int, ctypes.c_char_p, ctypes.c_int]
       
    73     klog.restype = ctypes.c_int
       
    74     s=ctypes.create_string_buffer(4*1024)
       
    75     last = None
       
    76     while not StopKMSGThread:
       
    77         l = klog(3,s,len(s)-1)
       
    78         log = s.value[:l-1]
       
    79         if last :
       
    80             log = log.rpartition(last)[2]
       
    81         if log : 
       
    82             last = log.rpartition('\n')[2]
       
    83             for lvl,msg in re.findall(
       
    84                             r'<(\d)>\[\s*\d*\.\d*\]\s*(EtherCAT\s*.*)$',
       
    85                             log, re.MULTILINE):
       
    86                 PLCObject.LogMessage(
       
    87                     LogLevelsDict[{
       
    88                         "4":"WARNING",
       
    89                         "3":"CRITICAL"}.get(lvl,"DEBUG")],
       
    90                     msg)
       
    91         time.sleep(0.5) 
       
    92 
       
    93 def _runtime_etherlab_init():
       
    94     global KMSGPollThread, StopKMSGThread
       
    95     StopKMSGThread = False
       
    96     KMSGPollThread = Thread(target = KMSGPollThreadProc)
       
    97     KMSGPollThread.start()
       
    98 
       
    99 def _runtime_etherlab_cleanup():
       
   100     global KMSGPollThread, StopKMSGThread, SDOProc, SDOThread
       
   101     try:
       
   102         os.kill(SDOProc.pid, SIGTERM)
       
   103     except:
       
   104         pass
       
   105     SDOThread = None
       
   106     StopKMSGThread = True
       
   107     KMSGPollThread = None
       
   108