STM32F411VE USB-De-Init-Problem mit benutzerdefiniertem Bootloader, das dazu führt, dass der Sprung zur App fehlschlägt

Ich entwickle einen benutzerdefinierten Bootloader auf der STM32F411VE-MCU, der eine .bin-Datei vom USB-Stick herunterladen und in die Anwendungssektoren des Flash-Speichers flashen muss. Nach den Beispielen mit Cube-Bibliotheken konnte ich die Datei korrekt mit dem FAT FS-System öffnen, aber es fällt mir schwer zu verstehen, wie ich den Bootloader verlasse und zu meiner App springe.

Dies sind die Szenarien: 1) Schalten Sie das Board ein, ohne dass ein USB-Schlüssel eingesteckt ist; der code hat kein usb stop/deinit/disconnect call -->boot beendet seine funktion und springt korrekt zur anwendung. Wenn ich den USB-Stick während der Anwendungsdauer einstecke, wird das System neu gestartet. Beachten Sie, dass in meiner Anwendung kein USB-Treiber ausgeführt wird. 2) Einschalten mit eingestecktem USB-Stick; der code hat kein usb stop/deinit/disconnect call --> boot schlägt fehl beim einstellen des MSP der anwendung:

__set_MSP((uint32_t)*APPLICATION_START_ADDRESS); 

3) Einschalten ohne eingesteckten USB-Schlüssel und USBH_Stop-Aufruf, bevor zur App gesprungen wird --> Booten schlägt fehl, wenn der MSP der Anwendung eingestellt wird

Dies ist meine Jump-to-App-Implementierung. Es funktionierte optimal vor dem Einfügen des USB-Host-Treibers

static void JumpToApplication(void)
{
 void (*pmain_app)(void);
 /* First, disable all IRQs */
 __disable_irq();

 SCB->VTOR = (uint32_t)APPLICATION_START_ADDRESS;
__set_MSP((uint32_t)*APPLICATION_START_ADDRESS);

pmain_app = (void (*)(void))*(APPLICATION_START_ADDRESS + 1);

pmain_app();
}

Vielen Dank für die Unterstützung

Woher wissen Sie, dass es beim Einstellen des MSP fehlschlägt? Können Sie die Anweisung im Befehls-Debug-Modus (im Disassemblierungsfenster) schrittweise durchlaufen? Welchen Wert hat das spRegister vorher und nachher? Kannst du die zerlegte Funktion zeigen? Welche Optimierungseinstellungen verwenden Sie?
Ich kann sagen, dass ich die mittlere Optimierung verwende, es tut mir leid, aber ich kann Ihnen die anderen Antworten nicht geben. Wärst du so nett, mich irgendwie zu führen? Ich möchte die Nachteile und Gefahren im Zusammenhang mit der Codeoptimierung besser verstehen

Antworten (1)

Ihr allgemeines Problem besteht darin, zu versuchen, zu einer Anwendung zu verzweigen, nachdem ein Bootloader das System stark betrieben hat. Davon wird beim STM32 dringend abgeraten, da Sie, um es zum Laufen zu bringen, jeden Aspekt des Chips wieder in einen Zustand versetzen müssen, den der Anwendungscode annimmt. Zu den wahrscheinlich offensichtlicheren Fehlern gehören Dinge wie das Einschalten und Auswählen der Takt-PLL (wie für USB erforderlich) und dann der erwartete Anwendungscode, dass die PLL nicht ausgewählt wird, wenn sie mit der Konfiguration beginnt. Aber alles zu jagen wird extrem frustrierend sein, und Sie können mit 90 % Funktionalität, aber 10 % scheinbar unerklärlicher Verrücktheit in einigen Peripheriegeräten zurückbleiben.

Stattdessen ist die übliche Empfehlung, ein Flag im Speicher oder in den RCC-Sicherungsregistern zu setzen, das System neu zu starten und dann das Flag und den Zweig früh beim Start zu erkennen, bevor Sie eine Konfiguration vornehmen. Als ich dies implementieren musste, tat ich es in Assembler, bevor sogar der C-Start ausgeführt wurde; Das war wahrscheinlich unnötig, wenn Sie sich jedoch für die Verwendung eines Speicherflags entschieden haben, achten Sie auf die Wahrscheinlichkeit, dass der Startcode den RAM initialisiert. Wenn das Aufrufen des Bootloaders eine explizite Aktion erfordert, benötigen Sie nicht einmal das Flag, sondern nur, um zu überprüfen, ob der GPIO "Im Bootloader bleiben" oder eine andere Bedingung nicht erfüllt ist und dass eine Anwendung vorhanden ist, die mit der von Ihnen verwendeten Gültigkeitsprüfung übereinstimmt.

boot schlägt fehl, wenn der MSP der Anwendung festgelegt wird

Das ist einfacher erklärt. Ihr Code versucht, eine lokale Stapelvariable zu verwenden, die zugewiesen wurde, bevor sie den Stapelzeiger änderte, was im Wesentlichen ein Rezept für eine Katastrophe ist. Wenn Sie das tun, möchten Sie den Stack nicht mehr verwenden, nachdem Sie ihn geändert haben.

Die Verwendung eines Flags im Speicher, um die Notwendigkeit zu erkennen, Peripheriegeräte im Bootloader zu initialisieren, wäre mit Sicherheit eine großartige Technik, um mein Problem zu umgehen. Andererseits muss ich möglicherweise einen Bootloader implementieren, der erkennen kann, ob ein USB-Stick eingesteckt ist, und schließlich selbst mit dem FW-Upgrade beginnen kann. Bitte beachten Sie, dass ich vor der Initialisierung von USB einige Timer und Uhren und PLL in meinem Bootloader ohne Probleme verwendet habe. Genauer gesagt habe ich getestet, dass die Funktion, die alles kaputt macht, "USBH_Start" ist. Wenn ich USB nicht starte, sondern nur initiere, passiert kein Problem
Ihr automatisches Upgrade ist nicht unvereinbar mit einem Selbst-Reset in den Löschzustand. Sie können gerne versuchen, das spezifische Problem zu identifizieren und zu beheben, aber die bewährte Methode auf dieser Plattform ist das Zurücksetzen - dort endete jede andere Version dieser Frage, die gestellt wurde