STM32F407 + LAN8720A + lwIP + FreeRTOS = Keine empfangenen Ethernet-Frames

Ich versuche, eine Platine mit einem STM32F407 und einem LAN8720A-Ethernet-PHY aufzurufen, und ich kann anscheinend keine Ethernet-Frames empfangen – obwohl ich keine Probleme beim Übertragen von Frames habe.

Hardware-Setup

Schema des Ethernet-PHYIch habe einen 25-MHz-Quarz auf dem STM32F4, der einen 25-MHz-Taktausgangspin in den LAN8720A treibt, der sich im REF_CLK_OUT-Modus befindet – und einen 50-MHz-Takt zurück zum STM32F4 als Teil der RMII-Schnittstelle treibt.

Die Buchse / Magnetics sind ein generisches Teil. Hier das Datenblatt:Geben Sie hier die Bildbeschreibung ein

Software

Ich verwende das neueste Update STM32CubeMX, um ein System Workbench für ein STM32-Projekt zu generieren, das FreeRTOS, lwIP und die ETH-Peripherietreiber enthält. Ich habe den generierten Code nicht wirklich berührt – also wird der lwIP-Stack in einem FreeRTOS-Stack initialisiert.

Experimente

Mit der lwIP meines Boards, die für eine statische IP 10.0.0.2 konfiguriert ist, und einem USB-zu-Ethernet-Dongle auf meinem Computer, der für eine statische IP 10.0.0.1 konfiguriert ist, verbinde ich die beiden Geräte direkt mit einem Ethernet-Kabel, und mein Board versucht, eine Verbindung herzustellen zu einem Dienst auf Port 80 des Computers. Ich erfasse die Interaktion zwischen meinem Board und dem Computer mit Wireshark (läuft auf dem Computer und ist an den USB-zu-Ethernet-Konverter gebunden).

Wegen des No-Received-Frames-Problems kommen wir nie über dieses ARP-Zeug hinaus: Wireshark-ErfassungWie Sie sehen können, kann das Stmicroe (mein Board) ARP-Pakete senden – von meinem Computer gehört – aber es scheint nie die Antwort von meinem Computer zu hören , da es weiterhin ARP-Pakete aussendet.

Beide Geräte sind mit einer 255.255.255.0-Maske konfiguriert, und beide sind mit einer Gateway-Adresse von 10.0.0.1 (dem Computer) konfiguriert. Ich habe gehört, dass ARP-Tabellen vermasselt werden und Computer ARP-Pakete ignorieren, aber ich kann mir nicht vorstellen, dass das Board ARP-Pakete ignorieren würde, die von meinem Computer speziell an es adressiert wurden – als Antwort auf die Anfragen, die das Board überhaupt gestellt hat.

Also tauche ich in die Datei ethernetif.c von lwIP ein und stelle fest, dass HAL_ETH_GetReceivedFrame_IT(&heth)sie einen Fehler zurückgibt. Diese Funktion gibt einen Fehler zurück, weil (heth->RxDesc->Status & ETH_DMARXDESC_OWN)== 0 statt 1. Ich interpretiere das so, dass die DMA-Puffer derzeit für das MAC-Peripheriegerät bereit sind und noch nichts empfangen haben.

Außerdem habe ich überprüft, dass der HAL_ETH_IRQHandler nie aufgerufen wird.

Ein Problem mit dem PHY?

An diesem Punkt vermutete ich, dass mein PHY selbst schuld war.

Um weiter nachzuforschen, habe ich mein Saleae Logic Pro 16 an alle relevanten Signale angeschlossen und festgestellt, dass sowohl auf den TX0/TX1- als auch auf den RX0/RX1-Leitungen viel Verkehr ist. Hier ist eine Aufnahme von etwas RX-Verkehr mit dem 25-MHz-Eingangstakt:

Erfassung des empfangenen Pakets

RX_ERR ist die ganze Zeit niedrig, es sei denn, ich versuche, den 50-MHz-Taktausgang zu erfassen (was bei einem Gerät wie dem Saleae offensichtlich eine Herausforderung darstellt): In diesem Fall wird RX_ERR gelegentlich für ein paar Pakete hoch geblinkt (was eigentlich ein gutes Zeichen ist — der Stift scheint zu funktionieren).

Nächste Schritte

Ich habe versucht, ETH-Interrupts manuell zu aktivieren, indem ich anrufe, HAL_NVIC_EnableIRQ(ETH_IRQn);nachdem tcpip_init()die Aufgabe aufgerufen wurde MX_LWIP_Init(), und das scheint das Problem nicht zu beheben. Ich bin mir nicht ganz sicher, ob die Ethernet-Interrupt-Routine überhaupt aufgerufen werden soll – das ist die Herausforderung beim Aufrufen eines brandneuen Designs. Ich habe Mühe, das richtige Verhalten des Systems zu bestimmen, damit ich dann feststellen kann, wie sich mein Setup unterscheidet.

Während ich das STM32/STM32CubeMX/FreeRTOS-Zeug schon einmal verwendet habe, habe ich noch nie das Ethernet-Peripheriegerät des STM32 verwendet, und meine einzige Erfahrung mit diesem Zeug ist auf benutzerdefinierten eingebetteten Linux-Systemen, die immer sofort zu funktionieren schienen. Das ist Neuland für mich!

Ich bin mir sicher, dass es irgendwo ein dummes Kontrollkästchen oder eine magische Ethernet_EnableReceive()Funktion gibt, die ich vergessen habe, aber ich kann keine Dokumentation finden, die darauf hindeutet, dass dieses Zeug explizit aktiviert werden muss, und die Beiträge, die ich im Internet sehe, sind alle darauf zurückzuführen, dass sie nichts damit zu tun haben Themen.

Wenn jemand eine Idee hat, würde ich mich über Hilfe freuen!

Nachtrag: FreeRTOS loswerden

Um Dinge zu eliminieren, habe ich die FreeRTOS-Projektkomponente entfernt und bin zu einem Bare-Metal-Projekt zurückgekehrt. In meiner Hauptschleife rufe ich auf MX_LWIP_Process(). Diese Methode sollte die Notwendigkeit von Interrupts eliminieren, aber sie behebt das Problem nicht; Ich kann immer noch keine Frames empfangen. Das lässt mich denken, dass der von STM32CubeMX generierte ETH-HAL-Code etwas enthält.

Lösung

Nur für den Fall, dass jemand in Zukunft auf diese Frage stößt, stellte sich heraus, dass das Problem vertauschte RXD0- und RXD1-Pins waren. Aus diesem Grund konnte ich den Verkehr auf meinem Logikanalysator sehen, aber er wurde nicht von meiner MCU dekodiert.

Wie jemand darauf hingewiesen hat, sind die von mir verwendeten Magnete asymmetrisch und sollten nicht für Auto-MDI-X verwendet werden. Ich hatte keine Probleme. Ich gehe davon aus, dass eines von zwei Dingen passiert: - Die Magnetik funktioniert nicht wirklich in der anderen Ausrichtung, aber da alles, was ich habe, Auto-MDI-X verwendet, bleibt mein Board im Wesentlichen in der funktionierenden Konfiguration, während das andere Gerät eingeschaltet ist das Kabel richtet seine Signale passend aus. - Die Magnetik bietet angesichts der kurzen Ethernet-Läufe eine angemessene Signalintegrität, aber eine Langzeitanalyse würde bei längeren Läufen höhere Raten von Paketverlusten oder Problemen zeigen.

Ehrlich gesagt ist mir nicht klar, warum es wichtig sein sollte, auf welcher Seite des 1:1-Transformators die Netzfilter installiert sind, also bin ich mir außerhalb von PoE-Anwendungen nicht sicher, warum ein symmetrisches oder asymmetrisches Design eine Rolle spielen würde.

Wo ist Wireshark installiert?
Der Computer, mit dem das Board versucht hat, eine Verbindung herzustellen. Ich werde die Frage bearbeiten, um Klarheit zu schaffen.
FWIW, ich würde empfehlen, den FreeRTOS-Stack zu verwenden. (Mir ist klar, dass dies bei Ihrer speziellen Anfrage nicht hilft.) Ich kann bis heute Abend nichts tun, aber wenn es geholfen hat, bin ich mir ziemlich sicher, dass ich ein Projekt für diesen Prozessor habe, bei dem ich Pings mit dem FreeRTOS-Stack zum Laufen gebracht habe. Ich weiß nicht, welcher PHY auf dem Board war, das ich zum Laufen gebracht habe. Wie auch immer, lassen Sie mich wissen, wenn Sie das Projekt haben möchten, ich kann es auf der interaktiven FreeRTOS-Site veröffentlichen.
Das wäre super hilfreich. Ich bin völlig agnostisch gegenüber dem Stack, den ich verwende - ich brauche nur etwas, das ich schnell zum Laufen bringen kann.
Können Sie den Schaltplan für das Hardware-Design posten? Dies scheint ein Firmware-Problem zu sein, aber es wäre trotzdem schön, alle möglichen Hardware-Fragen zu beseitigen.
Schema des Ethernet-PHY gepostet. Diese Pins gehen direkt zurück zum Ethernet-MAC auf dem STM32. CLKIN wird von einem 25-MHz-Oszillator auf dem STM32 erzeugt. Ich habe TX- und RX-Lanes vertauscht und RX-Pins vertauscht, um das Routing zu vereinfachen. Dieser PHY unterstützt Auto-MDX und Polaritätswechsel, glaube ich, also sollte ich keine Probleme haben. Nur um Probleme mit dieser Konfiguration zu beseitigen, habe ich ein Ethernet-Kabel gebaut, das die RX-Swaps rückgängig macht, aber das führt nicht zu einem anderen Verhalten.
Teilenummer der Klinke/Magnetik?
Es ist ein generisches Teil. Ich habe die Pinbelegung zum Abschnitt Hardware der Frage hinzugefügt.
Ich habe das gerade gesehen, da Sie mich in Ihrer Antwort nicht erwähnt haben. Ich werde versuchen, mich daran zu erinnern, es heute Abend im interaktiven Forum zu posten.
Ok, Magnetics können unterschiedliche interne Schaltungen haben, schauen Sie hier mouser.com/ds/2/336/-370307.pdf und Sie müssen tatsächlich die vom Hersteller empfohlene verwenden (mit anderen Worten, mit unterstützter Konfiguration ). Soweit ich weiß, lassen sich Magnetics zumindest in symmetrisch und asymmetrisch einteilen, symmetrisch unterstützt ohne weiteres MDI/MDIX, asymmetrisch nicht. Sie haben sich für Letzteres entschieden. Siehe Abschnitt 3.3 des Datenblatts für den Transceiver. Ändern Sie Ihre Magnetics auf J0011, wie hier angegeben ww1.microchip.com/downloads/en/DeviceDoc/… .
Ich habe versucht, Magnete mit etwas Symmetrischem auszutauschen, und das hat das Problem nicht behoben. Jedoch! Ich habe meinen Schaltplan mit Adleraugen betrachtet und festgestellt, dass ich RXD0 und RXD1 vertauscht hatte. Doh! Deshalb habe ich gesehen, dass RX-Daten aus dem PHY gespuckt wurden, aber nichts vom MAC empfangen wurde. Ich könnte meine alten Magnete wieder auf die Platine löten (nur damit nichts vom Tisch baumelt), und ich denke, das Auto-MDI-X-Protokoll sollte es herausfinden, oder? Die "Link"-LED sollte nur aufleuchten, wenn eine gültige RX/TX-Verbindung hergestellt wird, richtig? Es war immer beleuchtet, sogar mit den alten, asymmetrischen Magneten.
Ausgezeichnet, hoffentlich wird es die Lösung sein. Meines Wissens und meiner Erfahrung nach muss man für MDI/MDIX einen symmetrischen Transformator verwenden. Abschnitt 3.3 des Datenblatts bestätigt dies. Ich weiß jedoch nichts über seine Physik, kann es nicht im Detail erklären.
Nur um die Angelegenheit abzuschließen, habe ich die neuen Magnete wieder gegen die alten ausgetauscht und überprüft, ob der ursprüngliche gut funktioniert. Auto-MDI-X ist ein pessudozufälliger Prozess, wenn beide Seiten über Auto-MDI-X-Fähigkeiten verfügen, aber bisher scheint es, als ob es gut funktioniert, egal wie oft ich Sachen neu einstecke.
+1 von mir für die hervorragend geschriebene Frage mit der gesamten Dokumentation, was Sie versucht haben, was Sie sehen und welche Ideen Sie haben. Und ein virtuelles +2 von mir für die Bearbeitung der Frage, um die Lösung aufzunehmen. Ich wünschte, mehr Leute hätten Fragen geschrieben wie du!
Ihr Transformator ist ein 1:1-Transformator für beide Paare; Das Vertauschen der TX- und RX-Paare macht keinen Unterschied. Die Gleichtaktdrossel soll auf die Leitungsseite gehen, aber das ist nicht das, was ich in dieser Anwendung als asymmetrischen Transformator betrachte.

Antworten (3)

Entschuldigung, dass ich dieses Thema wiederbelebe. Ich konnte nicht bestehen, ohne meine Erfahrung zu erwähnen.

Ich habe diesen HR911105A (RJ45 mit Magnet) bei einem meiner Projekte verwendet.

HR911105A: Geben Sie hier die Bildbeschreibung ein Auf einen Blick erregte eine Sache meine Aufmerksamkeit, nämlich die Verbindung zwischen LAN8720 und RJ45 gemäß Ihrem Schema.

Da sehe ich, dass die Verbindung crossover aussieht. Obwohl verbundene Systeme meistens MDI-X verwenden und daher Receive / Transmit-Paare erkennen, wäre es gut, ihm eine weniger verwirrende Verbindung wie diese zu geben:

LAN -> RJ45
=====================
TXP -> TD+ (Pin #1)
TXN -> TD- (Pin #2)
RXP -> RD+ (Pin #3)
RXN -> RD- (Pin #6)

Pin #4 and Pin #53V3_AN(also die 49,9R-Pullup-Widerstände) wären gut, wenn sie in Ihrem Schaltplan angeschlossen wären, während die andere Seite über einen Kondensator (0,1 uF oder 0,022 uF) mit GND gekoppelt werden sollte.

Vielleicht ist das Ihr Problem, Sie sind Kreuz D0 und D1.

Geben Sie hier die Bildbeschreibung ein

Sie haben Wireshark auf dem PC installiert und verwenden wie Sie sagen, einen USB-zu-LAN-Adapter. Ich bin mir nicht sicher, an welchem ​​physischen Punkt Wireshark Pakete in Ihrem Setup erfasst, und daher ist es eine gute Frage, ob ausgehende Pakete tatsächlich im physischen Netzwerk erscheinen . Ich empfehle Ihnen, einen anderen PC mit Netzwerkschnittstelle anzuschließen und zu prüfen, ob diese PCs miteinander kommunizieren können, indem Sie die Ausgabe von Wiresharks auf ihnen vergleichen.

Ihre Wireshark-Ausgabe zeigt keine Probleme, der PC gibt dreimal bekannt, dass er sich im lokalen Netzwerk befindet und die IP-Adresse 10.0.0.1 hat (wenn er eine Antwort auf eine dieser 3 ARP-Anfragen erhalten würde, würde das Betriebssystem mit einem IP-Adresskonflikt auftauchen).

Dann fragt Ihr Board ständig: Wer hat 10.0.0.1? Sag 10.0.0.2 und PC antwortet mit 10.0.0.1 ist bei ... . Die Frage ist, warum es in Schleife passiert:

  1. Platine empfängt vom PC gesendetes Antwortpaket nicht physisch;
  2. Das Board erwartet etwas anderes oder das empfangene Paket ist beschädigt und verwirft das Paket.

Nehmen Sie daher als nächsten Schritt zur Fehlerbehebung einen anderen PC mit "normaler" Ethernet-Schnittstelle, installieren Sie Wireshark darauf, konfigurieren Sie das Netzwerk auf die gleiche Weise wie für das Board und versuchen Sie, zu sehen, ob das in Wiresharks auf beiden Computern angezeigt wird telnet 10.0.0.1 80. Auf diese Weise würden Sie sicherstellen, dass der PC mit seinem USB-zu-Ethernet-Adapter ordnungsgemäß funktioniert.

Ihre nächsten Schritte hängen von den Dingen ab, die Sie in diesen Wiresharks sehen.

Aktualisieren:

Ich empfange Pakete, sonst würden die RXD0/D1 Pins keine Aktivität zeigen, richtig?

Nicht richtig. Sie möchten glauben, dass Ihr Board Pakete empfängt. Sie sehen, dass sich der Pegel der PHY-Eingangssignale etwas ändert, aber sie repräsentieren nicht unbedingt gültige Pakete. Die Tatsache, dass RX_ERR nicht umschaltet, überzeugt mich nicht sofort davon, dass PHY bei den eingehenden Ereignissen ordnungsgemäß arbeitet oder dass ankommende Informationen richtige Pakete bilden.

Wie auch immer, es liegt an Ihnen, meine Theorie zur Fehlerbehebung ist einfach - Sie müssen auf höherer Ebene sicherstellen, wo Sie auf das Problem stoßen, und sich dann mit dem entsprechenden Teil des Designs befassen. In alle Teile zu graben und alles zu vermuten, ist nutzlos. Es wäre ein großes Glück, wenn Sie Probleme finden würden, die den Fokus verbreiten; Sie versuchen bereits, Software zu vereinfachen. Wenn dies nicht gelingt, werden Sie höchstwahrscheinlich anfangen, Chips zu ersetzen.

Ich denke nicht, dass mein Schritt zur Fehlerbehebung so kompliziert ist, um sicherzustellen, dass ein anderer PC mit dem PC mit Dongle kommunizieren und mir das Gegenteil oder Recht beweisen kann, und somit sicherzustellen, dass Sie zu Recht in die Tiefe graben, wenn Sie vermuten, dass PHY, MAC und Software des Boards funktionieren ihnen.

Obwohl ich es zu schätzen weiß, dass Sie sich die Zeit genommen haben, dies zu schreiben, ist es ziemlich klar, dass mein PHY Pakete von meinem PC empfängt, aber sie werden nicht von meinem Board empfangen. Sonst würde ich die Rx-Daten auf den RMII-Leitungen nicht sehen, richtig? Ich glaube nicht, dass dies eine einfache Netzwerkfrage auf hoher Ebene ist.
@JayCarlson Sie müssen noch beweisen, dass elektrische Signale am Kabelende Ihres Boards richtige Pakete darstellen, die erfasst und nicht verworfen werden können. Warum sich in die Tiefen der Technologie begeben, ohne solch einfache Dinge zu beweisen?
Ist Ihre Theorie, dass mein Computer nicht wirklich die Pakete sendet, die er senden sollte (und dass Wireshark sagt, dass er sendet)? Welche Pakete empfängt mein Board dann? Das Board ist direkt mit meinem Computer verbunden. Dies ist kein kompliziertes Netzwerk-Setup, und jedes vom PHY auf meinem Board empfangene Paket muss von meinem Computer stammen, oder? Ich empfange Pakete, sonst würden die RXD0/D1 Pins keine Aktivität zeigen, richtig? Ihre Hypothese ist, dass etwas Pakete verwirft, richtig? Was ist? Die PH? Das RX_ERR-Bit wird nie gesetzt. Der MAC der MCU? Die Empfangs-ISR wird nie ausgelöst.
Ich habe die Antwort aktualisiert. Seien Sie nicht zweifelhaft und vorgefasst. Komplexe Dinge können einfacher erscheinen, als Sie denken. Einfach handeln und Informationen sammeln.
In Ordnung, ich habe meinen Computer mit demselben Kabel und USB-zu-Ethernet-Adapter mit einem anderen verbunden. Ich habe auf beiden Computern eine Instanz von Wireshark ausgeführt, und sie zeigen identische Daten – etwas ARP-Geschwätz und dann eine erfolgreiche Verbindung zu einem Netcat-Dienst, der auf Port 80 ausgeführt wird. Ich habe das in beide Richtungen getestet. Ich habe versucht, von meinem eingebetteten Board aus eine Verbindung zu diesem Dienst herzustellen, und wie gesagt, ich komme nie an ARP-Nachrichten vorbei. Wenn ich versuche, mich von meinem Computer mit dem Board zu verbinden, kommt es nicht über die ARP-Phase hinaus, da das Board niemals auf die ARP-Anfragen meines Computers antwortet. Ich glaube wirklich nicht, dass es Pakete sind.