Mit der Bash Binärzahlen auf Com Port ausgeben

Gast #3866111
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
Gast #3866207
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??
Gast #3866272
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.
Gast #3866291
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
#3866308
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.
Moderator #3866357
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.
Gast #3866364
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....
Gast #3868792
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren