mirror of
https://github.com/naruxde/revpimodio2.git
synced 2025-11-08 13:53: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>Gibt aktuellen Timeout zurueck.</td>
|
||||
</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>Daten ueber das Netzwerk lesen.</td>
|
||||
</tr><tr>
|
||||
@@ -227,6 +230,20 @@ Gibt aktuellen Timeout zurueck.
|
||||
<dd>
|
||||
<class 'int'> in Millisekunden
|
||||
</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>
|
||||
<h3 style="background-color:#FFFFFF;color:#FF0000">
|
||||
NetFH.read</h3>
|
||||
|
||||
@@ -183,6 +183,7 @@ revpimodio2.netio.NetFH.flush?4()
|
||||
revpimodio2.netio.NetFH.get_closed?4()
|
||||
revpimodio2.netio.NetFH.get_name?4()
|
||||
revpimodio2.netio.NetFH.get_timeout?4()
|
||||
revpimodio2.netio.NetFH.ioctl?4(request, arg=b'')
|
||||
revpimodio2.netio.NetFH.name?7
|
||||
revpimodio2.netio.NetFH.read?4(length)
|
||||
revpimodio2.netio.NetFH.readpictory?4()
|
||||
|
||||
@@ -877,17 +877,8 @@ class DioModule(Device):
|
||||
"""Erweitert Device-Klasse zum Erkennen von IntIOCounter.
|
||||
@see #Device.__init__ Device.__init__(...)"""
|
||||
|
||||
# Stringliste der Byteadressen
|
||||
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)))
|
||||
elif producttype == 97:
|
||||
# DI - Counter auf DINT 4 - 64
|
||||
self._lst_counter = list(map(str, range(4, 68, 4)))
|
||||
# Stringliste der Byteadressen (alle Module sind gleich)
|
||||
self._lst_counter = list(map(str, range(6, 70, 4)))
|
||||
|
||||
# Basisklasse laden
|
||||
super().__init__(parentmodio, dict_device, simulator=simulator)
|
||||
@@ -964,8 +955,8 @@ class Virtual(Gateway):
|
||||
self._ba_devdata[io._slc_address] = io._defaultvalue
|
||||
|
||||
# Outputs auf Bus schreiben
|
||||
self._modio._myfh_lck.acquire()
|
||||
try:
|
||||
# TODO: globalen FileHandler absichern
|
||||
self._modio._myfh.seek(self._slc_inpoff.start)
|
||||
self._modio._myfh.write(self._ba_devdata[self._slc_inp])
|
||||
if self._modio._buffedwrite:
|
||||
@@ -973,6 +964,8 @@ class Virtual(Gateway):
|
||||
except IOError:
|
||||
self._modio._gotioerror("write")
|
||||
workokay = False
|
||||
finally:
|
||||
self._modio._myfh_lck.release()
|
||||
|
||||
self._filelock.release()
|
||||
return workokay
|
||||
|
||||
@@ -830,22 +830,30 @@ class IntIOCounter(IntIO):
|
||||
)
|
||||
|
||||
if isinstance(self._parentdevice._modio, RevPiNetIO):
|
||||
# TODO: NetFH ansprechen und an RevPiPyLoad senden
|
||||
warnings.warn("not jet implemented", FutureWarning)
|
||||
# IOCTL über Netzwerk
|
||||
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":
|
||||
# NOTE: Soll hier eine 0 in den Input geschrieben werden?
|
||||
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:
|
||||
# Counter reset durchführen (Funktion K+20)
|
||||
# TODO: globalen FileHandler absichern
|
||||
ioctl(self._parentdevice._modio._myfh, 19220, self.__ioctl_arg)
|
||||
# IOCTL auf dem RevPi
|
||||
with self._parentdevice._modio._myfh_lck:
|
||||
try:
|
||||
# Counter reset durchführen (Funktion K+20)
|
||||
ioctl(
|
||||
self._parentdevice._modio._myfh,
|
||||
19220, self.__ioctl_arg
|
||||
)
|
||||
except Exception:
|
||||
self._parentdevice._modio._gotioerror("ioctl")
|
||||
|
||||
|
||||
class IntIOReplaceable(IntIO):
|
||||
|
||||
@@ -10,7 +10,7 @@ from multiprocessing import cpu_count
|
||||
from os import access, F_OK, R_OK
|
||||
from queue import Empty
|
||||
from signal import signal, SIG_DFL, SIGINT, SIGTERM
|
||||
from threading import Thread, Event
|
||||
from threading import Thread, Event, Lock
|
||||
from timeit import default_timer
|
||||
|
||||
|
||||
@@ -30,8 +30,8 @@ class RevPiModIO(object):
|
||||
__slots__ = "__cleanupfunc", "_autorefresh", "_buffedwrite", \
|
||||
"_configrsc", "_exit", "_imgwriter", "_ioerror", "_length", \
|
||||
"_looprunning", "_lst_devselect", "_lst_refresh", "_maxioerrors", \
|
||||
"_myfh", "_monitoring", "_procimg", "_simulator", "_syncoutputs", \
|
||||
"_th_mainloop", "_waitexit", \
|
||||
"_myfh", "_myfh_lck", "_monitoring", "_procimg", "_simulator", \
|
||||
"_syncoutputs", "_th_mainloop", "_waitexit", \
|
||||
"core", "app", "device", "exitsignal", "io", "summary"
|
||||
|
||||
def __init__(
|
||||
@@ -68,6 +68,7 @@ class RevPiModIO(object):
|
||||
self._lst_refresh = []
|
||||
self._maxioerrors = 0
|
||||
self._myfh = None
|
||||
self._myfh_lck = Lock()
|
||||
self._th_mainloop = None
|
||||
self._waitexit = Event()
|
||||
|
||||
@@ -162,17 +163,18 @@ class RevPiModIO(object):
|
||||
dev_new = devicemodule.Core(
|
||||
self, device, simulator=self._simulator
|
||||
)
|
||||
self.core = dev_new
|
||||
elif pt == 105:
|
||||
# RevPi Connect
|
||||
dev_new = devicemodule.Connect(
|
||||
self, device, simulator=self._simulator
|
||||
)
|
||||
self.core = dev_new
|
||||
else:
|
||||
# Base immer als Fallback verwenden
|
||||
dev_new = devicemodule.Base(
|
||||
self, device, simulator=self._simulator
|
||||
)
|
||||
self.core = dev_new
|
||||
elif device["type"] == "LEFT_RIGHT":
|
||||
# IOs
|
||||
pt = int(device["productType"])
|
||||
@@ -687,12 +689,15 @@ class RevPiModIO(object):
|
||||
mylist = [dev]
|
||||
|
||||
# Daten komplett einlesen
|
||||
self._myfh_lck.acquire()
|
||||
try:
|
||||
self._myfh.seek(0)
|
||||
bytesbuff = self._myfh.read(self._length)
|
||||
except IOError:
|
||||
self._gotioerror("read")
|
||||
return False
|
||||
finally:
|
||||
self._myfh_lck.release()
|
||||
|
||||
for dev in mylist:
|
||||
if not dev._selfupdate:
|
||||
@@ -761,12 +766,15 @@ class RevPiModIO(object):
|
||||
)
|
||||
mylist = [dev]
|
||||
|
||||
self._myfh_lck.acquire()
|
||||
try:
|
||||
self._myfh.seek(0)
|
||||
bytesbuff = self._myfh.read(self._length)
|
||||
except IOError:
|
||||
self._gotioerror("read")
|
||||
return False
|
||||
finally:
|
||||
self._myfh_lck.release()
|
||||
|
||||
for dev in mylist:
|
||||
if not dev._selfupdate:
|
||||
@@ -810,11 +818,14 @@ class RevPiModIO(object):
|
||||
dev._filelock.acquire()
|
||||
|
||||
# Outpus auf Bus schreiben
|
||||
self._myfh_lck.acquire()
|
||||
try:
|
||||
self._myfh.seek(dev._slc_outoff.start)
|
||||
self._myfh.write(dev._ba_devdata[dev._slc_out])
|
||||
except IOError:
|
||||
workokay = False
|
||||
finally:
|
||||
self._myfh_lck.release()
|
||||
|
||||
dev._filelock.release()
|
||||
|
||||
|
||||
@@ -243,6 +243,37 @@ class NetFH(Thread):
|
||||
@return <class 'int'> in Millisekunden"""
|
||||
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):
|
||||
"""Daten ueber das Netzwerk lesen.
|
||||
@param length Anzahl der Bytes
|
||||
|
||||
Reference in New Issue
Block a user