Bootloader-Sprung zum Hauptanwendungsproblem bei Verwendung von STM32 mit Keil Uvision

Ich entwickle für den STM32F0 mit Keil uVision.

Ich habe einen benutzerdefinierten Bootloader geladen, der unter der Adresse 0x08000000 ausgeführt wird. Ich brauche den Bootloader, um zu meiner Hauptanwendung zu springen, die ich unter der Adresse 0x08003000 flashe. Das ultimative Ziel ist es, Remote-Updates der Hauptanwendung zu ermöglichen. Der Bootloader-Code, der zur Anwendung springt, lautet wie folgt:

__disable_irq();
JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS+4);
Jump_To_Application = (pFunction) JumpAddress;
__set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS);
Jump_To_Application();

Ich erhalte einen harten Fehler in der Zeile Jump_To_Application() mit der Meldung „Cannot access memory“ von Keil.

In Keil habe ich die IROM1-Startadresse in der Projektkonfiguration meiner Hauptanwendung auf 0x08003000 gesetzt. Ich habe das Gefühl, dass das Problem in einigen weiteren Einstellungen in Keil liegt. Sollte IROM2 beispielsweise auf irgendetwas eingestellt werden? Sollte etwas von den Standardeinstellungen in der Keil-Konfiguration innerhalb des Bootloader-Projekts angepasst werden?

Hat jemand irgendwelche Empfehlungen?

Haben Sie eine gültige Bewerbung unter der Adresse 0x08003000?
Können Sie die relevanten Teile Ihrer Linker-Skripte (Bootloader und Anwendung) hinzufügen?
Batuu - Ich verwende STLink, um die Anwendung bei 0x08003000 zu flashen.
rfkortekaas - Ich gehe davon aus, dass Keil basierend auf der GUI-Konfiguration produziert. Ich konfiguriere eigentlich keine Skripte manuell. Welche Dateien müssen Sie sehen?

Antworten (2)

Ich hatte das gleiche Problem: Ich habe es mit diesen Zeilen auskommentiert gelöst:

__disable_irq();
__set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS);

Einige Ratschläge für alle, die zum ersten Mal einen Bootloader schreiben:

Verwandeln Sie Ihren Code in kleine Abschnitte:

  1. Schreiben Sie im ersten einen einfachen Blinkcode ohne Interrupt.
  2. Verwenden Sie die Fähigkeit zum Löschen von Sektoren und schreiben Sie Ihren Bootloader und Ihren Anwendungscode in Flash. Jetzt müssen Sie nur noch versuchen, vom Bootloader in den Anwendungscode zu springen. Wenn es funktioniert, bedeutet dies, dass Ihr Sprung korrekt ist.
  3. Versuchen Sie nun, Ihren Anwendungscode mit USART (oder mit einem anderen Peripheriegerät) zu erhalten und in Flash zu schreiben. Es muss funktionieren, wenn nicht, bedeutet es, dass Flash falsch geschrieben ist (Hex-Code-Datei öffnen und Flash-Daten, Flash-Adresse und andere Dinge mit Hex-Datei vergleichen) (Achtung auf Little_endian-Schreiben)
  4. Schreiben Sie nun einen Blinkcode mit Timer und Interrupt. Es muss funktionieren, wenn nicht, bedeutet es, dass der Fehler in der springenden Vektortabelle liegt

Sie müssen den Offset der Vektortabelle neu konfigurieren. Der Offset ist die Startadresse Ihrer App.

Ihr Bootloader-Code sollte so aussehen:

__disable_irq();
JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS+4);
Jump_To_Application = (pFunction) JumpAddress;
SCB->VTOR = APPLICATION_ADDRESS;
__set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS);
Jump_To_Application();

Und wenn Sie STM32CubeMX zum Generieren Ihres Codes verwendet haben, müssen Sie dieselbe Codezeile am Anfang von main() Ihrer App hinzufügen:

 SCB->VTOR = APPLICATION_ADDRESS;

Da die Systeminitialisierung den Offset der Vektortabelle zurücksetzt, muss der Offset neu konfiguriert werden, sodass er auf die Startadresse Ihrer App zeigt.