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
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
Der Port wird nicht geklaut, der ist ein Usb Stecker. Das Ganze geht auch als C Program aber dann wird es richtig aufwendig.....
nimm doch einfach python statt nem bash script...
Christian J. schrieb: > Ich kann kein neumodisches Python :-( Dann nimm halt das klassische Python 2.x
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??
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
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
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.
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
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.
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
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....
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.