(Aktualisiert) Seltsames Reset-Verhalten mit ARM9-Prozessor

Ich arbeite daran, ein Boot-Problem mit einem Atmel AT91SAM9G20-Board zu debuggen. In den ersten 700 ms läuft alles super. Es scheint, dass der Prozessor etwa 700 ms nach dem Zurücksetzen einfriert. Merkwürdig ist, dass die CPU die Reset-Leitung ansteuert, nachdem ich die Reset-Taste losgelassen habe.

Hier ist eine Scope-Aufnahme, die zeigt, was los ist. Die gelbe Spur ist die Reset-Leitung. Der erste Einbruch ist die Zeit, in der ich tatsächlich die Reset-Taste gedrückt halte. Der zweite Einbruch wird, glaube ich, von der CPU erzeugt.

Die blaue Spur sind serielle Daten, die aus der CPU kommen. Die ersten beiden Bursts stammen vom anfänglichen Bootloader. Der dritte Burst ist der U-Boot-Start. Die CPU hört auf, Zeichen auszusenden, wenn der dritte blaue Burst endet.

Wenn ich die Spuren richtig interpretiere, bedeutet dies, dass die Reset-Leitung fast genau für die Zeit niedrig ist, in der der Prozessor U-Boot vom NAND-Flash lädt.

zwei Oszilloskopspuren

Ich habe ein paar Fragen:

  • Ist diese Art von CPU-gesteuertem Zurücksetzen normal?
  • Irgendwelche Vorschläge, wie man das debuggen kann?

Noch ein paar Details: Ich sollte hinzufügen, dass ich mir die Stromschienen angesehen habe und sie sauber aussehen. Das folgende Verhalten ist reproduzierbar. Ich kann die Länge des anfänglichen Reset-Dip (in Gelb) um einige Sekunden variieren, und der Rest des Verhaltens geschieht auf die gleiche Weise. Wenn ich das JTAG-Kabel einstecke, ändert sich das Verhalten – manchmal bootet es, manchmal nicht, aber nach ein paar Sekunden übernimmt JTAG und der Prozessor wird angehalten.

Unter JTAG kann ich erfolgreich booten. So sieht ein erfolgreicher JTAG-gesteuerter Boot aus:

Ein weiterer Scope-Screenshot, aber mit mehr seriellen Daten

Beachten Sie, dass die Zeitskala unterschiedlich ist und ich nicht die Reset-Taste drücke – sie ist softwaregesteuert. Der gleiche Reset-Dip tritt auf. In beiden Fällen beträgt die Länge etwa 500 ms.

Update (immer noch verblüfft)

Angeregt durch Mr. Taffeys Vorschlag unten habe ich den Watchdog-Timer und den Reset-Controller genauer untersucht. Der Watchdog-Timer wird tatsächlich vom ersten Bootloader deaktiviert; Ich bin mir ziemlich sicher, dass Code ausgeführt wird, da er auftritt, bevor Text über die serielle Debug-Schnittstelle gesendet wird, und ich den Text erfolgreich lesen kann.

Beim Lesen der Details des Reset-Controllers erfuhr ich, dass der Prozessor die Kontrolle über den Reset-Pin übernehmen und ihn für kurze Zeit auf Low ziehen soll . Dadurch soll sichergestellt werden, dass andere Hardware auf der Platine, die dieselbe Leitung abhört, einen ausreichend langen Reset erhält. Beim Durchstöbern von U-Boot stellte ich fest, dass die Dauer des Zurücksetzens mithilfe des ERSTL-Felds auf 0x0D eingestellt war:

at91_sys_write(AT91_RSTC_MR, AT91_RSTC_KEY |
  (AT91_RSTC_ERSTL & (0x0D << 8)) |
  AT91_RSTC_URSTEN);

Das Datenblatt erklärt, dass die Dauer auf 2 ^ (ERSTL + 1) langsame Taktperioden eingestellt ist.

Die Reset-Dauer sieht ungefähr 500 ms lang aus, der langsame Taktkristall ist 32768 Hz, und Google sagt mir, dass log (0,500 * 32768) / log (2) = 14 und 0x0D + 1 = 14, also macht das alles Sinn.

Ich denke, das eigentliche Problem könnte der Absturz von U-Boot sein; Die Tatsache, dass es direkt nach diesem Reset passiert, ist wahrscheinlich irrelevant. Verwirrend ist, warum U-Boot nur abstürzen würde, wenn JTAG nicht verbunden ist.

Zweite Aktualisierung

Ich weiß immer noch nicht, was schief läuft oder warum JTAG dafür sorgt, dass es sich anders verhält, aber ich glaube, ich habe (irgendwie) eine Problemumgehung gefunden. Es sieht so aus, als ob der U-Boot-Absturz in irgendeiner Weise durch den NAND-Flash auf der Platine verursacht wird. Zufälligerweise verwendet die nächste Revision des Boards, die erst kürzlich eingetroffen ist, eine microSD-Karte anstelle von NAND-Flash für die nichtflüchtige Massenspeicherung (nun, es gibt NAND-Flash in der microSD-Karte, aber Sie sehen den Punkt).

Meine "Lösung" besteht darin, einfach die nächste Revision des Boards zu verwenden. U-boot stürzt auch ab, aber aus bekannten Gründen – es ist so konfiguriert, dass es nach einem NAND-Flash sucht, den es nicht finden kann. Daher stirbt es einen feurigen Tod.

Also Problem "gelöst". (Erwarten Sie in Kürze eine weitere Frage in der Art von „Wie bringe ich AT91Bootstrap dazu, U-Boot von einem seriellen Flash zu laden?“ oder „Wie bringe ich U-Boot dazu, mit einer microSD-Karte zu funktionieren?“ oder „Warum mache ich das?“ )

Das grüne Häkchen geht wohl an Joby für die Feststellung, dass die Reset-Leitung vom Mikro angesteuert werden kann, auch wenn sich das auf Dauer als irrelevant herausgestellt hat. Danke für die Hilfe, euch allen. Ich schätze es.

Drittes Update (etwa eine Woche später)

Ich habe in letzter Zeit hauptsächlich an anderen Sachen gearbeitet, aber irgendwann habe ich herausgefunden, was das Problem war. Mein letztes Rätsel habe ich oben zusammengefasst als:

Verwirrend ist, warum U-Boot nur abstürzen würde, wenn JTAG nicht verbunden ist.

Tatsächlich stellte sich heraus, dass ich U-boot verwechselte, weil es keine Zeichen über den seriellen Debug-Port senden konnte, weil U-boot abstürzte. Ich verstehe die Details immer noch nicht, aber ich habe festgestellt, dass es nicht JTAG ist, das U-Boot zum Laufen bringt - es ist eine gemeinsame Masse zwischen meiner Schaltung und dem USB-Host meines PCs, die JTAG bereitgestellt hat, weil es durchläuft der USB-Port. Tatsächlich funktionierte U-Boot die ganze Zeit einwandfrei, aber immer wenn JTAG getrennt wurde, funktionierte der RS-232-zu-USB-Pegelumsetzer, den ich mit dem Steckbrett versehen hatte, nicht mehr, die serielle Schnittstelle fiel aus, und ich würde annehmen, dass U-Boot war tot. In Wirklichkeit entdeckte ich, dass ich beispielsweise immer noch Ping-Befehle eingeben und die erzeugten ICMP-Pakete sehen konnte, obwohl meine Zeichen nicht auf dem Terminal wiedergegeben wurden.

Ich verstehe nicht genau, was schief gelaufen ist, aber es ist mir auch egal - ich kann leicht einen anderen Weg finden, um die serielle Schnittstelle zu lesen, und kurzfristig kann ich einfach die Verbindung zur USB-Masse mit einem Kabel herstellen .

Danke für die Hilfe, alle.

"Interessant" ... das ist alles, was ich zu sagen habe.
wahrscheinlich eine dumme Frage, aber Ihre Reset-Schaltung (die Taste) hat einen Pull-up-Widerstand, oder? Ich meine, wenn die Taste nicht gedrückt wird, bleibt der Reset-Pin nicht schwebend. Zusätzlich könnten Sie auch eine Entprellkappe auf der Reset-Taste ausprobieren, um ein ungewöhnliches Verhalten durch Prellen der Reset-Leitung auszuschließen.
(Keine dumme Frage – das war eines der ersten Dinge, die ich überprüft habe.) Ja, da ist ein Klimmzug am Knopf. Es gibt keine Entprellkappe, aber ich habe mir die steigende Flanke genau angesehen und sie springt nicht nachweisbar. Der Fehler tritt fast 1 Sekunde nach dem Loslassen der Taste auf, daher denke ich, dass ich das ausschließen kann.
Ich würde wahrscheinlich anfangen, Code aus u-boot zu rippen, um herauszufinden, wo es abstürzt ... Vielleicht führt Ihr JTAG-Adapter einen Reset durch und hält dann die CPU für eine Weile an - was etwas anderem auf der Platine Zeit gibt, richtig hochzufahren
JTAG beeinflusst es, dies sagt Ihnen nur sicher, dass Sie in der Lage sein sollten, etwas Verwandtes im Uboot-Code zu finden.

Antworten (3)

Blick ins Datenblatt:

14.3.4.5 Watchdog-Reset Der Watchdog-Reset wird eingegeben, wenn ein Watchdog-Fehler auftritt. Dieser Zustand dauert 3 langsame Taktzyklen.

Im Watchdog-Reset hängt die Geltendmachung der Reset-Signale vom WDRPROC-Bit in WDT_MR ab: Wenn WDRPROC 0 ist, werden das Processor Reset und das Peripheral Reset geltend gemacht. Je nach Programmierung des Feldes ERSTL wird auch die NRST-Leitung aktiviert. Der resultierende niedrige Pegel an NRST führt jedoch nicht zu einem Benutzerrücksetzzustand.

Könnte es sein, dass der Watchdog feuert und die Reset-Leitung treibt?

Das nächste, was ich lesen wollte, war über den Watchdog-Timer, sie können seltsame Probleme verursachen, aber ich war mir nicht sicher, ob der JTAG den Watchdog deaktivieren und das Problem beenden würde.

Dies kann ein langer Schuss sein. Auf einem viel niedrigeren Mikrocontroller, einem PIC, habe ich vielen Leuten mit seltsamen Resets geholfen, weil ein Niederspannungs-Programmierstift aktiviert war.

Wenn ein Programmiergerät angeschlossen ist, hält es ähnliche Leitungen auf einer eingestellten Spannung, wenn das Programmiergerät getrennt wurde, könnten sie leicht schweben. Bei einem Projekt würde das Gerät zurückgesetzt, wenn es Metall überquerte. Sie haben LVP nicht überprüft, als ich sie darum gebeten habe, sie haben noch 2 Wochen gearbeitet und es dann deaktiviert und das Problem war gelöst.

Ich denke nicht, dass das überhaupt ein langer Weg ist. Es ist möglicherweise kein LVP- oder ähnlicher Pin, sondern ein beliebiger schwebender Eingang. Wir haben einen PowerPC erlebt, der mit einem schwebenden allgemeinen E/A-Eingang totgelaufen ist, nur weil der Pegel des Eingangs früh im Code überprüft wurde.

Sind die JTAG-Leitungen eines beliebigen Geräts mit Dingen verbunden, die sie nicht sein sollten?

Sagen wir zum Beispiel Adressbuslinien?

(Es hat Monate gedauert, dieses eine Mal zu debuggen.)

Gute Idee. Ich habe gerade den Schaltplan und das PCB-Layout überprüft. Ich sehe keine versehentlichen Kreuzungen oder Fehlverbindungen von Adresszeilen. Mir ist aufgefallen, dass sich der JTAG-Anschluss direkt unter dem RAM befindet, aber sie sind durch zwei Stromversorgungsebenen getrennt, und das Board bootet korrekt unter JTAG-Steuerung. Wenn der JTAG inaktiv ist, tritt das Problem auf.
Sie ziehen das jtag tclk und trst in sichere Zustände?
Ja, alle JTAG-Eingänge werden auf 3,3 V hochgezogen, sodass sich ihr Zustand nicht ändern sollte, es sei denn, JTAG ist angeschlossen und treibt sie an.