etherlab/runtime_etherlab.py
author Andrey Skvortsov <andrej.skvortzov@gmail.com>
Wed, 29 Aug 2018 18:58:51 +0300
changeset 2302 69fefac5760e
parent 2132 9f5e4dc43053
child 2353 8f1a2846b2f5
child 2641 c9deff128c37
permissions -rw-r--r--
Fix non-usable toolbar on wxPython with GTK3+ in PLCOpenEditor

this problem is related to 'Fix non-usable toolbar on wxPython with
GTK3+' (5927710b). This problem does not happen in Beremiz because
additional necessary self.AUIManager.Update() is called
BeremizIDE. Therefore minimal change in the mentioned commit was
enough for Beremiz, but is not enough for PLCOpenEditor.
2132
9f5e4dc43053 Added support for stopping SDOThreadProc when stopping PLC
Laurent Bessard
parents: 2116
diff changeset
     1
import os,subprocess,sys,ctypes
2086
8e4992e0f147 Adding block library for SDO download and SDO upload
Laurent Bessard
parents:
diff changeset
     2
from threading import Thread
2114
fc1bc441cf71 Added logging based on collecting Kernel logs
Edouard Tisserant
parents: 2086
diff changeset
     3
import ctypes,time,re
2115
edb49073227e Added error logging when SDO FB fails
Edouard Tisserant
parents: 2114
diff changeset
     4
from targets.typemapping import LogLevelsDict
2086
8e4992e0f147 Adding block library for SDO download and SDO upload
Laurent Bessard
parents:
diff changeset
     5
8e4992e0f147 Adding block library for SDO download and SDO upload
Laurent Bessard
parents:
diff changeset
     6
SDOAnswered = PLCBinary.SDOAnswered
8e4992e0f147 Adding block library for SDO download and SDO upload
Laurent Bessard
parents:
diff changeset
     7
SDOAnswered.restype = None
8e4992e0f147 Adding block library for SDO download and SDO upload
Laurent Bessard
parents:
diff changeset
     8
SDOAnswered.argtypes = []
8e4992e0f147 Adding block library for SDO download and SDO upload
Laurent Bessard
parents:
diff changeset
     9
8e4992e0f147 Adding block library for SDO download and SDO upload
Laurent Bessard
parents:
diff changeset
    10
SDOThread = None
2132
9f5e4dc43053 Added support for stopping SDOThreadProc when stopping PLC
Laurent Bessard
parents: 2116
diff changeset
    11
SDOProc = None
2086
8e4992e0f147 Adding block library for SDO download and SDO upload
Laurent Bessard
parents:
diff changeset
    12
Result = None
8e4992e0f147 Adding block library for SDO download and SDO upload
Laurent Bessard
parents:
diff changeset
    13
8e4992e0f147 Adding block library for SDO download and SDO upload
Laurent Bessard
parents:
diff changeset
    14
def SDOThreadProc(*params):
2132
9f5e4dc43053 Added support for stopping SDOThreadProc when stopping PLC
Laurent Bessard
parents: 2116
diff changeset
    15
    global Result, SDOProc
2086
8e4992e0f147 Adding block library for SDO download and SDO upload
Laurent Bessard
parents:
diff changeset
    16
    if params[0] == "upload":
2115
edb49073227e Added error logging when SDO FB fails
Edouard Tisserant
parents: 2114
diff changeset
    17
        cmdfmt = "ethercat upload -p %d -t %s 0x%.4x 0x%.2x"
2086
8e4992e0f147 Adding block library for SDO download and SDO upload
Laurent Bessard
parents:
diff changeset
    18
    else:
2115
edb49073227e Added error logging when SDO FB fails
Edouard Tisserant
parents: 2114
diff changeset
    19
        cmdfmt = "ethercat download -p %d -t %s 0x%.4x 0x%.2x %s"
2086
8e4992e0f147 Adding block library for SDO download and SDO upload
Laurent Bessard
parents:
diff changeset
    20
    
2115
edb49073227e Added error logging when SDO FB fails
Edouard Tisserant
parents: 2114
diff changeset
    21
    command = cmdfmt % params[1:]
2132
9f5e4dc43053 Added support for stopping SDOThreadProc when stopping PLC
Laurent Bessard
parents: 2116
diff changeset
    22
    SDOProc = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True)
9f5e4dc43053 Added support for stopping SDOThreadProc when stopping PLC
Laurent Bessard
parents: 2116
diff changeset
    23
    res = SDOProc.wait()
9f5e4dc43053 Added support for stopping SDOThreadProc when stopping PLC
Laurent Bessard
parents: 2116
diff changeset
    24
    output = SDOProc.communicate()[0]
2086
8e4992e0f147 Adding block library for SDO download and SDO upload
Laurent Bessard
parents:
diff changeset
    25
    
8e4992e0f147 Adding block library for SDO download and SDO upload
Laurent Bessard
parents:
diff changeset
    26
    if params[0] == "upload":
8e4992e0f147 Adding block library for SDO download and SDO upload
Laurent Bessard
parents:
diff changeset
    27
        Result = None
8e4992e0f147 Adding block library for SDO download and SDO upload
Laurent Bessard
parents:
diff changeset
    28
        if res == 0:
8e4992e0f147 Adding block library for SDO download and SDO upload
Laurent Bessard
parents:
diff changeset
    29
            if params[2] in ["float", "double"]:
8e4992e0f147 Adding block library for SDO download and SDO upload
Laurent Bessard
parents:
diff changeset
    30
                Result = float(output)
8e4992e0f147 Adding block library for SDO download and SDO upload
Laurent Bessard
parents:
diff changeset
    31
            elif params[2] in ["string", "octet_string", "unicode_string"]:
8e4992e0f147 Adding block library for SDO download and SDO upload
Laurent Bessard
parents:
diff changeset
    32
                Result = output
8e4992e0f147 Adding block library for SDO download and SDO upload
Laurent Bessard
parents:
diff changeset
    33
            else:
8e4992e0f147 Adding block library for SDO download and SDO upload
Laurent Bessard
parents:
diff changeset
    34
                hex_value, dec_value = output.split()
8e4992e0f147 Adding block library for SDO download and SDO upload
Laurent Bessard
parents:
diff changeset
    35
                if int(hex_value, 16) == int(dec_value):
8e4992e0f147 Adding block library for SDO download and SDO upload
Laurent Bessard
parents:
diff changeset
    36
                    Result = int(dec_value)
8e4992e0f147 Adding block library for SDO download and SDO upload
Laurent Bessard
parents:
diff changeset
    37
    else:
8e4992e0f147 Adding block library for SDO download and SDO upload
Laurent Bessard
parents:
diff changeset
    38
        Result = res == 0
8e4992e0f147 Adding block library for SDO download and SDO upload
Laurent Bessard
parents:
diff changeset
    39
    
8e4992e0f147 Adding block library for SDO download and SDO upload
Laurent Bessard
parents:
diff changeset
    40
    SDOAnswered()
2115
edb49073227e Added error logging when SDO FB fails
Edouard Tisserant
parents: 2114
diff changeset
    41
    if res != 0 :
edb49073227e Added error logging when SDO FB fails
Edouard Tisserant
parents: 2114
diff changeset
    42
        PLCObject.LogMessage(
edb49073227e Added error logging when SDO FB fails
Edouard Tisserant
parents: 2114
diff changeset
    43
            LogLevelsDict["WARNING"], 
edb49073227e Added error logging when SDO FB fails
Edouard Tisserant
parents: 2114
diff changeset
    44
            "%s : %s"%(command,output))
2086
8e4992e0f147 Adding block library for SDO download and SDO upload
Laurent Bessard
parents:
diff changeset
    45
    
8e4992e0f147 Adding block library for SDO download and SDO upload
Laurent Bessard
parents:
diff changeset
    46
def EthercatSDOUpload(pos, index, subindex, var_type):
8e4992e0f147 Adding block library for SDO download and SDO upload
Laurent Bessard
parents:
diff changeset
    47
    global SDOThread
8e4992e0f147 Adding block library for SDO download and SDO upload
Laurent Bessard
parents:
diff changeset
    48
    SDOThread = Thread(target=SDOThreadProc, args=["upload", pos, var_type, index, subindex])
8e4992e0f147 Adding block library for SDO download and SDO upload
Laurent Bessard
parents:
diff changeset
    49
    SDOThread.start()
8e4992e0f147 Adding block library for SDO download and SDO upload
Laurent Bessard
parents:
diff changeset
    50
    
8e4992e0f147 Adding block library for SDO download and SDO upload
Laurent Bessard
parents:
diff changeset
    51
def EthercatSDODownload(pos, index, subindex, var_type, value):
8e4992e0f147 Adding block library for SDO download and SDO upload
Laurent Bessard
parents:
diff changeset
    52
    global SDOThread
8e4992e0f147 Adding block library for SDO download and SDO upload
Laurent Bessard
parents:
diff changeset
    53
    SDOThread = Thread(target=SDOThreadProc, args=["download", pos, var_type, index, subindex, value])
8e4992e0f147 Adding block library for SDO download and SDO upload
Laurent Bessard
parents:
diff changeset
    54
    SDOThread.start()
8e4992e0f147 Adding block library for SDO download and SDO upload
Laurent Bessard
parents:
diff changeset
    55
8e4992e0f147 Adding block library for SDO download and SDO upload
Laurent Bessard
parents:
diff changeset
    56
def GetResult():
8e4992e0f147 Adding block library for SDO download and SDO upload
Laurent Bessard
parents:
diff changeset
    57
    global Result
8e4992e0f147 Adding block library for SDO download and SDO upload
Laurent Bessard
parents:
diff changeset
    58
    return Result
2114
fc1bc441cf71 Added logging based on collecting Kernel logs
Edouard Tisserant
parents: 2086
diff changeset
    59
fc1bc441cf71 Added logging based on collecting Kernel logs
Edouard Tisserant
parents: 2086
diff changeset
    60
KMSGPollThread=None
fc1bc441cf71 Added logging based on collecting Kernel logs
Edouard Tisserant
parents: 2086
diff changeset
    61
StopKMSGThread=False
fc1bc441cf71 Added logging based on collecting Kernel logs
Edouard Tisserant
parents: 2086
diff changeset
    62
def KMSGPollThreadProc():
fc1bc441cf71 Added logging based on collecting Kernel logs
Edouard Tisserant
parents: 2086
diff changeset
    63
    """
fc1bc441cf71 Added logging based on collecting Kernel logs
Edouard Tisserant
parents: 2086
diff changeset
    64
    Logs Kernel messages starting with EtherCAT
fc1bc441cf71 Added logging based on collecting Kernel logs
Edouard Tisserant
parents: 2086
diff changeset
    65
    Uses GLibc wrapper to Linux syscall "klogctl"
fc1bc441cf71 Added logging based on collecting Kernel logs
Edouard Tisserant
parents: 2086
diff changeset
    66
    Last 4 KB are polled, and lines compared to last 
fc1bc441cf71 Added logging based on collecting Kernel logs
Edouard Tisserant
parents: 2086
diff changeset
    67
    captured line to detect new lines
fc1bc441cf71 Added logging based on collecting Kernel logs
Edouard Tisserant
parents: 2086
diff changeset
    68
    """
fc1bc441cf71 Added logging based on collecting Kernel logs
Edouard Tisserant
parents: 2086
diff changeset
    69
    global StopKMSGThread
fc1bc441cf71 Added logging based on collecting Kernel logs
Edouard Tisserant
parents: 2086
diff changeset
    70
    libc=ctypes.CDLL("libc.so.6")
fc1bc441cf71 Added logging based on collecting Kernel logs
Edouard Tisserant
parents: 2086
diff changeset
    71
    klog = libc.klogctl
fc1bc441cf71 Added logging based on collecting Kernel logs
Edouard Tisserant
parents: 2086
diff changeset
    72
    klog.argtypes = [ctypes.c_int, ctypes.c_char_p, ctypes.c_int]
fc1bc441cf71 Added logging based on collecting Kernel logs
Edouard Tisserant
parents: 2086
diff changeset
    73
    klog.restype = ctypes.c_int
fc1bc441cf71 Added logging based on collecting Kernel logs
Edouard Tisserant
parents: 2086
diff changeset
    74
    s=ctypes.create_string_buffer(4*1024)
fc1bc441cf71 Added logging based on collecting Kernel logs
Edouard Tisserant
parents: 2086
diff changeset
    75
    last = None
fc1bc441cf71 Added logging based on collecting Kernel logs
Edouard Tisserant
parents: 2086
diff changeset
    76
    while not StopKMSGThread:
fc1bc441cf71 Added logging based on collecting Kernel logs
Edouard Tisserant
parents: 2086
diff changeset
    77
        l = klog(3,s,len(s)-1)
fc1bc441cf71 Added logging based on collecting Kernel logs
Edouard Tisserant
parents: 2086
diff changeset
    78
        log = s.value[:l-1]
fc1bc441cf71 Added logging based on collecting Kernel logs
Edouard Tisserant
parents: 2086
diff changeset
    79
        if last :
fc1bc441cf71 Added logging based on collecting Kernel logs
Edouard Tisserant
parents: 2086
diff changeset
    80
            log = log.rpartition(last)[2]
fc1bc441cf71 Added logging based on collecting Kernel logs
Edouard Tisserant
parents: 2086
diff changeset
    81
        if log : 
fc1bc441cf71 Added logging based on collecting Kernel logs
Edouard Tisserant
parents: 2086
diff changeset
    82
            last = log.rpartition('\n')[2]
2116
2b1980a038b1 Better logging, saffer failure at init (allows restart)
Edouard Tisserant
parents: 2115
diff changeset
    83
            for lvl,msg in re.findall(
2b1980a038b1 Better logging, saffer failure at init (allows restart)
Edouard Tisserant
parents: 2115
diff changeset
    84
                            r'<(\d)>\[\s*\d*\.\d*\]\s*(EtherCAT\s*.*)$',
2b1980a038b1 Better logging, saffer failure at init (allows restart)
Edouard Tisserant
parents: 2115
diff changeset
    85
                            log, re.MULTILINE):
2b1980a038b1 Better logging, saffer failure at init (allows restart)
Edouard Tisserant
parents: 2115
diff changeset
    86
                PLCObject.LogMessage(
2b1980a038b1 Better logging, saffer failure at init (allows restart)
Edouard Tisserant
parents: 2115
diff changeset
    87
                    LogLevelsDict[{
2b1980a038b1 Better logging, saffer failure at init (allows restart)
Edouard Tisserant
parents: 2115
diff changeset
    88
                        "4":"WARNING",
2b1980a038b1 Better logging, saffer failure at init (allows restart)
Edouard Tisserant
parents: 2115
diff changeset
    89
                        "3":"CRITICAL"}.get(lvl,"DEBUG")],
2b1980a038b1 Better logging, saffer failure at init (allows restart)
Edouard Tisserant
parents: 2115
diff changeset
    90
                    msg)
2114
fc1bc441cf71 Added logging based on collecting Kernel logs
Edouard Tisserant
parents: 2086
diff changeset
    91
        time.sleep(0.5) 
fc1bc441cf71 Added logging based on collecting Kernel logs
Edouard Tisserant
parents: 2086
diff changeset
    92
fc1bc441cf71 Added logging based on collecting Kernel logs
Edouard Tisserant
parents: 2086
diff changeset
    93
def _runtime_etherlab_init():
fc1bc441cf71 Added logging based on collecting Kernel logs
Edouard Tisserant
parents: 2086
diff changeset
    94
    global KMSGPollThread, StopKMSGThread
fc1bc441cf71 Added logging based on collecting Kernel logs
Edouard Tisserant
parents: 2086
diff changeset
    95
    StopKMSGThread = False
fc1bc441cf71 Added logging based on collecting Kernel logs
Edouard Tisserant
parents: 2086
diff changeset
    96
    KMSGPollThread = Thread(target = KMSGPollThreadProc)
fc1bc441cf71 Added logging based on collecting Kernel logs
Edouard Tisserant
parents: 2086
diff changeset
    97
    KMSGPollThread.start()
fc1bc441cf71 Added logging based on collecting Kernel logs
Edouard Tisserant
parents: 2086
diff changeset
    98
fc1bc441cf71 Added logging based on collecting Kernel logs
Edouard Tisserant
parents: 2086
diff changeset
    99
def _runtime_etherlab_cleanup():
2132
9f5e4dc43053 Added support for stopping SDOThreadProc when stopping PLC
Laurent Bessard
parents: 2116
diff changeset
   100
    global KMSGPollThread, StopKMSGThread, SDOProc, SDOThread
9f5e4dc43053 Added support for stopping SDOThreadProc when stopping PLC
Laurent Bessard
parents: 2116
diff changeset
   101
    try:
9f5e4dc43053 Added support for stopping SDOThreadProc when stopping PLC
Laurent Bessard
parents: 2116
diff changeset
   102
        os.kill(SDOProc.pid, SIGTERM)
9f5e4dc43053 Added support for stopping SDOThreadProc when stopping PLC
Laurent Bessard
parents: 2116
diff changeset
   103
    except:
9f5e4dc43053 Added support for stopping SDOThreadProc when stopping PLC
Laurent Bessard
parents: 2116
diff changeset
   104
        pass
9f5e4dc43053 Added support for stopping SDOThreadProc when stopping PLC
Laurent Bessard
parents: 2116
diff changeset
   105
    SDOThread = None
2114
fc1bc441cf71 Added logging based on collecting Kernel logs
Edouard Tisserant
parents: 2086
diff changeset
   106
    StopKMSGThread = True
fc1bc441cf71 Added logging based on collecting Kernel logs
Edouard Tisserant
parents: 2086
diff changeset
   107
    KMSGPollThread = None
fc1bc441cf71 Added logging based on collecting Kernel logs
Edouard Tisserant
parents: 2086
diff changeset
   108