mirror of
https://github.com/naruxde/revpimodio2.git
synced 2025-11-08 22:03:53 +01:00
.core wird nur gesetzt, wenn gültiges Basedevice erkannt wurde
Globalen FileHandler durch Lock gesichert IOCTL über das Netzwerk umgesetzt
This commit is contained in:
@@ -98,6 +98,9 @@ Methods</h3>
|
|||||||
<td><a style="color:#0000FF" href="#NetFH.get_timeout">get_timeout</a></td>
|
<td><a style="color:#0000FF" href="#NetFH.get_timeout">get_timeout</a></td>
|
||||||
<td>Gibt aktuellen Timeout zurueck.</td>
|
<td>Gibt aktuellen Timeout zurueck.</td>
|
||||||
</tr><tr>
|
</tr><tr>
|
||||||
|
<td><a style="color:#0000FF" href="#NetFH.ioctl">ioctl</a></td>
|
||||||
|
<td>IOCTL Befehle ueber das Netzwerk senden.</td>
|
||||||
|
</tr><tr>
|
||||||
<td><a style="color:#0000FF" href="#NetFH.read">read</a></td>
|
<td><a style="color:#0000FF" href="#NetFH.read">read</a></td>
|
||||||
<td>Daten ueber das Netzwerk lesen.</td>
|
<td>Daten ueber das Netzwerk lesen.</td>
|
||||||
</tr><tr>
|
</tr><tr>
|
||||||
@@ -227,6 +230,20 @@ Gibt aktuellen Timeout zurueck.
|
|||||||
<dd>
|
<dd>
|
||||||
<class 'int'> in Millisekunden
|
<class 'int'> in Millisekunden
|
||||||
</dd>
|
</dd>
|
||||||
|
</dl><a NAME="NetFH.ioctl" ID="NetFH.ioctl"></a>
|
||||||
|
<h3 style="background-color:#FFFFFF;color:#FF0000">
|
||||||
|
NetFH.ioctl</h3>
|
||||||
|
<b>ioctl</b>(<i>request, arg=b''</i>)
|
||||||
|
<p>
|
||||||
|
IOCTL Befehle ueber das Netzwerk senden.
|
||||||
|
</p><dl>
|
||||||
|
<dt><i>request</i></dt>
|
||||||
|
<dd>
|
||||||
|
Request as <class 'int'>
|
||||||
|
</dd><dt><i>arg</i></dt>
|
||||||
|
<dd>
|
||||||
|
Argument as <class 'byte'>
|
||||||
|
</dd>
|
||||||
</dl><a NAME="NetFH.read" ID="NetFH.read"></a>
|
</dl><a NAME="NetFH.read" ID="NetFH.read"></a>
|
||||||
<h3 style="background-color:#FFFFFF;color:#FF0000">
|
<h3 style="background-color:#FFFFFF;color:#FF0000">
|
||||||
NetFH.read</h3>
|
NetFH.read</h3>
|
||||||
|
|||||||
@@ -183,6 +183,7 @@ revpimodio2.netio.NetFH.flush?4()
|
|||||||
revpimodio2.netio.NetFH.get_closed?4()
|
revpimodio2.netio.NetFH.get_closed?4()
|
||||||
revpimodio2.netio.NetFH.get_name?4()
|
revpimodio2.netio.NetFH.get_name?4()
|
||||||
revpimodio2.netio.NetFH.get_timeout?4()
|
revpimodio2.netio.NetFH.get_timeout?4()
|
||||||
|
revpimodio2.netio.NetFH.ioctl?4(request, arg=b'')
|
||||||
revpimodio2.netio.NetFH.name?7
|
revpimodio2.netio.NetFH.name?7
|
||||||
revpimodio2.netio.NetFH.read?4(length)
|
revpimodio2.netio.NetFH.read?4(length)
|
||||||
revpimodio2.netio.NetFH.readpictory?4()
|
revpimodio2.netio.NetFH.readpictory?4()
|
||||||
|
|||||||
@@ -877,17 +877,8 @@ class DioModule(Device):
|
|||||||
"""Erweitert Device-Klasse zum Erkennen von IntIOCounter.
|
"""Erweitert Device-Klasse zum Erkennen von IntIOCounter.
|
||||||
@see #Device.__init__ Device.__init__(...)"""
|
@see #Device.__init__ Device.__init__(...)"""
|
||||||
|
|
||||||
# Stringliste der Byteadressen
|
# Stringliste der Byteadressen (alle Module sind gleich)
|
||||||
self._lst_counter = []
|
|
||||||
|
|
||||||
# Counter sind 4 Byte lang
|
|
||||||
producttype = int(dict_device.get("productType"))
|
|
||||||
if producttype == 96:
|
|
||||||
# DIO - Counter auf DINT 6 - 66
|
|
||||||
self._lst_counter = list(map(str, range(6, 70, 4)))
|
self._lst_counter = list(map(str, range(6, 70, 4)))
|
||||||
elif producttype == 97:
|
|
||||||
# DI - Counter auf DINT 4 - 64
|
|
||||||
self._lst_counter = list(map(str, range(4, 68, 4)))
|
|
||||||
|
|
||||||
# Basisklasse laden
|
# Basisklasse laden
|
||||||
super().__init__(parentmodio, dict_device, simulator=simulator)
|
super().__init__(parentmodio, dict_device, simulator=simulator)
|
||||||
@@ -964,8 +955,8 @@ class Virtual(Gateway):
|
|||||||
self._ba_devdata[io._slc_address] = io._defaultvalue
|
self._ba_devdata[io._slc_address] = io._defaultvalue
|
||||||
|
|
||||||
# Outputs auf Bus schreiben
|
# Outputs auf Bus schreiben
|
||||||
|
self._modio._myfh_lck.acquire()
|
||||||
try:
|
try:
|
||||||
# TODO: globalen FileHandler absichern
|
|
||||||
self._modio._myfh.seek(self._slc_inpoff.start)
|
self._modio._myfh.seek(self._slc_inpoff.start)
|
||||||
self._modio._myfh.write(self._ba_devdata[self._slc_inp])
|
self._modio._myfh.write(self._ba_devdata[self._slc_inp])
|
||||||
if self._modio._buffedwrite:
|
if self._modio._buffedwrite:
|
||||||
@@ -973,6 +964,8 @@ class Virtual(Gateway):
|
|||||||
except IOError:
|
except IOError:
|
||||||
self._modio._gotioerror("write")
|
self._modio._gotioerror("write")
|
||||||
workokay = False
|
workokay = False
|
||||||
|
finally:
|
||||||
|
self._modio._myfh_lck.release()
|
||||||
|
|
||||||
self._filelock.release()
|
self._filelock.release()
|
||||||
return workokay
|
return workokay
|
||||||
|
|||||||
@@ -830,22 +830,30 @@ class IntIOCounter(IntIO):
|
|||||||
)
|
)
|
||||||
|
|
||||||
if isinstance(self._parentdevice._modio, RevPiNetIO):
|
if isinstance(self._parentdevice._modio, RevPiNetIO):
|
||||||
# TODO: NetFH ansprechen und an RevPiPyLoad senden
|
# IOCTL über Netzwerk
|
||||||
warnings.warn("not jet implemented", FutureWarning)
|
with self._parentdevice._modio._myfh_lck:
|
||||||
|
try:
|
||||||
|
self._parentdevice._modio._myfh.ioctl(
|
||||||
|
19220, self.__ioctl_arg
|
||||||
|
)
|
||||||
|
except Exception:
|
||||||
|
self._parentdevice._modio._gotioerror("net_ioctl")
|
||||||
|
|
||||||
elif self._parentdevice._modio._procimg != "/dev/piControl0":
|
elif self._parentdevice._modio._procimg != "/dev/piControl0":
|
||||||
# NOTE: Soll hier eine 0 in den Input geschrieben werden?
|
# NOTE: Soll hier eine 0 in den Input geschrieben werden?
|
||||||
warnings.warn("this will work on a revolution pi only")
|
warnings.warn("this will work on a revolution pi only")
|
||||||
|
|
||||||
elif ioctl is None:
|
|
||||||
raise RuntimeError(
|
|
||||||
"can not reset counter on this system without ioctl"
|
|
||||||
)
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
# IOCTL auf dem RevPi
|
||||||
|
with self._parentdevice._modio._myfh_lck:
|
||||||
|
try:
|
||||||
# Counter reset durchführen (Funktion K+20)
|
# Counter reset durchführen (Funktion K+20)
|
||||||
# TODO: globalen FileHandler absichern
|
ioctl(
|
||||||
ioctl(self._parentdevice._modio._myfh, 19220, self.__ioctl_arg)
|
self._parentdevice._modio._myfh,
|
||||||
|
19220, self.__ioctl_arg
|
||||||
|
)
|
||||||
|
except Exception:
|
||||||
|
self._parentdevice._modio._gotioerror("ioctl")
|
||||||
|
|
||||||
|
|
||||||
class IntIOReplaceable(IntIO):
|
class IntIOReplaceable(IntIO):
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ from multiprocessing import cpu_count
|
|||||||
from os import access, F_OK, R_OK
|
from os import access, F_OK, R_OK
|
||||||
from queue import Empty
|
from queue import Empty
|
||||||
from signal import signal, SIG_DFL, SIGINT, SIGTERM
|
from signal import signal, SIG_DFL, SIGINT, SIGTERM
|
||||||
from threading import Thread, Event
|
from threading import Thread, Event, Lock
|
||||||
from timeit import default_timer
|
from timeit import default_timer
|
||||||
|
|
||||||
|
|
||||||
@@ -30,8 +30,8 @@ class RevPiModIO(object):
|
|||||||
__slots__ = "__cleanupfunc", "_autorefresh", "_buffedwrite", \
|
__slots__ = "__cleanupfunc", "_autorefresh", "_buffedwrite", \
|
||||||
"_configrsc", "_exit", "_imgwriter", "_ioerror", "_length", \
|
"_configrsc", "_exit", "_imgwriter", "_ioerror", "_length", \
|
||||||
"_looprunning", "_lst_devselect", "_lst_refresh", "_maxioerrors", \
|
"_looprunning", "_lst_devselect", "_lst_refresh", "_maxioerrors", \
|
||||||
"_myfh", "_monitoring", "_procimg", "_simulator", "_syncoutputs", \
|
"_myfh", "_myfh_lck", "_monitoring", "_procimg", "_simulator", \
|
||||||
"_th_mainloop", "_waitexit", \
|
"_syncoutputs", "_th_mainloop", "_waitexit", \
|
||||||
"core", "app", "device", "exitsignal", "io", "summary"
|
"core", "app", "device", "exitsignal", "io", "summary"
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
@@ -68,6 +68,7 @@ class RevPiModIO(object):
|
|||||||
self._lst_refresh = []
|
self._lst_refresh = []
|
||||||
self._maxioerrors = 0
|
self._maxioerrors = 0
|
||||||
self._myfh = None
|
self._myfh = None
|
||||||
|
self._myfh_lck = Lock()
|
||||||
self._th_mainloop = None
|
self._th_mainloop = None
|
||||||
self._waitexit = Event()
|
self._waitexit = Event()
|
||||||
|
|
||||||
@@ -162,17 +163,18 @@ class RevPiModIO(object):
|
|||||||
dev_new = devicemodule.Core(
|
dev_new = devicemodule.Core(
|
||||||
self, device, simulator=self._simulator
|
self, device, simulator=self._simulator
|
||||||
)
|
)
|
||||||
|
self.core = dev_new
|
||||||
elif pt == 105:
|
elif pt == 105:
|
||||||
# RevPi Connect
|
# RevPi Connect
|
||||||
dev_new = devicemodule.Connect(
|
dev_new = devicemodule.Connect(
|
||||||
self, device, simulator=self._simulator
|
self, device, simulator=self._simulator
|
||||||
)
|
)
|
||||||
|
self.core = dev_new
|
||||||
else:
|
else:
|
||||||
# Base immer als Fallback verwenden
|
# Base immer als Fallback verwenden
|
||||||
dev_new = devicemodule.Base(
|
dev_new = devicemodule.Base(
|
||||||
self, device, simulator=self._simulator
|
self, device, simulator=self._simulator
|
||||||
)
|
)
|
||||||
self.core = dev_new
|
|
||||||
elif device["type"] == "LEFT_RIGHT":
|
elif device["type"] == "LEFT_RIGHT":
|
||||||
# IOs
|
# IOs
|
||||||
pt = int(device["productType"])
|
pt = int(device["productType"])
|
||||||
@@ -687,12 +689,15 @@ class RevPiModIO(object):
|
|||||||
mylist = [dev]
|
mylist = [dev]
|
||||||
|
|
||||||
# Daten komplett einlesen
|
# Daten komplett einlesen
|
||||||
|
self._myfh_lck.acquire()
|
||||||
try:
|
try:
|
||||||
self._myfh.seek(0)
|
self._myfh.seek(0)
|
||||||
bytesbuff = self._myfh.read(self._length)
|
bytesbuff = self._myfh.read(self._length)
|
||||||
except IOError:
|
except IOError:
|
||||||
self._gotioerror("read")
|
self._gotioerror("read")
|
||||||
return False
|
return False
|
||||||
|
finally:
|
||||||
|
self._myfh_lck.release()
|
||||||
|
|
||||||
for dev in mylist:
|
for dev in mylist:
|
||||||
if not dev._selfupdate:
|
if not dev._selfupdate:
|
||||||
@@ -761,12 +766,15 @@ class RevPiModIO(object):
|
|||||||
)
|
)
|
||||||
mylist = [dev]
|
mylist = [dev]
|
||||||
|
|
||||||
|
self._myfh_lck.acquire()
|
||||||
try:
|
try:
|
||||||
self._myfh.seek(0)
|
self._myfh.seek(0)
|
||||||
bytesbuff = self._myfh.read(self._length)
|
bytesbuff = self._myfh.read(self._length)
|
||||||
except IOError:
|
except IOError:
|
||||||
self._gotioerror("read")
|
self._gotioerror("read")
|
||||||
return False
|
return False
|
||||||
|
finally:
|
||||||
|
self._myfh_lck.release()
|
||||||
|
|
||||||
for dev in mylist:
|
for dev in mylist:
|
||||||
if not dev._selfupdate:
|
if not dev._selfupdate:
|
||||||
@@ -810,11 +818,14 @@ class RevPiModIO(object):
|
|||||||
dev._filelock.acquire()
|
dev._filelock.acquire()
|
||||||
|
|
||||||
# Outpus auf Bus schreiben
|
# Outpus auf Bus schreiben
|
||||||
|
self._myfh_lck.acquire()
|
||||||
try:
|
try:
|
||||||
self._myfh.seek(dev._slc_outoff.start)
|
self._myfh.seek(dev._slc_outoff.start)
|
||||||
self._myfh.write(dev._ba_devdata[dev._slc_out])
|
self._myfh.write(dev._ba_devdata[dev._slc_out])
|
||||||
except IOError:
|
except IOError:
|
||||||
workokay = False
|
workokay = False
|
||||||
|
finally:
|
||||||
|
self._myfh_lck.release()
|
||||||
|
|
||||||
dev._filelock.release()
|
dev._filelock.release()
|
||||||
|
|
||||||
|
|||||||
@@ -243,6 +243,37 @@ class NetFH(Thread):
|
|||||||
@return <class 'int'> in Millisekunden"""
|
@return <class 'int'> in Millisekunden"""
|
||||||
return int(self.__timeout * 1000)
|
return int(self.__timeout * 1000)
|
||||||
|
|
||||||
|
def ioctl(self, request, arg=b''):
|
||||||
|
"""IOCTL Befehle ueber das Netzwerk senden.
|
||||||
|
@param request Request as <class 'int'>
|
||||||
|
@param arg Argument as <class 'byte'>"""
|
||||||
|
if self.__sockend:
|
||||||
|
raise ValueError("read of closed file")
|
||||||
|
|
||||||
|
if not (isinstance(arg, bytes) and len(arg) <= 1024):
|
||||||
|
raise ValueError("arg must be <class 'bytes'>")
|
||||||
|
|
||||||
|
with self.__socklock:
|
||||||
|
self._slavesock.send(
|
||||||
|
b'\x01IC' +
|
||||||
|
request.to_bytes(length=4, byteorder="little") +
|
||||||
|
len(arg).to_bytes(length=2, byteorder="little") +
|
||||||
|
b'\x00\x00\x00\x00\x00\x00\x17'
|
||||||
|
)
|
||||||
|
self._slavesock.sendall(arg)
|
||||||
|
|
||||||
|
# Rückmeldebyte auswerten
|
||||||
|
check = self._slavesock.recv(1)
|
||||||
|
if check != b'\x1e':
|
||||||
|
|
||||||
|
# ACL prüfen und ggf Fehler werfen
|
||||||
|
self.__check_acl(check)
|
||||||
|
|
||||||
|
self.__sockerr.set()
|
||||||
|
raise IOError("ioctl error on network")
|
||||||
|
|
||||||
|
self.__trigger = True
|
||||||
|
|
||||||
def read(self, length):
|
def read(self, length):
|
||||||
"""Daten ueber das Netzwerk lesen.
|
"""Daten ueber das Netzwerk lesen.
|
||||||
@param length Anzahl der Bytes
|
@param length Anzahl der Bytes
|
||||||
|
|||||||
Reference in New Issue
Block a user