Verständnisfragen zu serieller Verbindung/pyserial

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
darktrym
User
Beiträge: 784
Registriert: Freitag 24. April 2009, 09:26

Vorneweg, ich bin nicht wirklich firm in der Kommunikation mit E-Technik und der Bibliothek pyserial.
Zu meinem Anwendungsfall:
Ich besitze ein technisches Gerät, welches seinen Code ausschließlich über eine Stück Windows Software übermittelt bekommt. Dies erfolgt über eine serielle Verbindung via USB.
Einen Auszug einer Sitzung habe ich via advanced serial port monitor mitschneiden lassen. Das sieht dann so aus:

Code: Alles auswählen

<20131116114117.322 SYS>
COM ist offen
<20131116114117.322 SYS>
Leeren der seriellen Schnittstelle: RXABORT, RXCLEAR, TXABORT, TXCLEAR
<20131116114117.322 SYS>
Zeitüberschreitungen: ReadInterval=300, ReadTotalTimeoutMultiplier=1, ReadTotalTimeoutConstant=1, WriteTotalTimeoutMultiplier=10, WriteTotalTimeoutConstant=100
<20131116114117.322 SYS>
Baud-Rate 115200
<20131116114117.322 SYS>
RTS an
<20131116114117.322 SYS>
DTR an
<20131116114117.322 SYS>
Data Bits=8, Stop Bits=1, Parity=None
<20131116114117.322 SYS>
Zeichen setzen: Eof=0x00, Error=0x00, Break=0x00, Event=0x00, Xon=0x00, Xoff=0x00
<20131116114117.322 SYS>
Handflow: ControlHandShake=(DTR_CONTROL), FlowReplace=(TRANSMIT_TOGGLE, RTS_CONTROL), XonLimit=32768, XoffLimit=8192
<20131116114117.322 SYS>
DTR an
<20131116114117.385 SYS>
DTR aus
<20131116114118.399 SYS>
Leeren der seriellen Schnittstelle: RXABORT, RXCLEAR, TXABORT, TXCLEAR
<20131116114118.399 TX>
4dgl
<20131116114118.586 RX>
G
<20131116114118.586 TX>
L<BS>
<20131116114118.976 RX>
<ACK>
<20131116114118.976 TX>
hz<NUL>$<NUL>D<NUL>++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++.<NUL>
<20131116114118.976 RX>
<NUL>
<20131116114118.976 TX>
.+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.+++.´<SOH>T<NUL><SOH><SYN>w
<20131116114118.992 RX>
<NUL>
<20131116114118.992 TX>
hŒ<NUL>T<NUL>$<SOH><SYN>؈<NUL><LF>t<NUL>T<SOH><SOH><SYN>¤<NUL>h—ÿX<BEL>€$<SOH><BS>èÊ<SOH>X<BEL>€¤<NUL><FF><ETX>T+<ACK>èÄ<NUL>´<STX>Ä<SOH><FF>´<STX>Ä<SOH><FF><ETB>T<SOH><FF>X<NUL><SOH><DLE><SOH><US>
<20131116114119.007 RX>
<NUL>
<20131116114119.007 TX>
<SYN>ØÃ<SOH>X<BEL>€¤<NUL><FF><ETX>T-<ACK>èè<NUL>´<STX>Ä<SOH><FF>´<STX>Ä<SOH><FF><ETB>T<SOH> [len=231]
<20131116114119.007 TX>
X<NUL><SOH><DLE><SOH><SYN>ØÃ<SOH>X<BEL>€¤<NUL><FF><ETX>T.<ACK>è<EOT><SOH>hþÿ´<STX>Ä<SOH><FF><ETB>$<SOH>“
<20131116114119.007 RX>
<NUL>
<20131116114119.007 TX>
<SYN>ØÃ<SOH>X<BEL>€¤<NUL><FF><ETX>T,<ACK>è <SOH>´<STX>Ä<SOH><FF>håÿ$<NUL><SOH><SYN>ØÃ<SOH>X<BEL>€¤<NUL><FF><ETX>T<<ACK>è<<SOH>´<SOH>Ä<SOH>T<SOH> [len=85]
<20131116114119.007 TX>
Tþ<DLE><SOH><SYN>ØÃ<SOH>X<BEL>€¤Â
<20131116114119.023 RX>
<NUL>
<20131116114119.023 TX>
<NUL><FF><ETX>T><ACK>èX<SOH>´<SOH>Ä<SOH>T<SOH><FF>Tþ<DLE><SOH><SYN>ØÃ<SOH>X<BEL>€¤<NUL><FF><ETX>T[<ACK>èµ<SOH>´<STX>Ä<SOH><FF><ETB>T<NUL><BEL>è<SOH>dŒ¤<NUL>T<SOH><FF>$<SOH><SYN>Ø <NUL>ز®
<20131116114119.023 RX>
<NUL>
<20131116114119.023 TX>
<SOH>„<NUL>T<NUL><BEL>è²<SOH>X<BEL>€”<NUL><GS><FF><ETX>T[<ACK>èž<SOH>t<NUL><GS><SYN>د<SOH>X<BEL>€¤<NUL><FF><ETX>T]<ACK>è¯<SOH>t<NUL><RS><SYN>؁<SOH>ØÃ<SOH>X<BEL>€¤<NUL><FF><ETX>T]<ACK>èË
<20131116114119.038 RX>
<NUL>
<20131116114119.038 TX>
Ã<SOH><LF>”<NUL><GS><SYN>Ø’<NUL><LF>ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ,
<20131116114119.038 RX>
<NUL><ACK>
<20131116114119.054 SYS>
COM ist geschlossen
Meinen Verständnis nach müsste ich nun die Rolle von tx(transmit) übernehmen. Wenn ich mich nun testweise verbinde(Konstruktor) und ein "4dgl" sende(write), müsste doch das Gerät irgendwann mit G antworten(read(), receive). Das tut es nicht, deshalb bin ich etwas verwirrt. Des Weiteren, wenn ich ihm einen String sende, wie sieht dann dessen Kodierung aus, sprich bedeutet ein "4dgl" dann ein '4','d', 'g', 'l', '\0'?
Ist der Initialisierungskram, sprich das was SYS da macht unbedingt haargenau so zu imitieren oder rät das Gerät die passenden Parameter?
„gcc finds bugs in Linux, NetBSD finds bugs in gcc.“[Michael Dexter, Systems 2008]
Bitbucket, Github
BlackJack

@darktrym: Die Konfiguration wirst Du schon exakt so machen müssen wie das Gerät die erwartet. Wobei ich denke das ein Teil davon am Anfang die Standardeinstellung der Schnittstelle ist, die dann vom Programm geändert wird. DTR würde ich hier zum Beispiel als „aus” annehmen, auch wenn das am Anfang (und zwischenzeitlich) mal auf „an” war.

Wie die Kodierung von den ersten Daten aussieht ist schwer zu sagen solange man nicht weiss wie Zeilenenden von dem Programm darstellt werden was Du da zum Mitschneiden der Kommunikation verwendet hast. Ein Nullbyte ist jedenfalls nicht in den Daten, denn später sieht man, dass das als '<NUL>' angezeigt würde. Da '\n' offenbar als '<LF>' dargestellt wird, gehe ich mal davon aus, dass '\r' auch angzeigt würde. Als '<CR>'. Also wird da wahrscheinlich tatsächlich nur '4dgl' gesendet.

Da musst Du wahrscheinlich mit einem `flush()`-Aufruf dafür sorgen, dass die vier Bytes nicht nur gepuffert, sondern tatsächlich gesendet werden.

Letztendlich sieht es so aus als wenn das ein Binärprotokoll ist, bei dem man die Nachrichten und deren Aufbau und damit auch deren Länge kennen *muss* um damit arbeiten zu können.

Was ist denn das für ein technisches Gerät dem man Brainfuck-Code schicken kann? :-)
Benutzeravatar
darktrym
User
Beiträge: 784
Registriert: Freitag 24. April 2009, 09:26

Kurzum, auf dem Gerät läuft EVE von 4D Systems, eine sehr spezielle VM.
Diese wiederum führt dann meinen Brainfuck Interpreter aus, welches ein Hello World ausgibt.
„gcc finds bugs in Linux, NetBSD finds bugs in gcc.“[Michael Dexter, Systems 2008]
Bitbucket, Github
BlackJack

@darktrym: Das sieht ja interessant aus. Allerdings auch nach einem relativ „geschlossenen” Produkt. Dieses 4DGL und Windows scheinen zwei Sachen zu sein um die man nicht herum kommt. :-(
Benutzeravatar
darktrym
User
Beiträge: 784
Registriert: Freitag 24. April 2009, 09:26

Für das was es kann war es spotbillig, bin leider ein Jahr zu spät darauf aufmerksam gewurden, nachdem Super Pixel Bros. nicht mehr erhältlich war.
Zum großen Teil Windows-Only, ja. Aber gerade diesen Umstand will ich beheben.
Ein Teil davon ist eben der Upload. Es gibt einige Produkte aus dem gleichen Haus die ähnlich funktionieren. Leute aus der Community hatten bspw. hier und da sich bereits damit beschäftigt.

Bin mir noch nicht im klaren ob das rechtlich zu beanstanden ist. Eine Antwort zur Dissembelierung hat zur Löschung eines 3 Jahren alten Threads("verwirrt sonst die Nutzer") geführt.

Ich leg' mich jetzt schlafen.
„gcc finds bugs in Linux, NetBSD finds bugs in gcc.“[Michael Dexter, Systems 2008]
Bitbucket, Github
BlackJack

@darktrym: Ich habe mir den `4DCmdLine`-Quelltext mal angeschaut. Hast Du das schon mal ausprobiert? Von den Daten her passt der Code genau zu der mitgeschnittenen Kommunikation. Nach dem 'G' als Antwort wird 'L\b' gesendet, wobei '\b' den Bytewert 8 hat. Danach folgen 8 Datenpakete die jeweils von der Gegenseite mit einem Nullbyte quittiert werden, gefolgt von einem <ACK> für die gesamte Datenübertragung. Bei den ersten beiden Datenpaketen habe ich auch die Prüfsumme nachgerechnet — die stimmt auch. Hier mal für das zweite Datenpaket:

Code: Alles auswählen

In [54]: s = '.+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.+++.\xb4\x01T\0\x01\x16'

In [55]: chr(-sum(map(ord, s)) & 0xff)
Out[55]: 'w'
Das am Anfang mit der DTR-Leitung scheint doch nötig zu sein, denn die wird offenbar laut Code und einem anderen Forenbeitrag zum Auslösen eines Reset auf der Gegenseite missbraucht. Darum geht auch nicht jeder USB-Serial-Adapter sondern nur solche wo man auch diese Leitung gezielt einzeln ansteuern kann.

Was die rechtliche Seite angeht gilt natürlich wie immer: Man muss einen Anwalt fragen. Und der kann auch keine definitive Antwort geben, sondern nur seine Rechtsauffassung mit der er gegebenenfalls vor Gericht argumentieren würde. ;-)

Das Analysieren von Protokollen sollte aber rechtlich kein Problem darstellen. Insbesondere nicht wenn es der Interoperabilität dient, also zum Beispiel wenn man auch unter Linux ein kompiliertes Programm auf ein Gerät einspielen möchte wofür es nur Windows-Software für diesen Zweck gibt. :-)

Solange man sich nur die Daten anschaut, die ausgetauscht werden, hat das ja auch nichts mit disassemblieren zu tun.

Rechtlich interessanter wäre da schon wenn man sich den Bytecode von dieser 4DGL-Sprache vornimmt und den „reverse engineer”t um zum Beispiel einen eigenen Compiler zu schreiben. Beispielsweise einen Brainfuck-Compiler der direkt Code für die EVE-VM erzeugt anstelle von Brainfuck-Quelltext + Interpreter. :-)
Benutzeravatar
darktrym
User
Beiträge: 784
Registriert: Freitag 24. April 2009, 09:26

Danke nochmal für die tatkräftige Unterstützung.
Jetzt habe ich wenigstens eine funktionierende Version.
Es hat ein wenig länger gedauert als gedacht wegen 3 Dingen:
  • Man sollte/muss "4dgl" mehrfach senden, damit das Gerät auch irgendwann mal reagiert!
  • Fehlendes Schließen der seriellen Verbindungen verursacht gern mal ein Absturz des Treibers, Neustart yeah.
  • Die Ausgaben müssen und können nicht exakt so eingehalten werden, dazu ist pyserial nicht in der Lage.

Code: Alles auswählen


CHUNK_SIZE = 64

def transfer(data, port):
    '''transfer data to given port'''
    print("opening port %s" % port)
    try:
        ser = serial.Serial(
        port=port,
        baudrate=115200,
        timeout=1)
    except serial.serialutil.SerialException:
        print("couldnt establish a serial connection")
        return
    ser.setDTR(True)
    ser.setDTR(False)
    ser.flushInput()
    ser.flushOutput()
    print("sending commands")
    for i in range(10):
        ser.write("4dgl")
        response = ser.read()
        if response != "":
            break
    if response:
        ser.write("L\b")
        response = ser.read()
        print("data transfer starts:", end="")
        start = 0
        for start in range(0, len(data), CHUNK_SIZE):
            chunk = data[start: start + CHUNK_SIZE]
            if len(chunk) < CHUNK_SIZE:
                chunk = chunk.ljust(CHUNK_SIZE, '\xFF')
            check_sum = chr(-sum(map(ord, chunk)) & 0xFF)
            ser.write(chunk + check_sum)
            response = ser.read()
            if response:
                print(".", end="")
            else:
                print("transferring stopped because of missing ACK")
                break
        print("\n")
    else:
        print("communication error by initialisation")
    print("closing port")
    ser.close()
Beim letzten Paket muss mit 0xFF aufgefüllt werden. Ich bekomme zwar nur ein <NUL> statt ein <NUL><ACK> aber es funktioniert trotzdem.

Code: Alles auswählen

<20131117202325.596 SYS>
COM ist offen
<20131117202325.596 SYS>
Schlangengröße In/Out 4096/4096
<20131117202325.596 SYS>
Zeitüberschreitungen: ReadInterval=0, ReadTotalTimeoutMultiplier=0, ReadTotalTimeoutConstant=1000, WriteTotalTimeoutMultiplier=0, WriteTotalTimeoutConstant=0
<20131117202325.596 SYS>
Baud-Rate 115200
<20131117202325.596 SYS>
RTS an
<20131117202325.597 SYS>
DTR an
<20131117202325.597 SYS>
Data Bits=8, Stop Bits=1, Parity=None
<20131117202325.597 SYS>
Zeichen setzen: Eof=0x00, Error=0x00, Break=0x00, Event=0x00, Xon=0x11, Xoff=0x13
<20131117202325.598 SYS>
Handflow: ControlHandShake=(DTR_CONTROL), FlowReplace=(TRANSMIT_TOGGLE, RTS_CONTROL), XonLimit=32768, XoffLimit=8192
<20131117202325.598 SYS>
Leeren der seriellen Schnittstelle: RXABORT, RXCLEAR, TXABORT, TXCLEAR
<20131117202325.598 SYS>
DTR an
<20131117202325.598 SYS>
DTR aus
<20131117202325.599 SYS>
Leeren der seriellen Schnittstelle: RXABORT, RXCLEAR
<20131117202325.599 SYS>
Leeren der seriellen Schnittstelle: TXABORT, TXCLEAR
<20131117202325.599 TX>
4dgl4dgl
<20131117202326.797 RX>
G
<20131117202326.797 TX>
L<BS>
<20131117202327.177 RX>
<ACK>
<20131117202327.178 TX>
hz<NUL>$<NUL>D<NUL>++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++.<NUL>
<20131117202327.186 RX>
<NUL>
<20131117202327.187 TX>
.+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.+++.´<SOH>T<NUL><SOH><SYN>w
<20131117202327.196 RX>
<NUL>
<20131117202327.196 TX>
hŒ<NUL>T<NUL>$<SOH><SYN>؈<NUL><LF>t<NUL>T<SOH><SOH><SYN>¤<NUL>h—ÿX<BEL>€$<SOH><BS>èÊ<SOH>X<BEL>€¤<NUL><FF><ETX>T+<ACK>èÄ<NUL>´<STX>Ä<SOH><FF>´<STX>Ä<SOH><FF><ETB>T<SOH><FF>X<NUL><SOH><DLE><SOH><US>
<20131117202327.205 RX>
<NUL>
<20131117202327.205 TX>
<SYN>ØÃ<SOH>X<BEL>€¤<NUL><FF><ETX>T-<ACK>èè<NUL>´<STX>Ä<SOH><FF>´<STX>Ä<SOH><FF><ETB>T<SOH> [len=235]
<20131117202327.205 TX>
X<NUL><SOH><DLE><SOH><SYN>ØÃ<SOH>X<BEL>€¤<NUL><FF><ETX>T.<ACK>è<EOT><SOH>hþÿ´<STX>Ä<SOH><FF><ETB>$<SOH>“
<20131117202327.214 RX>
<NUL>
<20131117202327.214 TX>
<SYN>ØÃ<SOH>X<BEL>€¤<NUL><FF><ETX>T,<ACK>è <SOH>´<STX>Ä<SOH><FF>håÿ$<NUL><SOH><SYN>ØÃ<SOH>X<BEL>€¤<NUL><FF><ETX>T<<ACK>è<<SOH>´<SOH>Ä<SOH>T<SOH> [len=85]
<20131117202327.214 TX>
Tþ<DLE><SOH><SYN>ØÃ<SOH>X<BEL>€¤Â
<20131117202327.223 RX>
<NUL>
<20131117202327.223 TX>
<NUL><FF><ETX>T><ACK>èX<SOH>´<SOH>Ä<SOH>T<SOH><FF>Tþ<DLE><SOH><SYN>ØÃ<SOH>X<BEL>€¤<NUL><FF><ETX>T[<ACK>èµ<SOH>´<STX>Ä<SOH><FF><ETB>T<NUL><BEL>è<SOH>dŒ¤<NUL>T<SOH><FF>$<SOH><SYN>Ø <NUL>ز®
<20131117202327.232 RX>
<NUL>
<20131117202327.232 TX>
<SOH>„<NUL>T<NUL><BEL>è²<SOH>X<BEL>€”<NUL><GS><FF><ETX>T[<ACK>èž<SOH>t<NUL><GS><SYN>د<SOH>X<BEL>€¤<NUL><FF><ETX>T]<ACK>è¯<SOH>t<NUL><RS><SYN>؁<SOH>ØÃ<SOH>X<BEL>€¤<NUL><FF><ETX>T]<ACK>èË
<20131117202327.241 RX>
<NUL>
<20131117202327.241 TX>
Ã<SOH><LF>”<NUL><GS><SYN>Ø’<NUL><LF>ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ,
<20131117202327.250 RX>
<NUL>
<20131117202327.250 SYS>
Zeitüberschreitungen: ReadInterval=300, ReadTotalTimeoutMultiplier=1, ReadTotalTimeoutConstant=1, WriteTotalTimeoutMultiplier=10, WriteTotalTimeoutConstant=100
<20131117202327.251 SYS>
COM ist geschlossen
„gcc finds bugs in Linux, NetBSD finds bugs in gcc.“[Michael Dexter, Systems 2008]
Bitbucket, Github
BlackJack

@darktrym: Nach dem Reset braucht das Gerät wahrscheinlich einfach ein bisschen Zeit zum booten.

Den letzten Punkt habe ich nicht verstanden?

Dein Code funktioniert nur mit Daten die zwischen 449 und 512 Bytes lang sind denn nach dem 'L' kommt ein Bytewert der angibt wie viele 64 Bytes + Prüfsummenbyte Pakete übertragen werden. Da hast Du '\b', also 8 hart in den Quelltext kodiert.

Ich hatte mal das hier zusammengehackt. Natürlich ohne die Möglichkeit es auch zu testen.

Code: Alles auswählen

# coding: utf8
import math
from collections import namedtuple
from time import sleep
from serial import Serial

ACK, NACK = '\x06', '\x15'

DEVICE_NAMES = ['µOLED', 'µLCD', 'µVGA']
VALUE_TO_RESOLUTION = {
    0x22: 220,
    0x24: 240,
    0x28: 128,
    0x32: 320,
    0x60: 160,
    0x64: 64,
    0x76: 176,
    0x96: 96,
}

class Error(Exception):
    pass


DeviceInfo = namedtuple(
    'DeviceInfo', 'name hardware_version software_version resolution'
)


def calculate_checksum(data):
    return -sum(ord(c) for c in data) & 0xff


class Device(object):
    def __init__(self, port, baudrate=115200):
        self.connection = Serial(port, baudrate, rtscts=True)

    def __enter__(self):
        return self

    def __exit__(self, *args):
        self.close()

    def reset(self):
        self.connection.setDTR(0)
        sleep(0.01)
        self.connection.setDTR(1)
        sleep(0.1)

    def read_expected(self, expected_data):
        data = self.connection.read(len(expected_data))
        if data != expected_data:
            raise Error(
                'expected {0!r}, got {1!r} instead'.format(expected_data, data)
            )

    def write(self, data, expected_data=ACK):
        self.connection.write(data)
        self.connection.flush()
        if expected_data:
            self.read_expected(expected_data)

    def get_info(self):
        self.write('V\0', '')
        response = map(ord, self.connection.read(5))
        try:
            name = DEVICE_NAMES[response[0]]
        except IndexError:
            name = 'Unknown'
        return DeviceInfo(
            name,
            response[1],
            response[2],
            (VALUE_TO_RESOLUTION[response[3]], VALUE_TO_RESOLUTION[response[4]])
        )

    def initialize(self):
        self.write('\x55')
        return self.get_info()

    def send_4dgl(self, data):
        # 
        # Attention: Expects `data` without the first 16 bytes of the file.
        #            So just the data that actually should be sent to the
        #            device!
        # 
        chunk_size = 64
        chunk_count = int(math.ceil(float(len(data)) / chunk_size))
        if chunk_count > 255:
            raise ValueError(
                'data too long (max. {0} bytes allowed, got {1})'.format(
                    chunk_size * 255, len(data)
                )
            )
        self.reset()
        sleep(0.2)
        self.write('4dgl', 'G')
        self.write('L' + chr(chunk_count))
        chunks = (
            data[i:i + chunk_size].ljust(chunk_size, ord(255))
            for i in xrange(0, len(data), chunk_size)
        )
        for chunk in chunks:
            self.write(chunk + calculate_checksum(chunk), '\0')
        self.read_expected(ACK)
        self.reset()

    def close(self):
        self.connection.close()


def main():
    with Device('/dev/...') as device:
        print device.initialize()


if __name__ == '__main__':
    main()
Benutzeravatar
darktrym
User
Beiträge: 784
Registriert: Freitag 24. April 2009, 09:26

Stimmt, die Anzahl der Pakete sollte man nicht hart codieren. :roll:
Das Timeout und die Antwort unterscheidet sich beim letzten Packet.
Daher frage ich mich woher er weiß, dass nix mehr kommt.
Und eine andere Sache ist noch interessant.
Nach der Protokolllogik werden immer ganze Blöcke geschrieben d.h. entweder enthalten die Binaries ein spez. Opcode oder man setzt eine Endlosschleife am Ende des auszuführenden Programms voraus.
„gcc finds bugs in Linux, NetBSD finds bugs in gcc.“[Michael Dexter, Systems 2008]
Bitbucket, Github
BlackJack

@darktrym: Das Ende der Daten weiss das Gerät doch dadurch, dass man am Anfang übermittelt wie viele Datenpakete man sendet. Und ich denke mal am Ende werden die Füllbytes im letzten Block einfach mit gespeichert.
Benutzeravatar
darktrym
User
Beiträge: 784
Registriert: Freitag 24. April 2009, 09:26

Trotzdem bekomme ich kein <NUL><ACK> sondern nur ein einfaches <NUL>, die Blockanzahl stimmt ja weiterhin und wieso Timeout, merkwürdig das Ganze.
Die Sache mit dem letzten Block, ich habe da bereits ein Opcode in Verdacht, der EVE signalisiert hier ist Schluss.

Und zu den rechtlichen Sache:
Das Dekompilieren der Software worauf das Copyright von 4D Systems draufliegt, sprich die Binaries und Bibliotheken ist klar illegal. Aber der Byte Code ist da schon eine andere Sache. Möglicherweise gibts Patente auf die Technologie. Das werde ich wohl nur erfahren, wenn ich das ok vom Hersteller bekomme, dessen Motivation sollte sich dahingehend in Grenzen halten. Vielleicht gibts ja Seiten/Leute da draußen die das klarer beantworten können.
„gcc finds bugs in Linux, NetBSD finds bugs in gcc.“[Michael Dexter, Systems 2008]
Bitbucket, Github
BlackJack

@darktrym: Nur weil jemand ein Copyright auf eine Software hat ist es noch lange nicht illegal die zu dekompilieren. Selbst wenn ein Verbot im Vetrag steht den man „eingeht” muss das Verbot nicht wirksam sein.
BlackJack

Ich habe noch mal geschaut: Bei den übertragenen Nutzdaten gibt es zwischen den beiden Mitschnitten keine Unterschiede, abgesehen von dem fehlenden <ACK> am Ende von der Gegenseite.

Das erste Programm wartet nach dem Reset per DTR-Leitung eine Sekunde bis die nächste Aktivität folgt. Deswegen sendet das '4dgl' auch nur einmal, denn dann ist der Reset des Systems auf der Gegenseite komplett durchgelaufen.

Ansonsten sind die Unterschiede dass beim Python-Programm eine Schlangengrösse angegeben wird. Vielleicht arbeitet das andere Programm ungepuffert.

Die Zeitüberschreitungen haben andere Werte. Und bei „Zeichen setzen:” unterscheiden sich die Xon/Xoff-Werte.
Benutzeravatar
darktrym
User
Beiträge: 784
Registriert: Freitag 24. April 2009, 09:26

Nun versuche ich den Firmware Upload anzugehen. Ich bekomme aber, beim besten Willen, keine Verbindung zustande, gesucht wird:

Code: Alles auswählen

20131121122303.478 SYS>
COM ist offen
<20131121122303.478 SYS>
Leeren der seriellen Schnittstelle: RXABORT, RXCLEAR, TXABORT, TXCLEAR
<20131121122303.478 SYS>
Zeitüberschreitungen: ReadInterval=5, ReadTotalTimeoutMultiplier=1, ReadTotalTimeoutConstant=1, WriteTotalTimeoutMultiplier=0, WriteTotalTimeoutConstant=0
<20131121122303.478 SYS>
Baud-Rate 115200
<20131121122303.478 SYS>
RTS aus
<20131121122303.478 SYS>
DTR aus
<20131121122303.478 SYS>
Data Bits=8, Stop Bits=1, Parity=None
<20131121122303.478 SYS>
Zeichen setzen: Eof=0x00, Error=0x00, Break=0x00, Event=0x00, Xon=0x00, Xoff=0x00
<20131121122303.478 SYS>
Handflow: ControlHandShake=(), FlowReplace=(), XonLimit=32768, XoffLimit=8192
<20131121122303.478 SYS>
DTR an
<20131121122303.494 SYS>
DTR aus
<20131121122303.525 SYS>
Leeren der seriellen Schnittstelle: RXABORT, RXCLEAR, TXABORT, TXCLEAR
<20131121122303.525 TX>
4DGL
<20131121122303.541 RX>
4dgl
<20131121122303.541 TX>
e
<20131121122303.572 RX>
<ACK>E
<20131121122304.693 TX>
p<NUL>BzJè<EM>¿<ENQ>'zETDÀJe"<GS>é"·³Ó<¹<DC1><STX>>J<DLE><SI>u(ÉÝÇ%Š&š[<FS>_~hÇgÙ™@ª~<CAN>º˜õÛzûq‰¹ž\çëQG9GôQO<DLE>×\<NAK>®Ÿ¤JF<NUL><ETX>È2ÈQ·<FF>(c{¡CÒΕþ<BEL>“cò<NAK>»TÅÆð<EM>‡ûñ^”Û~Ó™Êf‡÷œy„ÿPiwh`6-<US>Ž<EOT>Ñ!›IáΟuìû±0†Ÿ‹<SO>?cTM¦—¸<EM>ê$è#~öfvE<SI>Ò´ë2} q<DC3>9‡æµØµ‚·í¹2:<EM>p¡CŠ<FS>ÒÞYý$z;n™mbz6ð¤<EOT>?=qéÉ<ACK>["?=qéÉ<ACK>["?=qéÉ<ACK>["?=qéÉ<ACK>["?=qéÉ<ACK>["Ï
<20131121122304.755 RX>
<ACK>
<20131121122304.755 TX>
p<NUL>~TömºÔ‰ªí<FS>$Χ<¡I¤!as8”ÄÆ,± iéoœ<STX>8ã«v^ùò›ÀÎE$ÔÒv<SO>ö¢ÐŒÓ@Híú(rmLåÐs1OÆ»!<DC1>zÚåÞ¡«»‹Þw–ð^>‡¾0ñ<SO>ê<SOH>%_î<ESC>™´Vo³1üoÁÕË“³þ<FF>çb<FS><SYN>ñÐ<ESC><FF>Dù~82¯4ÉØâÊìÞ(Àþõˆn’¥'ð%}äžSÆù“èÔK•T9Ž6P¯½VðÅ@$V„ésH»a5#ȝðãyq;é•Ñ¹™6Q><NAK>UΞ©›<HT>s³<ETX>à%:Îý¨£w^áÖ—7‰oW„<SO>¶\ør<HT>ÐD¹ñ<ESC>œÁ×X<DC1>ý<DLE>'<ETB><STX>•¶Öƒ<SO>{žÙ¡rÜ‘ü
<20131121122304.818 RX>
<ACK>
...
<20131121122313.128 TX>
f
<20131121122313.159 RX>
<ACK>
<20131121122313.159 SYS>
COM ist geschlossen
Die Kodierung der Daten(am Ende) ist vermutlich bereits geklärt(siehe 4cmd Tool).

Aber mal abgesehen davon, dass ich RTS und DTR bei der Initialisierung nicht auf False setzen kann, bekomme ich keinen Zugriff auf Handshake Parameter etc.
Mit der Bibliothek uspp habe ich die gleichen Probleme. Dort scheint das Problem darin zu liegen, dass die DCB Struktur(unter Windows) nur mit ByteSize, Parity, StopBits gefüllt wird, statt mit allen sinnvollen Parametern. Bevor ich einen dieser Entwickler damit belästige, uspp forke, oder was eigenes schreibe, gibts da noch saubere Möglichkeiten auf die gewünschten Attribute Einfluss zu nehmen? Schließlich will ich die 50€ für die Analysesoftware sinnvoll investiert wissen.
„gcc finds bugs in Linux, NetBSD finds bugs in gcc.“[Michael Dexter, Systems 2008]
Bitbucket, Github
Antworten