Einfrieren des STM32F7-Geräts: Zugriff auf Register nicht möglich

Beim STM32F7 treten zufällige Einfrierungen auf. Dieses Problem ist schwer zu debuggen, da jede in Eclipse gestartete Debug-Sitzung beim Versuch, den Kern anzuhalten, abstürzt, wodurch es unmöglich ist, zu erkennen, wo im Code das Einfrieren aufgetreten ist.

Ebenso kann ich nicht auf die Geräteregister zugreifen, um den Programmzähler, den Stapelzeiger und das IPSR zu überprüfen, weder über die Eclipse-Debug-Sitzung noch über die ST-Link-Dienstprogrammsoftware (das Gerät wird beim Verbinden zurückgesetzt und der Status geht verloren). .

Ich würde mich über Informationen freuen, wie der Gerätestatus im eingefrorenen Zustand extrahiert werden kann oder ob nach einem Reset irgendwelche Zustände wiederhergestellt werden können. Auch wenn diese Situation jemandem bekannt vorkommt, lassen Sie es mich bitte wissen, wenn Sie eine Grundursache gefunden haben. Für Fragen und weitere Details stehe ich gerne zur Verfügung.

Weitere Details

(a) Die Hardware - Ich fürchte, ich kann Ihnen hier nicht zu viele Informationen geben, es ist ein kundenspezifisches proprietäres Design.

(b) Die Geschichte – Dieses Problem des Einfrierens ist erst vor kurzem zu einem Problem geworden. Als ich unseren älteren Code erneut testete, wurde das Problem jedoch gesehen, wenn auch weniger häufig (glaube ich). Ich habe Codebits zurückgesetzt, um zu sehen, ob das Problem weiterhin auftritt. Das Problem ist, dass ich keine Protokolle oder Debugging-Funktionen habe, wenn das Gerät einfriert, sodass ich nicht genau feststellen kann, wo der Code fehlschlägt.

Das Problem tritt selten auf, daher ist es schwierig zu sagen, ob eine Änderung Auswirkungen hatte oder nicht.

(c) Ich habe nicht versucht, die (System-?) Taktfrequenz zu reduzieren, und ich werde das Gerät erneut gründlicher testen, wobei verschiedene Verbindungen entfernt werden.

(d) Die Ausfallrate beträgt ungefähr 1 Ausfall pro Gerät und Tag, aber es ist schwierig, Verbesserungen/Rückgänge zu quantifizieren (Gerät läuft den ganzen Tag).

(e) Sie fragen nach dem Erfassen von Daten nach einem Reset, aber Sie berichten, dass das Problem darin besteht, dass die MCU "einfriert", nicht dass sie zurückgesetzt wird. Ich vermute (aber es ist nicht klar), dass das Problem immer darin besteht, dass die MCU einfriert. Sie können ein manuelles Zurücksetzen durchführen, und Sie fragen, ob nach dem manuellen Zurücksetzen nützliche Informationen erfasst werden können. Ist das korrekt?

Richtig. Das Abrufen von Informationen während des Einfrierens wäre jedoch noch besser.

Schritte debuggen

(i) Dieses Problem ist trotz meiner Bemühungen nicht mit einem Test reproduzierbar.

(ii) was machst du danach zB führst du einen manuellen Reset durch?

Versuchen Sie, die Register zu lesen, und stellen Sie fest, wo der Code hing.

Was Sie idealerweise wünschen, ist die Funktionalität, die an das Ziel angehängt werden kann, während es ausgeführt wird. Ich verwende Ihre Toolchain nicht, daher habe ich keine Ahnung, ob dies möglich ist. Diese Website bietet einige Informationen mit einem Segger J-Link, und ich habe eine leichte Erinnerung daran, dass ein ST-Link zu einem J-Link aufgerüstet werden kann (nicht sicher, ob es nur die auf den Nucleo-Boards waren). Aber auch ohne das könnte es helfen, da der Weg auch für den ST-Link funktionieren könnte.
Klingt für mich nach einem Hardware-Reset-Problem. Handelt es sich um ein einmaliges Design?
Warten auf eine unvollständige IO
Wie ist das System getaktet? Verwenden Sie Standard-Uhrenkonfigurationscode (z. B. CubeMX)?
@Arsenal Ich werde das testen, danke für den Tipp!
@Andyaka nein, dieses Problem ist auf mehreren (identischen) Geräten reproduzierbar
@ SunnyskyguyEE75 ja, ich dachte, ich denke, es hängt mit Unterbrechungen zusammen, da es asynchron ist
@ Jon Standard-Taktkonfiguration, 216 MHz
@nick - Bitte bearbeiten Sie Ihre Frage, um weitere Details hinzuzufügen: (a) Erklären Sie die Hardware - ist dies Ihr Design oder ein Standard-Entwicklungsboard? Fügen Sie der Frage Fotos der Hardware hinzu. (b) Angenommen, es ist Ihr Design, erklären Sie die Vorgeschichte – war dies schon immer ein Problem, oder gab es eine Zeit, in der dieses Problem nicht auftrat? Welche Fehlersuche hast du bisher gemacht? (c) Welche Vereinfachung können Sie am System vornehmen (oder haben Sie bereits vorgenommen), z. B. Verringerung der Taktfrequenz? Externe Verbindungen entfernen, nur "Blink-LED" -Code usw. ausführen? (d) Was ist die Ausfallrate und haben Sie etwas gefunden, das sie verändert?
(e) Sie fragen nach dem Erfassen von Daten nach einem Reset, aber Sie berichten, dass das Problem darin besteht, dass die MCU "einfriert", nicht dass sie zurückgesetzt wird. Ich vermute (aber es ist nicht klar), dass das Problem immer darin besteht , dass die MCU einfriert. Sie können ein manuelles Zurücksetzen durchführen, und Sie fragen, ob nach dem manuellen Zurücksetzen nützliche Informationen erfasst werden können . Ist das korrekt? Bearbeiten Sie bitte erneut die Frage, um Details zu den genauen Schritten hinzuzufügen, die Sie befolgen, um (i) den Test durchzuführen, der das Problem auslöst, und (ii) was Sie danach tun, z. B. führen Sie einen manuellen Reset durch? (f) Bitte fügen Sie auch einen Schaltplan hinzu. Danke.
@SamGibson danke, ich werde das klären
Die üblichen Verdächtigen: MCU-Reset inkl. Watchdog, Taktverlust, Stromausfall/Brown-Out.

Antworten (2)

Wenn der Debugger gesperrt ist, vorausgesetzt, die Stromversorgung/Taktung ist in Ordnung, dann ist das wahrscheinlichste Ergebnis ein interner Bus-Deadlock. Wenn Sie beispielsweise ein externes XIP-EEPROM haben und das Gerät falsch konfiguriert haben, kann das Peripheriegerät hängen bleiben, wenn Sie auf bestimmte Adress-/Datenmuster treffen.

Möglicherweise können Sie nach dem Zurücksetzen immer noch RAM-Informationen lesen (oder eine Ablaufverfolgung hinzufügen, um etwas in den RAM zu kopieren). Die zentralen Architekturregister werden nicht zurückgesetzt (es sei denn, Sie haben einen hochzuverlässigen sicherheitsspezifischen Teil). Wenn Sie also ein B selfin den Reset-Handler einfügen (vorausgesetzt, der Debugger „Halt nach Reset“ funktioniert nicht), sollte Ihr alter Zustand erhalten bleiben .

Sie können den ETM-Trace verwenden, um den Echtzeit-Trace zu erfassen, und wenn Sie den Trace im ETB erfassen, können Sie diesen nach dem Zurücksetzen einfach auslesen (auch hier sollte er dauerhaft sein), ohne dass eine Sonde erforderlich ist (aber möglicherweise geht der Pufferzeiger verloren, also Sie möglicherweise muss die Ablaufverfolgung manuell verarbeitet werden). Die ETM-Ablaufverfolgung zeigt Verzweigungen (Adressen für alle indirekten Verzweigungen) und Ausnahmen (einschließlich Sperren) an - Sie sollten also einen ziemlich genauen Hinweis darauf erhalten, was das letzte Ding war. Insbesondere "beobachtet" die Ablaufverfolgung nur den Kern, sodass Befehle zurückgezogen werden, ohne von der Busaktivität beeinflusst zu werden. Die DWT könnte auch etwas Nützliches geben - je nachdem, was tatsächlich fehlschlägt.

Wie in einem der Kommentare erwähnt, können Sie zumindest mit MDK eine Verbindung zu einem "heißen" laufenden Ziel herstellen (ohne Zurücksetzen / Anhalten, ohne Code-Download), da der Debug-Port ein vollständig asynchroner Busmaster ist, der in den Kern eingebettet ist . Dies gibt Ihnen die Möglichkeit, den Speicherstatus auf einem Gerät mit langer Betriebszeit (aber nicht Kernregister) mit minimalem Eingriff zu prüfen, und dies kann wertvoll sein, um eine Diagnose zu bestätigen. Sie könnten sogar eine regelmäßige Abfrage von Speicherorten skripten, wenn dies relevant ist.

Da sich der Debug-Port schließlich wie der Kern verhält, können Sie viele Bus-Deadlock-Fehler nachahmen, indem Sie einfach das Debugger-Speicherfenster verwenden.

Versuchen Sie auch, Keil MDK zu verwenden. Es ist möglich, dass dies mehr Glück beim Verbinden mit einem unzufriedenen Zielgerät hat. Es sollte Ihre STLink-Sonde unterstützen.

Ich empfehle Ihnen, nicht sofort zu irgendwelchen Schlussfolgerungen zu kommen. Da Ihr Design proprietär ist, wissen wir nicht viel über die Hardware. Daher kann ich Ihnen einige allgemeine Tipps zur Fehlerbehebung vorschlagen.

  1. Das Problem könnte ein Kurzschluss irgendwo auf der Platine oder eine offene Verbindung oder vielleicht eine lockere Verbindung sein. Wir wissen nicht, was es sein könnte. Reinigen Sie also zuerst die gesamte Platine mit Isopropylalkohol (auch bekannt als PCB-Reiniger), reiben Sie sie gut mit einer Zahnbürste ab und wischen Sie dann mit Kimwipes den Schmutz / Staub / Metallteile usw. ab. Überprüfen Sie, ob der uC funktioniert. Wenn dies nicht der Fall ist, überprüfen Sie die PCB-Nachreinigung auf gebrochene Spuren, beschädigte PCB-Pads, kalte Lötstellen usw. Vorzugsweise sollten Sie in diesem Stadium versuchen, die gesamte Platine zu überarbeiten, um das Problem „lockere Verbindungen/Verbindungen“ zu beseitigen. Überprüfen Sie, ob der uC danach funktioniert.

  2. Wenn der uC immer noch nicht funktioniert, überprüfen Sie grundlegende Dinge wie Schwankungen der Stromversorgung, Rauschen auf den Signalleitungen, Taktimpulse des uC usw. Verwenden Sie ein DSO, um die Taktimpulse und die Reset-Leitung zu überwachen. Auch auf Durchgang an allen Steckern prüfen. Wackeln Sie an den Kabeln, wenn der uC läuft, und prüfen Sie, ob das Problem behoben ist. Überprüfen Sie diese Dinge und versuchen Sie es dann erneut am uC.

  3. Wenn das Problem dadurch nicht behoben wird, überprüfen Sie die Software. Flashen Sie den Code auf einem neuen uC (kein neues Entwicklungsboard!). Erstellen Sie Ihr eigenes Barebone-Entwicklungsboard. Mit Barebones meine ich keine angeschlossenen Peripheriegeräte, keine externen Schaltkreise. Nur die Uhr und einige Regler, das war's! Sie müssen sicherstellen, dass der Code den uC nicht einfriert. Das Eliminieren der externen Peripheriegeräte beseitigt die von ihnen verursachten Probleme (falls vorhanden). Jetzt wird also Ihre Software getestet. Wenn Sie Ihr eigenes Barebone-Entwicklungsboard erstellen, blinken Sie einen LED-Blinkcode, um sicherzustellen, dass es funktioniert. Flashen Sie dann Ihre Software auf dem uC und prüfen Sie, ob der uC einfriert oder nicht. Wenn es dann glücklich ist, war es die Software, die das Problem verursachte. Nehmen Sie die notwendigen Änderungen in der Software vor und sorgen Sie dafür, dass sie auf dem Barebones-Entwicklungsboard funktioniert. Sobald es auf dem BB-Devboard perfekt funktioniert,

  4. Wenn der uC immer noch einfriert, bedeutet dies, dass Sie möglicherweise einige „nicht zu berührende“ Registerbits des uC über die Software geändert haben. Überprüfen Sie Ihre Software und notieren Sie sich alle Register und Bits, die sie ändert. Stellen Sie sicher, dass die Software das uC auf sichere Weise verwendet.

  5. Wenn das Problem weiterhin besteht, überprüfen Sie, ob das von Ihnen verwendete Flash-Tool ordnungsgemäß funktioniert oder nicht. Tun Sie dies, indem Sie das Flash-Tool verwenden, um „gesunde“ uC-Boards zu debuggen. Wenn die Operation erfolgreich ist, ist Ihr Flash-Tool in Ordnung.

  6. Wenn Ihre Software alle uC einfriert, liegt es wahrscheinlich an der Software. Überprüfen Sie, ob STMm32F7 so etwas wie "Verwenden Sie einen Hochspannungs-Parallelprogrammierer zum Zurücksetzen der Sicherungsbits" bietet. Bricked Atmel MCUs können mit HVPP wiederbelebt werden.

Probieren Sie diese Methoden aus und lassen Sie mich wissen, was passiert. Seien Sie beim Debugging-Prozess geduldig und beseitigen Sie Probleme nacheinander. Denken Sie daran, Codieren ist eine Fähigkeit, aber Debuggen ist eine Kunst!

Während diese Liste für allgemeines Debuggen gültig ist, geht sie nicht wirklich auf die Frage „Wie kann ich den Zustand des Kerns extrahieren“ ein. Das OP fragt nach den Funktionen eines bestimmten Geräts. Beim DAP-Debug haben wir einen Überblick darüber, welche Schicht des Protokolls stecken geblieben ist, und das Debugging ist so konzipiert, dass es auch das Heraufbringen von Silizium erleichtert – es gibt also einige ziemlich spezifische Anleitungen, wenn wir diesen Weg einschlagen müssen.