mirror of
https://github.com/naruxde/revpipyload.git
synced 2025-11-08 23:23:52 +01:00
RTLevel default 0 (aus)
Workdirectory prüfen vor dem Wechseln Optimierung -OO entfernt _setuprt(...) um ksoftirqd und ktimersoftd auf höhere Prioritäten zu ziehen Python PLC Programm kann max auf Prio RR 1 laufen
This commit is contained in:
@@ -8,7 +8,7 @@ plcuid = 1000
|
|||||||
plcgid = 1000
|
plcgid = 1000
|
||||||
plcslave = 0
|
plcslave = 0
|
||||||
pythonversion = 3
|
pythonversion = 3
|
||||||
rtlevel = 1
|
rtlevel = 0
|
||||||
xmlrpc = 0
|
xmlrpc = 0
|
||||||
zeroonerror = 0
|
zeroonerror = 0
|
||||||
zeroonexit = 0
|
zeroonexit = 0
|
||||||
|
|||||||
@@ -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>)
|
||||||
|
|||||||
@@ -24,6 +24,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()
|
||||||
|
|||||||
@@ -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-17, 11:21:23 -->
|
<!-- 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>
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
<ProgLanguage mixed="0">Python3</ProgLanguage>
|
<ProgLanguage mixed="0">Python3</ProgLanguage>
|
||||||
<ProjectType>Console</ProjectType>
|
<ProjectType>Console</ProjectType>
|
||||||
<Description>Dieser Loader wird über das Init-System geladen und führt das angegebene Pythonprogramm aus. Es ist für den RevolutionPi gedacht um automatisch das SPS-Programm zu starten.</Description>
|
<Description>Dieser Loader wird über das Init-System geladen und führt das angegebene Pythonprogramm aus. Es ist für den RevolutionPi gedacht um automatisch das SPS-Programm zu starten.</Description>
|
||||||
<Version>0.4.3</Version>
|
<Version>0.4.6</Version>
|
||||||
<Author>Sven Sager</Author>
|
<Author>Sven Sager</Author>
|
||||||
<Email>akira@narux.de</Email>
|
<Email>akira@narux.de</Email>
|
||||||
<Eol index="1"/>
|
<Eol index="1"/>
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ from time import asctime
|
|||||||
from xmlrpc.client import Binary
|
from xmlrpc.client import Binary
|
||||||
from xmlrpc.server import SimpleXMLRPCServer
|
from xmlrpc.server import SimpleXMLRPCServer
|
||||||
|
|
||||||
pyloadversion = "0.4.5"
|
pyloadversion = "0.4.6"
|
||||||
|
|
||||||
|
|
||||||
class RevPiPyLoad():
|
class RevPiPyLoad():
|
||||||
@@ -124,7 +124,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))
|
||||||
self.zeroonerror = \
|
self.zeroonerror = \
|
||||||
@@ -133,6 +133,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
|
||||||
@@ -569,7 +573,7 @@ class RevPiPyLoad():
|
|||||||
"plcarguments": ".*",
|
"plcarguments": ".*",
|
||||||
"plcslave": "[01]",
|
"plcslave": "[01]",
|
||||||
"pythonversion": "[23]",
|
"pythonversion": "[23]",
|
||||||
"rtlevel": "[0-2]",
|
"rtlevel": "[0-1]",
|
||||||
"xmlrpc": "[0-3]",
|
"xmlrpc": "[0-3]",
|
||||||
"zeroonerror": "[01]",
|
"zeroonerror": "[01]",
|
||||||
"zeroonexit": "[01]"
|
"zeroonexit": "[01]"
|
||||||
|
|||||||
Reference in New Issue
Block a user