stm32 bootloader problem

Gast #5006322
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
Gast #5006765
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?
Gast #5006959
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...

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