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
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.
folgte Monica zu Codidact
sp
Register vorher und nachher? Kannst du die zerlegte Funktion zeigen? Welche Optimierungseinstellungen verwenden Sie?Gdivella