STM32L0 startet nicht

OP Persönliche Seite #6139674
Lesenswert?

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
}
Gast #6139689
Lesenswert?

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.
Gast #6139696
Lesenswert?

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.
OP Persönliche Seite #6139720
Lesenswert?

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.
Angehängte Dateien:
OP Persönliche Seite #6139768
Lesenswert?

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);
OP Persönliche Seite #6139977
Lesenswert?

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...
Gast #6140085
Lesenswert?

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?
OP Persönliche Seite #6140182
Lesenswert?

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.
OP Persönliche Seite #6141043
Lesenswert?

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?
Gast #6141298
Lesenswert?

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.
#6143160
Lesenswert?

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
Gast #6143182
Lesenswert?

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.ä.?
#6143195
Lesenswert?

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.
Gast #6143205
Lesenswert?

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.
Gast #6143244
Lesenswert?

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).

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren