Mit default zusammenführen

This commit is contained in:
2017-09-20 18:15:17 +02:00
7 changed files with 142 additions and 29 deletions

View File

@@ -10,7 +10,7 @@ plcslave = 0
plcslaveacl = plcslaveacl =
plcslaveport = 55234 plcslaveport = 55234
pythonversion = 3 pythonversion = 3
rtlevel = 1 rtlevel = 0
xmlrpc = 0 xmlrpc = 0
xmlrpcacl = xmlrpcacl =
zeroonerror = 0 zeroonerror = 0

View File

@@ -23,6 +23,9 @@ Classes</h3>
Functions</h3> Functions</h3>
<table> <table>
<tr> <tr>
<td><a style="color:#0000FF" href="#_setuprt">_setuprt</a></td>
<td>Konfiguriert Programm fuer den RT-Scheduler.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#_zeroprocimg">_zeroprocimg</a></td> <td><a style="color:#0000FF" href="#_zeroprocimg">_zeroprocimg</a></td>
<td>Setzt Prozessabbild auf NULL.</td> <td>Setzt Prozessabbild auf NULL.</td>
</tr><tr> </tr><tr>
@@ -34,6 +37,24 @@ Functions</h3>
</tr> </tr>
</table> </table>
<hr /><hr /> <hr /><hr />
<a NAME="_setuprt" ID="_setuprt"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">_setuprt</h2>
<b>_setuprt</b>(<i>pid, evt_exit</i>)
<p>
Konfiguriert Programm fuer den RT-Scheduler.
</p><dl>
<dt><i>pid</i></dt>
<dd>
PID, der angehoben werden soll
</dd>
</dl><dl>
<dt>Returns:</dt>
<dd>
None
</dd>
</dl>
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr /><hr />
<a NAME="_zeroprocimg" ID="_zeroprocimg"></a> <a NAME="_zeroprocimg" ID="_zeroprocimg"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">_zeroprocimg</h2> <h2 style="background-color:#FFFFFF;color:#0000FF">_zeroprocimg</h2>
<b>_zeroprocimg</b>(<i></i>) <b>_zeroprocimg</b>(<i></i>)

View File

@@ -31,6 +31,7 @@ procimgserver.ProcimgServer.start?4()
procimgserver.ProcimgServer.stop?4() procimgserver.ProcimgServer.stop?4()
procimgserver.ProcimgServer.values?4() procimgserver.ProcimgServer.values?4()
procimgserver.ProcimgServer?1(xmlserver, aclmode) procimgserver.ProcimgServer?1(xmlserver, aclmode)
proginit._setuprt?5(pid, evt_exit)
proginit._zeroprocimg?5() proginit._zeroprocimg?5()
proginit.cleanup?4() proginit.cleanup?4()
proginit.configure?4() proginit.configure?4()

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Project SYSTEM "Project-5.1.dtd"> <!DOCTYPE Project SYSTEM "Project-5.1.dtd">
<!-- eric project file for project revpipyload --> <!-- eric project file for project revpipyload -->
<!-- Saved: 2017-09-19, 14:11:22 --> <!-- Saved: 2017-09-20, 18:10:38 -->
<!-- Copyright (C) 2017 Sven Sager, akira@narux.de --> <!-- Copyright (C) 2017 Sven Sager, akira@narux.de -->
<Project version="5.1"> <Project version="5.1">
<Language>en_US</Language> <Language>en_US</Language>

View File

@@ -11,6 +11,7 @@ import proginit
import shlex import shlex
import subprocess import subprocess
from logsystem import PipeLogwriter from logsystem import PipeLogwriter
from proginit import _setuprt
from sys import stdout as sysstdout from sys import stdout as sysstdout
from threading import Event, Thread from threading import Event, Thread
from time import sleep, asctime from time import sleep, asctime
@@ -41,7 +42,7 @@ class RevPiPlc(Thread):
self.exitcode = None self.exitcode = None
self.gid = 65534 self.gid = 65534
self.uid = 65534 self.uid = 65534
self.rtlevel = 1 self.rtlevel = 0
self.zeroonerror = False self.zeroonerror = False
self.zeroonexit = False self.zeroonexit = False
@@ -104,8 +105,16 @@ class RevPiPlc(Thread):
"""Fuehrt PLC-Programm aus und ueberwacht es.""" """Fuehrt PLC-Programm aus und ueberwacht es."""
proginit.logger.debug("enter RevPiPlc.run()") proginit.logger.debug("enter RevPiPlc.run()")
# LogWriter starten und Logausgaben schreiben
if self._plw is not None:
self._plw.logline("-" * 55)
self._plw.logline("plc: {} started: {}".format(
os.path.basename(self._program), asctime()
))
self._plw.start()
# Befehlstliste aufbauen # Befehlstliste aufbauen
lst_proc = shlex.split("/usr/bin/env {} -OO -u {} {}".format( lst_proc = shlex.split("/usr/bin/env {} -u {} {}".format(
"python2" if self._pversion == 2 else "python3", "python2" if self._pversion == 2 else "python3",
self._program, self._program,
self._arguments self._arguments
@@ -115,29 +124,13 @@ class RevPiPlc(Thread):
proginit.logger.info("start plc program {}".format(self._program)) proginit.logger.info("start plc program {}".format(self._program))
self._procplc = self._spopen(lst_proc) self._procplc = self._spopen(lst_proc)
# RealTime Scheduler nutzen # RealTime Scheduler nutzen nach 5 Sekunden Programmvorlauf
if self.rtlevel > 0 and self._procplc.poll() is None: if self.rtlevel > 0 \
proginit.logger.info( and not self._evt_exit.wait(5) \
"set scheduler profile of pid {}".format(self._procplc.pid) and self._procplc.poll() is None:
) _setuprt(self._procplc.pid, self._evt_exit)
ec = os.system("/usr/bin/env chrt -p {} {}".format(
20 if self.rtlevel == 2 else 1,
self._procplc.pid
))
if ec != 0:
proginit.logger.error(
"could not set scheduler profile of pid {}"
"".format(self._procplc.pid)
)
# LogWriter starten und Logausgaben schreiben
if self._plw is not None:
self._plw.logline("-" * 55)
self._plw.logline("plc: {} started: {}".format(
os.path.basename(self._program), asctime()
))
self._plw.start()
# Überwachung starten
while not self._evt_exit.is_set(): while not self._evt_exit.is_set():
# Auswerten # Auswerten
@@ -179,7 +172,7 @@ class RevPiPlc(Thread):
else: else:
break break
self._evt_exit.wait(1) self._evt_exit.wait(0.5)
if self._plw is not None: if self._plw is not None:
self._plw.logline("-" * 55) self._plw.logline("-" * 55)

View File

@@ -10,6 +10,7 @@ import logging
import os import os
import sys import sys
from argparse import ArgumentParser from argparse import ArgumentParser
from subprocess import Popen, PIPE
forked = False forked = False
globalconffile = None globalconffile = None
@@ -22,6 +23,99 @@ rapcatalog = None
startdir = None startdir = None
def _setuprt(pid, evt_exit):
"""Konfiguriert Programm fuer den RT-Scheduler.
@param pid PID, der angehoben werden soll
@return None"""
if logger is not None:
logger.debug("enter _setuprt()")
dict_change = {
"ksoftirqd/0,ksoftirqd/1,ksoftirqd/2,ksoftirqd/3": 10,
"ktimersoftd/0,ktimersoftd/1,ktimersoftd/2,ktimersoftd/3": 20
}
for ps_change in dict_change:
# pid und prio ermitteln
kpidps = Popen([
"/bin/ps", "-o", "pid=,rtprio=", "-C", ps_change
], bufsize=1, stdout=PIPE)
# Timeout nachbilden da in Python 3.2 nicht vorhanden
count = 10
while kpidps.poll() is None:
count -= 1
if count == 0:
kpidps.kill()
if logger is not None:
logger.error(
"ps timeout to get rt prio info - no rt active"
)
return None
evt_exit.wait(0.5)
if evt_exit.is_set():
return None
try:
kpiddat = kpidps.communicate()[0]
lst_kpids = kpiddat.split()
except:
kpidps.kill()
if logger is not None:
logger.error(
"can not get pid and prio - no rt active"
)
return None
while len(lst_kpids) > 0:
# Elemente paarweise übernehmen
kpid = lst_kpids.pop(0)
kprio = lst_kpids.pop(0)
# Daten prüfen
if not kpid.isdigit():
if logger is not None:
logger.error(
"pid={} and prio={} are not valid - no rt active"
"".format(kpid, kprio)
)
return None
kpid = int(kpid)
# RTPrio ermitteln
if kprio.isdigit():
kprio = int(kprio)
else:
kprio = 0
if kprio < 10:
# Profile anpassen
ec = os.system("/usr/bin/env chrt -fp {} {}".format(
dict_change[ps_change], kpid
))
if ec != 0:
if logger is not None:
logger.error(
"could not adjust scheduler - no rt active"
)
return None
# SCHED_RR für pid setzen
if logger is not None:
logger.info("set scheduler profile of pid {}".format(pid))
ec = os.system("/usr/bin/env chrt -p 1 {}".format(pid))
if ec != 0 and logger is not None:
logger.error(
"could not set scheduler profile of pid {}"
"".format(pid)
)
if logger is not None:
logger.debug("leave _setuprt()")
def _zeroprocimg(): def _zeroprocimg():
"""Setzt Prozessabbild auf NULL.""" """Setzt Prozessabbild auf NULL."""
procimg = "/dev/piControl0" if pargs is None else pargs.procimg procimg = "/dev/piControl0" if pargs is None else pargs.procimg

View File

@@ -165,7 +165,7 @@ class RevPiPyLoad():
self.pythonver = \ self.pythonver = \
int(self.globalconfig["DEFAULT"].get("pythonversion", 3)) int(self.globalconfig["DEFAULT"].get("pythonversion", 3))
self.rtlevel = \ self.rtlevel = \
int(self.globalconfig["DEFAULT"].get("rtlevel", 1)) int(self.globalconfig["DEFAULT"].get("rtlevel", 0))
self.xmlrpc = \ self.xmlrpc = \
int(self.globalconfig["DEFAULT"].get("xmlrpc", 0)) int(self.globalconfig["DEFAULT"].get("xmlrpc", 0))
@@ -185,6 +185,10 @@ class RevPiPyLoad():
int(self.globalconfig["DEFAULT"].get("zeroonexit", 1)) int(self.globalconfig["DEFAULT"].get("zeroonexit", 1))
# Workdirectory wechseln # Workdirectory wechseln
if not os.access(self.plcworkdir, os.R_OK | os.W_OK | os.X_OK):
raise ValueError(
"can not access plcworkdir '{}'".format(self.plcworkdir)
)
os.chdir(self.plcworkdir) os.chdir(self.plcworkdir)
# PLC Thread konfigurieren # PLC Thread konfigurieren
@@ -666,7 +670,7 @@ class RevPiPyLoad():
"plcslaveacl": re_ipacl, "plcslaveacl": re_ipacl,
"plcslaveport": "[0-9]{,5}", "plcslaveport": "[0-9]{,5}",
"pythonversion": "[23]", "pythonversion": "[23]",
"rtlevel": "[0-2]", "rtlevel": "[0-1]",
"xmlrpc": "[0-3]", "xmlrpc": "[0-3]",
"xmlrpcacl": re_ipacl, "xmlrpcacl": re_ipacl,
"zeroonerror": "[01]", "zeroonerror": "[01]",