Guten Tag,
für meine Anwendung mit einem STM32F042K6 möchte ich ermöglichen, dass
man über den eingebauten USB-Port in den Bootloader springen kann, um
mit z.B. STM32CubeProgrammer die Firmware zu aktualisieren.
- Verwendet wird der USB-Port, wenn das Gerät nicht programmiert werden
soll, als Virtual COM Port (VCP) mit dem USB Device (FS) Treiber
- Option Bits: nBOOT0 = 1, nBOOT1 = 0, BOOT_SEL = 0
- Der Boot0-Pin wird als GPIO, konfiguriert als Input mit Pullup
verwendet
- Ich verwende STM32CubeMX, die HAL und SystemWorkbench als
Programmierumgebung.
- Weitere verwendete Peripherie, falls relevant: TIM2, TIM16, I2C1, SPI1
- Clock: 48 MHz (HSI48), USB: 48 MHz
Mein Ansatz besteht bisher weitgehend daraus, die Schritte der Anleitung
hier: https://www.youtube.com/watch?v=cvKC-4tCRgw zu replizieren, und
sie natürlich an meiner Anwendung anzupassen, bisher allerdings
vergeblich. Hier der adaptierte Code:
1 | void (*sys_mem_boot_jmp)(void);
|
2 | void activate_bootloader(uint32_t bootloader_status) {
|
3 | if(bootloader_status == 1) {
|
4 | HAL_RCC_DeInit();
|
5 |
|
6 | SysTick->CTRL = 0;
|
7 | SysTick->LOAD = 0;
|
8 | SysTick->VAL = 0;
|
9 |
|
10 | __disable_irq();
|
11 | sys_mem_boot_jmp = (void (*)(void)) (*((uint32_t *) ((0x1FFFC400 + 4))));
|
12 |
|
13 | // __set_PRIMASK(1); // Disable Interrupts
|
14 | __set_MSP(*(__IO uint32_t*)0x1FFFC400);
|
15 | sys_mem_boot_jmp();
|
16 |
|
17 | while(1);
|
18 | }
|
19 | }
|
Erläuterung: Nach Application Note AN2606, S. 43 von STM ist die Adresse
0x1FFFC400 die System Memory Start Address, demnach soll der Sprung bei
der Adresse +4 liegen; da in 0x1FFFC400 die Default-Stack Adresse liegt,
wird sie bei __set_MSP einmal geladen.
Die Funktion
1 | void activate_bootloader(uint32_t)
|
wird (erfolgreich) getriggert, wenn im Serial-Protokoll des Virtual COM
Ports (User Code) das Kommando zur Anforderung eines Firmware-Updates
erkannt wird.
Die Funktion wird erfolgreich ausgeführt. Beim Debuggen sieht man, dass
es sich weder in eine HardFault aufhängt, noch in die InfiniteLoop geht
bei while(1). Dennoch wird im CubeProgrammer weder ein Gerät im
DFU-Modus erkannt (No Device Found), noch lässt sich eine Verbindung
darin mittels UART herstellen (Timeout).
Mache ich irgendeinen offensichtlichen Fehler? Was mache ich falsch?
Falls etwas fehlt, werde ich es schnellstmöglich ergänzen.
Danke im Voraus und bleibt gesund.
Liebe Grüße.