Forum: Mikrocontroller und Digitale Elektronik stm32 bootloader problem


von ben (Gast)


Lesenswert?

Hallo,

ich habe ein Problem meinen Bootloader für einen STM32F070 zum laufen zu 
bekommen. Der Bootloader soll das Hauptprogramm über eine SD Karte (über 
SPI) laden, in den Flash schreiben und dann in das Hauptprogramm 
springen. Das Schreiben in den Flash funktioniert.

Jedoch beobachte ich folgendes Verhalten beim Sprung in das 
Hauptprogramm:

Wenn auf SPI Schnittstelle zugegriffen wird:
- Beim ersten Start läuft das Hauptprogramm nach dem Sprung nicht
- Führe ich dann über die Debug Schnittstelle ein Software Reset durch, 
läuft das Hauptprogramm
- Wird nicht auf die SPI Schnittstelle zugegriffen funktioniert der 
Sprung ebenfalls.

Hier die Sprungroutine:
1
HAL_FLASH_Lock();  
2
3
    void (*pProgResetHandler)(void);
4
5
  /* enable system configuration peripheral, which is needed to remap the RAM later on */
6
  __HAL_RCC_SYSCFG_CLK_ENABLE();
7
8
  /* copy user program vector's to RAM */
9
  CpuMemCopy(CPU_USER_PROGRAM_RAM_BASEADDR, CPU_USER_PROGRAM_VECTABLE_OFFSET,
10
             CPU_USER_PROGRAM_VECTABLE_SIZE);
11
  /* remap RAM so that it also appears at address 0x00000000. this way the user program's
12
   * vector table in RAM is used instead of the bootloader's vector table in flash.
13
   */
14
  LL_SYSCFG_SetRemapMemory(LL_SYSCFG_REMAP_SRAM);
15
16
  /* set the address where the bootloader needs to jump to. this is the address of
17
   * the 2nd entry in the user program's vector table. this address points to the
18
   * user program's reset handler.
19
   */
20
  pProgResetHandler = (void(*)(void))(*((uint32_t *)CPU_USER_PROGRAM_STARTADDR_PTR));
21
22
  /* start the user program by activating its reset interrupt service routine */
23
24
  pProgResetHandler();

Meine Vermutung ist, dass durch das SPI irgendwelche (Interrupt) Flags 
gesetzt werden, die dann das Hauptprogramm zum Absturz bringen.
Jedoch kann ich mit dem Debugger nur bis zum Sprung debuggen, danach 
erhalte ich keine Informationen mehr.

Versucht habe ich noch das hier vor dem Sprung:

1
 // Deinit everything
2
    LL_SPI_ClearFlag_FRE(SPI_SD);
3
    SPI_SD->SR = 0;
4
    HAL_SPI_DeInit(&hspi1);
5
    HAL_DeInit();

Ändert aber nichts. Ich tappe im Dunkeln. Hat jemand eine Idee? Danke

von ben (Gast)


Lesenswert?

So nach Tagelangem hin und her läuft es jetzt.

Die Sprungroutine benötigte noch ein
1
__disable_irq();

Im Hauptprogramm müssen die Interrupts dann wieder eingeschaltet werden.
1
__enable_irq();

Kann jemand dieses Verhalten erklären?

von eagle user (Gast)


Lesenswert?

Weisst du denn nicht, welche Interrupts im Bootloader eingeschaltet 
werden? Und weisst du, wann und wo das VTOR Register geschrieben wird? 
Das sollte zwar auch atomar machbar sein, aber weiss man's?

Und überhaupt, warum schaltet der Bootloader überhaupt irgendwelche 
Interrupts ein? Und warum mappt man das RAM auf 0 und kopiert da was 
rein?  Nach dem Reset ist das doch alles wieder weg? Der Bootloader und 
das Hauptprogramm stehen doch beide im Flash, da kommt das RAM doch 
garnicht ins Spiel? Sind Bootloader und Hauptprogramm zwei ganz 
getrennte Programme oder werden die Teile zu einem zusammen gelinkt?

Fragen über Fragen, aber ich fange selbst gerade mit meinem Bootloader 
an...

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
Noch kein Account? Hier anmelden.