ttyS0 gepuffert(?) lesen?

01/03/2016 - 23:05 von Nico Hoffmann | Report spam
Hallo,

ich bastle etwas mit der bash und stehe gerade irgendwie auf dem
Schlauch.

Es geht erstmal um eine while-Schleife.

In der Schleife muß ich ein Programm aufrufen, was ein oder zwei
Minuten làuft.

Dann muß ich überprüfen, ob bei der Gegenstelle Probleme aufgetreten
sind, was sie mit Daten über ein serielles Kabel anzeigt.

Die Gegenstelle schickt kontinuierlich mehrmals in der Sekunde ein (1)
Zeichen. "A" heißt soviel wie "ich bin da und es geht mir gut", und
"X" bedeutet "ich bin da, aber es gibt Schwierigkeiten". Kommt gar
nichts, dann ist meine kleine Welt untergegangen :-)

Abhàngig davon, was die Gegenstelle signalisiert, muß ich das
Ein-oder-Zwei-Minuten-Programm im nàchsten Schleifendurchlauf erneut
aufrufen oder warten oder ganz abbrechen.

Im interessanten Fall kommt aus /dev/ttyS0 also sowas

A
A
A
A
A
X
X
A
X
A
A
[...]

wàhrend das Ein-oder-Zwei-Minuten-Programm làuft.

Leider sind die Zeitverhàltnisse nicht ganz scharf, ich weiß also
nicht, wieviele Zeichen über die serielle Schnittstelle gekommen sind,
seit ich das letzte Mal abgefragt habe.

Ich habe jetzt mit sowas

while [ 1 ]; do
RDIN=`dd if=/dev/ttyS0 count%`
echo $RDIN | grep X
if [ $? -eq 0 ]; then
echo "Found X!"
else
echo "No X!"
fi
sleep 10 ### hier steht eigentlich das Ein-oder-Zwei-Minuten-Programm
done

experimentiert, aber mit "count%" habe ich evtl. nicht alle neuen
Zeichen gelesen oder noch Zeichen vom letzten Zyklus mit drin.

Ich müßte eigentlich eine Art Puffer haben, den ich in jedem Durchlauf
auslese und dann leere. Wàhrend das Ein-oder-Zwei-Minuten-Programm
làuft, wird er wieder beschrieben.
Allerdings fehlt mir die Idee, wie sowas umzusetzen ist.

Hat jemand einen Tipp für mich?

N.
Dies ist keine echte Signatur, aber immerhin eine sehr gute Fàlschung.
 

Lesen sie die antworten

#1 Juergen P. Meier
02/03/2016 - 06:37 | Warnen spam
Nico Hoffmann :
ich bastle etwas mit der bash und stehe gerade irgendwie auf dem
Schlauch.

while [ 1 ]; do
RDIN=`dd if=/dev/ttyS0 count%`
echo $RDIN | grep X
if [ $? -eq 0 ]; then
echo "Found X!"
else
echo "No X!"
fi
sleep 10 ### hier steht eigentlich das Ein-oder-Zwei-Minuten-Programm
done

experimentiert, aber mit "count%" habe ich evtl. nicht alle neuen
Zeichen gelesen oder noch Zeichen vom letzten Zyklus mit drin.

Ich müßte eigentlich eine Art Puffer haben, den ich in jedem Durchlauf
auslese und dann leere. Wàhrend das Ein-oder-Zwei-Minuten-Programm
làuft, wird er wieder beschrieben.
Allerdings fehlt mir die Idee, wie sowas umzusetzen ist.



Dein Problem scheint mir zu sein, dass du die Shellabarbeitung
unterbrichst, waehrend du die Zeichen einliest (ttyS0 ist ungepuffert,
und dd ohne weitere Optionen bricht ab wenn nix mehr kommt), und zum
Weiterarbeiten in der Shell das einlesen abbrechen musst.

Einfacher waere es, wenn du zwei Threads laufen lassen koenntest,
die gepuffert mit einander kommunizieren, einer der ungepuffert von
ttyS0 liest und einen mit der Programmlogik als Schleife, der auch das
Ein-oder-Zweiminutenprogramm steuert.

Das geht Shell nur mit Co-Prozessen.

Hat jemand einen Tipp für mich?



Also ich wuerde das mit ksh und Coprocess* machen, oder gleich
ein C-Programm schreiben (ok, ich wuerde erstes machen und nur wenn
das nicht funktioniert zu C greiffen).

Im Web gibts Beispiele wie du sowohl buffered als auch ubuffered
mit Coprozessen arbeiten kannst.

* Coprocesses ist ein Feature der KSH, es gibt das wohl auch in zsh
und sogar in bash ab Version 4 (coproc), die Umsetzung in bash
sieht mir deutlich weniger Elegant und ziemlich Fehlerhaft im
Vergleich zu ksh (und wohl auch zsh) zu sein (10 Sek. Webrecherche).

HTH
Juergen
Juergen P. Meier - "This World is about to be Destroyed!"
end
If you think technology can solve your problems you don't understand
technology and you don't understand your problems. (Bruce Schneier)

Ähnliche fragen