Kann der Arduino verwendet werden, um eine UART-Verbindung zwischen zwei Geräten auszuspionieren?


11

Ich muss ein Arduino (eigentlich nur den IC) in vorhandene Hardware installieren, um die Funktionalität zu verbessern.

Was ich tun möchte, ist das Arduino so anzuschließen, dass es die E / A-Leitungen zwischen zwei Chips auf einer Platine "ausspioniert". Wenn der Arduino ein bestimmtes Schlüsselwort für diese UART-Verbindung aufnimmt, führt er eine bestimmte Aktion für einen separaten Satz von Ausgangspins aus.

Ich bin mir nicht sicher, wie ich das Arduino so verbinden soll, dass es eine vorhandene UART-Verbindung ohne Teilnahme dekodieren kann. Wenn nicht möglich, interessiere ich mich für Theorien, Ideen usw.

Antworten:


17

Wenn ich das richtig verstehe, haben Sie 2 Geräte über UART verbunden. Ich gehe davon aus, dass nur TX-, RX- und GND-Leitungen zwischen den Geräten angeschlossen sind. (dh es werden keine DTS / CTS / DTR / RTS-Steuerleitungen verwendet - dies ist typisch).

In diesem Szenario ist der TX (Senden) von Gerät 1 mit dem RX (Empfangen) von Gerät 2 verbunden und umgekehrt. Ihre Gründe sind miteinander verbunden. Somit kann jedes Gerät gleichzeitig senden und empfangen (jedes sendet auf einer separaten Leitung, die Kommunikation erfolgt im Vollduplexmodus).

Der Grund, warum ich das alles erwähne, ist, dass klar wird, dass Sie zum "Schnüffeln" oder "Zuhören" tatsächlich 2 UARTs benötigen, um beide Seiten des Gesprächs anzuhören.

Grundsätzlich müssen Sie nur sicherstellen, dass die UART-GNDs aller drei Geräte kurzgeschlossen sind, und die TX-Leitungen von Gerät 1 und Gerät 2 mit den 2 RX-Leitungen verbinden (wirklich "T-Stück", wie bei einem T-Stück wie bei einem Sanitär) auf 2 UARTs. Stellen Sie sicher, dass alle Baudraten identisch konfiguriert sind.

Es gibt viele Arduino-Boards / Designs. Der heutzutage gebräuchlichste, der Duemilanove, verwendet den ATMega328P, der meiner Meinung nach nur 1 UART (naja, USART) hat. Sie müssten also entweder einen zweiten UART-IC verkabeln oder auf "Bit Banging" am zweiten Empfänger zurückgreifen.

Die asynchrone UART-Kommunikation ist mit Start- und Stoppbits (und manchmal Paritätsbits) gut definiert. Wenn Ihr Prozessor also schnell genug ist, können Sie einfach eine der UART TX-Leitungen des Geräts an einen als Eingang konfigurierten GPIO anschließen und die Leitung abfragen schnell genug mit Oversampling, um START & STOP und Abtastbits zu erkennen. Der Artikel "Bit Banging" von Jack Ganssle gibt Ihnen viel zu kauen.

Eine anständige Beschreibung der RS232-Wellenform finden Sie bei BeyondLogic .

Beachten Sie, dass Sie andere Probleme wie Spannungspegel (0 / + 5, -10 V / + 10 V usw.) berücksichtigen müssen (siehe Abschnitt Beyond Logic unter "RS232-Pegelwandler"). Ich habe nicht genügend Informationen auf Ihrem System, um die Hardware-Schnittstelle neben dem oben beschriebenen Ansatz "Connect the Lines" zu diskutieren. Unter der Annahme, dass die Spannungspegel übereinstimmen, ist es normalerweise kein Problem, die TX-Leitung in einen zweiten Empfänger (den Sniffer) zu "tippen". Wenn der TX jedoch nicht über genügend Laufwerk verfügt, müssen Sie möglicherweise einen Puffer / Treiber einfügen, um dies zu verhindern Signal von Verschlechterung.


Schön! Ich brauche nur die Daten, die in eine Richtung wandern, damit der einzelne UART auf dem ATMega-Chip gerade ausreicht! Die beiden Chips kommunizieren mit +/- 5V UART, was meiner Meinung nach mit dem ATMega identisch ist. Wow, das sollte es sein! Vielen Dank!
Brad Hein

@BradHein, was Sie "+/- 5V" nennen, wird normalerweise als "TTL-Level" bezeichnet - siehe en.wikipedia.org/wiki/Logic_level .
Mels

3
@Mels +/- 5V ist NICHT TTL, TTL geht NICHT unter die Erde. Dies ist RS-232.
nmz787

9

Es gibt einen netten Trick, den Sie ausführen können, wenn die Kommunikation jeweils nur in eine Richtung erfolgt (dh Halbduplex-Kommunikation). Es wird nicht funktionieren, wenn beide Seiten gleichzeitig miteinander sprechen (Vollduplex), aber wenn es Ihr typisches "mach das" ist "ok hier ist die Antwort" "jetzt mach das" "ok hier ist die neue Antwort" Art der Kommunikation es funktioniert ganz gut.

Da die UART-Verbindung einen Leerlaufzustand des Senders auf einem logisch hohen (1) Pegel verwendet, würden Sie ein UND-Gatter mit 2 Eingängen verwenden und den TX von jeder Seite mit einem UND-Eingang verbinden. Der Ausgang des UND-Gatters ist Ihr Eingang zum UART Ihres Sniffers (es ist der RX-Pin). Nehmen Sie nun die TX-Leitung von Gerät B und bringen Sie sie an einen E / A-Anschluss am Sniffer. Sie konfigurieren den Sniffer so, dass ein Interrupt generiert wird, wenn dieser Pin von hoch nach niedrig wechselt.

Um es noch einmal zusammenzufassen: Gerät A UART TX -> AND-Gate-Eingang. Gerät B UART TX -> anderer UND-Gatter-Eingang UND Sniffer-GPIO-Pin. Ausgang des UND-Gatters -> Sniffer-UART-RX-Leitung.

Die UART-Kommunikation besteht aus einem Startbit, einer bestimmten Anzahl von Datenbits, einem optionalen Paritätsbit und einem oder mehreren Stoppbits. Da der Ruhezustand ein logisch hohes (1) ist, ist der Start JEDES Bytes ein logisches niedriges (0) und der Interrupt auf dem Sniffer wird ausgelöst. Während Ihr Sniffer den E / A-Interrupt ausführt, sammelt die UART-Hardware Bits vom UND-Gatter. Wenn der UART das Stoppbit empfangen hat, ist der E / A-Interrupt lange abgeschlossen und der UART RX-Interrupt wird ausgelöst.

Die Interrupt-on-IO-Änderungsroutine setzt eine "Richtungs" -Variable, um anzuzeigen, dass die Kommunikation in der "B-> A" -Richtung erfolgt. Der UART-Empfangsinterrupt des Sniffers würde diese "Richtungs" -Variable betrachten und das gerade empfangene Byte in den entsprechenden Puffer schreiben. Der UART RX-Interrupt würde dann die Variable "Richtung" auf den Standardzustand "A-> B" zurücksetzen:

volatile int direction = 0;           /* 0 = A -> B */

void io_interrupt(void)
{
    direction = 1;                    /* switch direction, now B -> A */
}

void uart_interrupt(void)
{
    unsigned char b;

    b = UART_RX_REG;
    if(direction) {
        store_byte_to_device_b_sniff_buffer(b);
    } else {
        store_byte_to_device_a_sniff_buffer(b);
    }

    direction = 0;                   /* reset direction to default A -> B */
}

Dieser Code ist aus Gründen der Klarheit geschrieben und nicht unbedingt das, was Sie in einer realen Situation schreiben würden. Persönlich würde ich "Richtung" zu einem Zeiger auf die entsprechende FIFO-Struktur machen, aber das ist eine ganz andere Übung. :-)

Wenn Gerät A spricht, bewegt sich die E / A-Leitung nicht (sie bleibt auf einer logischen '1', da der UART-Sender von Gerät B inaktiv ist), und der UART RX-Interrupt empfängt ein Byte. Achten Sie darauf, dass die Richtung A-> B ist und speichern Sie die Daten in diesem Puffer. Wenn Gerät B spricht, wird die E / A-Leitung niedrig, sobald Gerät B beginnt, Daten zu verschieben, und die E / A-Interrupt-Routine legt die Richtung fest, um anzuzeigen, dass Gerät B spricht. Der UART RX-Interrupt wird schließlich ausgelöst, nachdem alle Bits gesammelt wurden, und da der E / A-Interrupt dafür gesorgt hat, dass das Richtungsregister entsprechend eingestellt wird, wird das empfangene Byte im richtigen Puffer gespeichert.

Presto: Halbduplex-Kommunikation zwischen zwei Geräten, die mit einer einzigen UART- und E / A-Leitung auf dem Sniffer erfasst wurden, ohne bitgebundene UART-Kommunikation.


Faszinierend. Dies stößt an die Grenzen meines Verständnisses, aber es ist großartig! Ein Teil, den ich nicht verstehe, ist, wie der UART des Schnüfflers mit dem Ziel verbunden ist, damit er beide Kommunikationsrichtungen abfangen kann. Ich habe mehrere E / A-Pins zur Verfügung. Könnte ich mit dieser Methode einfach zwei E / A-Pins verwenden und effektiv beide Verkehrsrichtungen erfassen?
Brad Hein

Die Sniffer-UART-RX-Leitung ist mit dem Ausgang des UND-Gatters verbunden. Der UART TX von Gerät A ist mit einem Eingang des UND-Gatters verbunden, und der UART TX von Gerät B ist mit dem anderen Eingang des UND-Gatters verbunden. Da der Leerlaufzustand (kein Verkehr) eines UART eine logische '1' ist, kombiniert das UND-Gatter effektiv beide Sendesignale zu einem. Die E / A-Leitung am Sniffer wird verwendet, um das Startbit von Gerät B zu erkennen, sodass es das Byte, das es auf seinem UART empfängt, in den entsprechenden Puffer (Verkehr von Gerät A oder Verkehr von Gerät B) legen kann.
Akohlsmith

Das Codefragment und die Verkabelung des UND-Gatters ermöglichen es dem Sniffer, beide Richtungen des Verkehrsflusses mit einem einzigen UART aufzuzeichnen. Dies funktioniert NUR, wenn der Verkehr Halbduplex ist. Das heißt, wenn ein Gerät spricht, hört das andere zu. Wenn beide gleichzeitig sprechen (Vollduplex), würde dies überhaupt nicht funktionieren.
Akohlsmith

5

Sie müssen den Sende-Daten-Pin des AVR nicht in Ihre Schaltung einbinden. Verbinden Sie einfach die Empfangsleitung mit der Hälfte des vorhandenen Links, den Sie abhören möchten. Wenn Ihr bestimmter AVR über zwei serielle Schnittstellen verfügt, sollten Sie in der Lage sein, beide Hälften der vorhandenen Verbindung gleichzeitig auszuspionieren. Sie müssen nur die Porteinstellungen an die vorhandene Baudrate, Stoppbits usw. anpassen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.