In meinem Fall würde ich gerne die uC's vorerst mit einem I2C Bootloader bespielen, so dass die User Application später nachgeladen werden kann. Meine Bootloader Implementierung ist soweit fertig. Der STM32 läßt sich als I2C Slave ansprechen, empfängt Daten und schreib diese ins Flash. Den Bootloader würde ich gerne auf die letzten Pages des Controllers platzieren. Der uC soll den Bootloader nur bei fehlender User-Application starten oder per Befehl aus der User-App zum Bootloader springen. Sobald ich dies im Linker umsetzen, läßt sich der uC nicht mehr über I2C ansprechen. Im Debug Modus scheint der aber zu laufen, zumindest wird mir angezeigt, dass der UC in der while(1) läuft (aber auch keine I2C Kommunikation möglich). Woran kann es liegen? Muss die Firmware unbedingt bei der Adresse 0x08000000 beginnen? Oder muss neben dem Linker noch was geändert werden? Hatte bis jetzt alle meine Bootloaderimplementierungen immer am Anfang vom Flash gehabt, was funktioniert hat. /* Entry Point */ ENTRY(Reset_Handler) /* Highest address of the user mode stack */ _estack = 0x20002000; /* end of RAM */ /* Generate a link error if heap and stack don't fit into RAM */ _Min_Heap_Size = 0x200; /* required amount of heap */ _Min_Stack_Size = 0x400; /* required amount of stack */ /* Specify the memory areas */ MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 8K FLASH (rx) : ORIGIN = 0x08006C00, LENGTH = 5K }
Moin, die Firmware muss bei 08000000 beginnen, dort erwartet der Controller die Reset/Interrupt-Vektoren. Man muss es umgekehrt machen: Bootloader ab 08000000 und die Applikation dahinter. Die Interrupt-Vektoren kann man nach dem Start umbiegen.
Wenn Du Interrupts benutzt, muss auch der Offset der Vector Tabelle angegeben werden.
Die Vektortabelle (zumindest initialer SP und Reset-Vektor) muss an Adresse 0x0 beginnen! In Abhängigkeit vom Boot-Modus wird ab Adresse 0x0 das RAM, System Mem. oder eben das Flash eingeblendet. Bei Booten vom Flash muss die Vektortabelle zunächst also bei Adresse 0x08000000 beginnen.
pegel schrieb: > Wenn Du Interrupts benutzt, muss auch der Offset der Vector > Tabelle > angegeben werden. Ja schon, I2C Slave benutzt Interrupts. Danke für den Hinweis, habe es in der "system_stm32l0xx.c" geändert auf: #define VECT_TAB_OFFSET 0x6C00 /* Specify the memory areas */ MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 8K FLASH (rx) : ORIGIN = 0x08006C00, LENGTH = 5K } Die Änderung wird im Map File auch angezeigt, leider noch ohne Erfolg. Der I2C Slave antwortet noch nicht.
:
Bearbeitet durch User
Für mich klingt das so, als wenn am Linker vom Bootloader irgendwas geändert hast. Du musst aber vor allem am Linker der Applikation was ändern... (Du darfst dem Bootloader linker ruhig mitteilen, dass er nur ein paar kb zur Verfügung hat...)
https://stackoverflow.com/questions/56896375/how-can-i-change-the-start-address-on-flash Die erste Antwort sollte passen, um nicht bei 0x08000000 starten zu müssen.
Mathias M. schrieb: > Für mich klingt das so, als wenn am Linker vom Bootloader irgendwas > geändert hast. Du musst aber vor allem am Linker der Applikation was > ändern... Ich habe noch keine User-Application, sondern vorerst nur den Bootloader. Den möchte ich hinten im Flash haben. Später muss es möglich sein als der App zum BL zu springen. BL muss aber auch starten, falls keine App vorhanden ist. Wenn der Reset Vector auf der Addr. 0 erwartet wird ok, aber in der Initphase des uCs VTOR Register zu ändern scheint auch nicht zu funktionieren. I2C läuft immer noch nicht. SCB->VTOR = (FLASH_BASE | 0x6C00);
:
Bearbeitet durch User
A. F. schrieb: > Den möchte ich hinten im Flash haben. Wie kommst Du da hin, wenn der L0 die Wahl der Boot Adresse nicht anbietet? Bleibt eigentlich wirklich nur den BL an den Flash Anfang zu setzen.
pegel schrieb: > Wie kommst Du da hin, wenn der L0 die Wahl der Boot Adresse nicht > anbietet? A. F. schrieb: > Muss die Firmware unbedingt bei der Adresse > 0x08000000 beginnen? Ds ist ja die eigentliche Frage, ob es überhaupt möglich ist.
Wenn Du die Versorgungsspannung einschaltest, bleibt dir nur von Flash ab 0x08000000 oder falls vorhanden, vom Internen BL zu starten.
pegel schrieb: > Wenn Du die Versorgungsspannung einschaltest, bleibt dir nur von > Flash > ab 0x08000000 oder falls vorhanden, vom Internen BL zu starten. Und das kann man beim STM32 nicht umgehen? Schade... Das heißt die User-App sollte für die Debugging-Zwecke auch bei 0x08000000 starten, weil sonst die Interrupts nicht laufen werden?
Für das Debuging ist das egal. Da kann deine "User-App" auch im RAM liegen.
pegel schrieb: > Für das Debuging ist das egal. > Da kann deine "User-App" auch im RAM liegen. Ok, vielen Dank euch allen. PS: dann funktionieren komischerweise die Interrupts nicht, wenn ich den Bootloader auf einer Adresse mit dem Offset starte.
:
Bearbeitet durch User
A. F. schrieb: > FLASH (rx) : ORIGIN = 0x08006C00, LENGTH = 5K Wie ist denn die letzte Flash Adresse? Welcher F0 ist es genau?
Du kannst auch alles selber testen. Leg doch mal ein Blinky auf verschiedene Positionen im Flash und im RAM. Damit kannst Du I2C Fehler ausschließen.
Ich habe eben mit HAL ein Blinky auf 0x08006C00 (Größe 5k) gelegt und ein Offset mit: #define VECT_TAB_OFFSET 0x00006C00U angegeben. Damit gibt es keine Probleme.
pegel schrieb: > Ich habe eben mit HAL ein Blinky auf 0x08006C00 (Größe 5k) gelegt und > ein Offset mit: > #define VECT_TAB_OFFSET 0x00006C00U > angegeben. > > Damit gibt es keine Probleme. Ich habe einen STM32L031 mit 32K, mein BL ist 4k groß. Beim Debuggen scheint die FW zu laufen, wenn ich auf den I2C Slave zugreife, ändern sich auch die SFRs für I2C, aber es erfolgt kein Sprung in die ISR. Wenn ich die FW auf 0x08000000 lege, läuft alles...
A. F. schrieb: > Wenn ich die FW auf 0x08000000 lege, läuft alles... Das hatte ich leider vorhin schon verstanden. Jetzt habe ich den Flash gelöscht, ein neues Projekt angelegt und nun ist es bei mir auch so! Selbst wenn ich schöne runde Werte nehme, läuft das Debug in einen Fehler. Den Start von Adresse 0x08002000 hatte ich in früheren Projekten öfter verwendet. Ist aber schon ein paar Updates her. Jetzt kriege ich mein Blinky da nicht hin. Im Moment bin ich überfragt. Vielleicht kann noch einmal jemand anders testen?
Der STM32L031 hat nach AN2606 einen BL über USART2 und SPI1. Leider keinen über I2C.
pegel schrieb: > Selbst wenn ich schöne runde Werte nehme, läuft das Debug in einen > Fehler. Aktuell funktioniert es wieder. Ich verstehe das nicht mehr. Reicht erst mal für heute.
pegel schrieb: > Ich fürchte, es liegt an meinem BluePill in Kombi mit dem CubeProg. Fake oder Original?
pegel schrieb: > Ich fürchte, es liegt an meinem BluePill in Kombi mit dem CubeProg. Bei mir laufen die Interrupts, wenn ich die gleiche FW zuvor auf Addr. 0 starte und danach mit dem Offset (ohne full chip errase). Ich vermute dass der uC immer auf Adresse 0 Startet... Der einzige Weg ist wohl entweder den Bootloader tatsächlich am Anfang vom Flash zu haben, oder eine mini App die danach zum Bootloader oder der User App springt.
A. F. schrieb: > den Bootloader tatsächlich am Anfang Würde ich auch machen. Das funktioniert immer, auch wenn deine App den Sprung nicht schafft.
pegel schrieb: > A. F. schrieb: >> den Bootloader tatsächlich am Anfang > > Würde ich auch machen. Das funktioniert immer, auch wenn deine App den > Sprung nicht schafft. Bin leider noch kein Stück weiter gekommen. Sobald ich das Hauptprogramm auf einer anderen Flashadresse im Debug-Modus laufen lassen, funktionieren die Interrupts nicht. Das Programm bleibt in der delay Funktion hängen, weil die auf SysTickCouner aufsetzt.... Vielleicht weiß es jemand, was ich evtl. übersehe?
Jetzt läuft..... Falls jemand noch die Probleme bekommen sollte: VECT_TAB_OFFSET muss App Flash Adresse sein +4...
Ich hatte beim Debuggen mal stundenlang einen verstecken Fehler gesucht der plötzlich beim Durchsteppen auftrat obwohl die gleiche Stelle wenige Minuten vorher noch richtig funktionierte. Letztendlich war des Rätsels Lösung, dass ich den µC einmal kurz Stromlos machen musste. Was ich komisch finde, ich dachte bisher immer, dass der Reset Taster alles zurücksetzt.
Beim M0 die Vectortable ins RAM copieren und Remap durchführen: #ifdef BOOLOADER_START uint32_t *VectorTable = (uint32_t *)0x20000000; uint32_t i = 0; for(i = 0; i < 48; i++) VectorTable[i] = *(__IO uint32_t*)(APPLICATION_ADDRESS + (i<<2)); // Enable the SYSCFG peripheral clock LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SYSCFG); // Remap SRAM at 0x00000000 LL_SYSCFG_SetRemapMemory(LL_SYSCFG_REMAP_SRAM); #endif
A. F. schrieb: > Bei mir laufen die Interrupts, wenn ich die gleiche FW zuvor auf Addr. 0 > starte und danach mit dem Offset (ohne full chip errase). Bei mir auch. Habe mein CN BP wohl zu Unrecht angezweifelt. A. F. schrieb: > Bin leider noch kein Stück weiter gekommen. Sobald ich das Hauptprogramm > auf einer anderen Flashadresse im Debug-Modus laufen lassen, > funktionieren die Interrupts nicht. Ich vermute ganz stark, dass das Problem in der neu dazu gekommenen Datei:
1 | * Debug.launch |
liegt. Die Zeile:
1 | <stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.pcRegister" value=""/> |
hat bei mir schon mal neben value="" auch value="0x08008004" automatisch enthalten. Vielleicht fehlt in dieser Datei noch die Verwaltung des Stack Pointers o.ä.?
A. F. schrieb: > Jetzt läuft..... > Falls jemand noch die Probleme bekommen sollte: > > VECT_TAB_OFFSET muss App Flash Adresse sein +4... Beim Cortex-M muss die Tabelle immer auf einer durch 128 teilbaren Adresse beginnen (bei größeren CPUs auch 256, 512,...). So ein offset ist doch Programmierer-Verarschung vom Feinsten. Sagt mal, welche IDE das ist, damit die niemand versehentlich installiert.
Ich habe jetzt für mich die Lösung gefunden. Ich flashe auf die gewünschte Adresse (vielfaches von 0x200). Z.B.: 0x08008000 Setze Offset der Vector Tabelle. passend dazu: 0x8000 Kopiere die Inhalte von 0x08008000-0x08008007 nach 0x08000000-0x08000007, also an den leeren Flash Anfang. So lange ich die Größe der Vector Tabelle oder die Stack Obergrenze nicht ändere bleiben diese Werte gültig. Falls jemand in der Lage ist, das Kopieren der 8Byte im Debug Startup als Befehle oder Script zu schreiben, nur her damit. Damit würde es für alle funktionieren, ohne das man darüber nachdenken müsste.
pegel schrieb: > Wie kommst Du da hin, wenn der L0 die Wahl der Boot Adresse nicht > anbietet? > > Bleibt eigentlich wirklich nur den BL an den Flash Anfang zu setzen. Das Problem ist mit meiner aktuellen Kopiermethode auch gelöst. Dann wird kein Bootloader benötigt und er springt auch beim Einschalten zum Reset_Handler an der richtigen Position. Damit läuft das Programm, egal wo es liegt (0x200 Schritte).
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.