Forum: PC-Programmierung Mit der Bash Binärzahlen auf Com Port ausgeben


von Christian J. (Gast)


Lesenswert?

Hallo,

ich stehe vor folgedem Problem einem Controler am USB ein Programm zu 
übermitteln und dabei das Ende der daten zu signalisieren. Protokoll ist 
so billig wie nur möglich:

s     = Startzeichen
nnnn  = 2 Bytes für Datenlängae
nnnn x 1 Byte Datentransfer
Ende

Bisher bin ich nur soweit:

echo "s" > dev/ttyUSB0
stat -c %s binaer.bin > /dev/tty
cat daten.bin > /dev/ttyUSB0

Wertebereich Datenlänge = 1 .... ca 40000.

der stat Ausdruck überträgt halt nur die Dateilänge als String mit 
variabler Länge, den ich wieder umständlich in eine Binärzahl umbauen 
müsste, zudem ich nur Zeichen und keine Strings variabler Länge 
empfangen kann. der Asm Code soll so knapp wie möglich auf der 
Empfängerseite sein, 2  chars, zusammenbauen zu einem int und fertig.

Wie müsste man es formulieren, dass der stat Ausdruck das binäre 
Aquivalent zu der Dateilänge ausgibt?

gruss,
Christian

von Klaus (Gast)


Lesenswert?

Für solche Aufgaben ist die bash oder auch jede andere shell das falsche 
Schwert. Was z.B. passiert, wenn dir zwischen "echo ..." und "stat ..." 
ein anderer Prozess den Port klaut?

MfG Klaus

von Christian J. (Gast)


Lesenswert?

Der Port wird nicht geklaut, der ist ein Usb Stecker. Das Ganze geht 
auch als C Program aber dann wird es richtig aufwendig.....

von Test (Gast)


Lesenswert?

nimm doch einfach python statt nem bash script...

von Christian J. (Gast)


Lesenswert?

Ich kann kein neumodisches Python :-(

von Bernd K. (prof7bit)


Lesenswert?

Christian J. schrieb:
> Ich kann kein neumodisches Python :-(

Dann nimm halt das klassische Python 2.x

von ByteByte (Gast)


Lesenswert?

Hallo Christian,

Christian J. schrieb:
>
> s     = Startzeichen
> nnnn  = 2 Bytes für Datenlängae
> nnnn x 1 Byte Datentransfer
> Ende
>
> Bisher bin ich nur soweit:
>
> echo "s" > dev/ttyUSB0
> stat -c %s binaer.bin > /dev/tty
> cat daten.bin > /dev/ttyUSB0

und zum schluss noch:

echo "nnnn" Ende

must du natürlich im Kontoler definieren...

Oder habe ich da was falsch verstanden??

von Stefan L. (timpi)


Lesenswert?

printf %08x $(stat -c %s binaer.bin > /dev/tty

oder auch nur '04x' je nachdem wir groß binaer.bin maximal werden kann.

Damit hast Du wenigstens eine bekannte Länge des Feldes.

: Bearbeitet durch User
von Daniel A. (daniel-a)


Lesenswert?

Klaus schrieb:
> Was z.B. passiert, wenn dir zwischen "echo ..." und "stat ..."
> ein anderer Prozess den Port klaut?

Ich denke dass sollte sich einfach verhindern lassen:
{
  echo ...
  stat ...
} > /dev/tty

von Kaj (Gast)


Lesenswert?

Christian J. schrieb:
> neumodisches Python
Naja, so "neumodisch" ist das nun auch nicht, gibts immerhin (laut 
wikipedia) schon seit 1991. :P
1
#!/usr/bin/env python3
2
3
# Bevor das Modul serial genutz werden kann, muss PySerial installiert sein
4
# Entweder Python-Pip installieren und dann mit: pip install pyserial
5
# installieren, oder über deine Paketverwaltung, unter Arch z.B.
6
# yaourt -S Python-Pyserial
7
8
import serial
9
10
ser = serial.Serial('/dev/ttyUSB0', <Baudrate>) # Port oeffnen
11
ser.write(<hier deine Daten>)  # Daten auf port schreiben
12
ser.close()                    # Port schliessen

Die .write()-Funktion unterscheidet sich zwischen den Pythonversionen 
2.x und 3.x einbisschen, inbezug darauf, was man für daten reinschiebt. 
Es muss eventuell gecastet werden.

von Christian J. (Gast)


Lesenswert?

Hi,

ich werde das Python Script mal ausprobieren, michda soweit einlesen, 
dass ich wenigstens 10 Zeilen hinkriege. Die andere Sache die ich grad 
überdenke ist einen einfach Intel Hex Interpreter zu schreiben, der das 
eh auf 7 Bit umcodiert und eine Endesequenz hat, die der Slave erkennen 
kann. Das ist sicherlich eine saubere Lösung, die zudem standardisiert 
ist.

PS: Die %4 printf Variante erzeugt zb bei einem 1177 Byte großen File, 
in eine test.dat geschrieben und mit

>$hexdump test.dat angeschaut

000000 30 34 39 39   = 0x0499
000004

allerdings eben auch als String. Der wiederum mit Bordmitteln wie BCD 
Umwandlung und Subtraktion in 04 99 umcodiert werden müsste.

Klar, printf ist ascii textbasiert, damit kann man keine Binärdaten 
ausgeben, versteht ja ein Bildschirm nicht.


Gruss,
Christian

von Konrad S. (maybee)


Lesenswert?

1
perl -e ´open F, $ARGV[0] or die; $s = -s $ARGV[0]; $h = $s >> 8; $l = $s & 0xff; printf ¨%c%c¨, $h, $l; sysread( F, $b, $s ) == $s or die; close F; print $b´ binaer.bin > /dev/ttyUSB0

Die Dateilänge ist hier in Big-Endian, kannst du auch umdrehen. Die 
einfachen und doppelten Anführungszeichen könnten falsch sein, die 
kommen von ´nem Tablett, keine Ahnung wie die kodiert sind, einfach die 
ASCII-Versionen davon verwenden.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Little Endian:
1
len=$(stat -c %s binaer.bin)
2
printf "$(printf '\\x%x' $((len & 0xff)))$(printf '\\x%x' $((len >> 8)))" > /dev/ttyUSB0

oder besser: integriert in dieses Konstrukt:

Daniel A. schrieb:
> {
>   echo ...
>   stat ...
> } > /dev/tty

Big Endian: anders herum

BTW: Printf ist ein Bash-Builtin, erzeugt also keinen Overhead für das
Laden des Kommandos.

: Bearbeitet durch Moderator
von Christian J. (Gast)


Lesenswert?

Konrad S. schrieb:
> perl -e ´open F, $ARGV[0] or die; $s = -s $ARGV[0]; $h = $s >> 8; $l =
> $s & 0xff; printf ¨%c%c¨, $h, $l; sysread( F, $b, $s ) == $s or die;
> close F; print $b´ binaer.bin > /dev/ttyUSB0

Mal eine Frage: Hast Du das jetzt so aus dem kragen gezogen? 
Wahnsinn....

von perl dude (Gast)


Lesenswert?

Konrad S. schrieb:
> perl -e ´open F, $ARGV[0] or die; $s = -s $ARGV[0]; $h = $s >> 8;
> $l = $s & 0xff; printf ¨%c%c¨, $h, $l; sysread( F, $b, $s ) == $s or
> die; close F; print $b´ binaer.bin > /dev/ttyUSB0
> Die Dateilänge ist hier in Big-Endian, kannst du auch umdrehen. Die
> einfachen und doppelten Anführungszeichen könnten falsch sein, die
> kommen von ´nem Tablett, keine Ahnung wie die kodiert sind, einfach die
> ASCII-Versionen davon verwenden.
Wenn man beliebige Binaerformate hinbiegen muss (verschiedene 
Endianness, Double, Single,...)
http://perldoc.perl.org/functions/pack.html

von Konrad S. (maybee)


Lesenswert?

perl dude schrieb:
> Wenn man beliebige Binaerformate hinbiegen muss

Schon klar, aber ob's ankommt? (Nicht die Daten, sondern die Message! 
;-)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.