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
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.
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
importserial
9
10
ser=serial.Serial('/dev/ttyUSB0',<Baudrate>)# Port oeffnen
11
ser.write(<hierdeineDaten>)# 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
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.
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.
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