Forum: Mikrocontroller und Digitale Elektronik Verständnisfrage zum Bootloader Speicherbereich beim STM32 Connectivity Line


von Bülent C. (mirki)


Lesenswert?

Hallo zusammen,

laut AN2606 soll sich der Bootloader für ein STM32F1105/107 sich im 
Speicher bei 0x1FFFB000 befinden.
Wenn ich mir diesen aber, während eines Debugvorgangs anschaue, dann 
sehe ich, das ab dieser Adresse die ersten 5 WORD's mit nullen gefüllt 
sind.

Verwundert bin ich, weil ich dachte, das das erste WORD der "main stack 
pointer" und das vierte WORD der Systemmemory reset vector wäre.

Habe ich eine AN evtl. übersehen? Im RM konnte ich nichts gegenteiliges 
finden.


Hier ein Ausschnitt:
1
0x1FFFB000 : 0x1FFFB000 <Hex>
2
  Address   0 - 3     4 - 7     8 - B     C - F               
3
  1FFFB000  00000000  00000000  00000000  00000000          
4
  1FFFB010  00000000  CDE9FF1F  CDE9FF1F  00000000          
5
  1FFFB020  00000000  00000000  00000000  CDE9FF1F          
6
  1FFFB030  CDE9FF1F  00000000  CDE9FF1F  CDE9FF1F          
7
  1FFFB040  CDE9FF1F  CDE9FF1F  CDE9FF1F  CDE9FF1F          
8
  1FFFB050  CDE9FF1F  CDE9FF1F  CDE9FF1F  CDE9FF1F          
9
  1FFFB060  CDE9FF1F  CDE9FF1F  CDE9FF1F  CDE9FF1F          
10
  1FFFB070  CDE9FF1F  CDE9FF1F  CDE9FF1F  CDE9FF1F

Brauchen tue ich das, weil ich aus meiner Applikation heraus den 
Bootloader aufrufen möchte:
1
void StartBootLoader()
2
{
3
4
  SysMemBootJump=(void (*)) (*((u32 *) 0x1FFFB000)); // Adresse stimmt wohl nicht
5
6
  RCC_DeInit();
7
  SysTick->CTRL = 0;
8
  SysTick->LOAD = 0;
9
  SysTick->VAL = 0;
10
  __set_PRIMASK(1);
11
  __set_MSP(0x00000000); // // Adresse stimmt wohl nicht
12
  SysMemBootJump();
13
14
}

von Bernhard K. (bskeller)


Lesenswert?

abo

von Bülent C. (mirki)


Lesenswert?

Hat sich nun erledigt und es läuft...man muss nur richtig schauen und 
dann auch in die richtige Ausgabe :-)
1
void StartBootLoader()
2
{
3
4
5
  SysMemBootJump=(void (*)) (*((u32 *) 0x1FFFB004));
6
7
  RCC_DeInit();
8
  SysTick->CTRL = 0;
9
  SysTick->LOAD = 0;
10
  SysTick->VAL = 0;
11
  __set_PRIMASK(1);
12
  __set_MSP(0x20000FF0);
13
  SysMemBootJump();
14
15
16
}

So kann ich nun wunderbar der Bootloader von meiner eigenen Firmware aus 
aufrufen.

von Rene (Gast)


Lesenswert?

Bei mir funktioniert es nicht. Ich nutze einen stm32f407. Könntest Du 
mir bitte sagen welche Adressen ich da nehmen muss.

von Rene (Gast)


Lesenswert?

Hey Bülent bey, es ist sehr wichtig

von Uwe Bonnes (Gast)


Lesenswert?

Schon mal eine Blick in die ST AN2606 geworfen?

von Rene (Gast)


Lesenswert?

Uwe Bonnes schrieb:
> Schon mal eine Blick in die ST AN2606 geworfen?

Natürlich habe ich das, aber da stehen die Adressen die Bülent verwendet 
hat ja auch nicht drinne.
Wenn man hier Infos gibt, dann sollte man das auch richtig machen damit 
alle was davon haben. Das ist das Prinzip einer community

von Uwe Bonnes (Gast)


Lesenswert?

Neben den Adresses steht da auch:
 In addition to patterns described above, user can execute bootloader
 by performing a jump t system memory from user code. Before jumping
 to Bootloader user must:
·    Disable all peripheral clocks
·    Disable used PLL
·    Disable interrupts
·    Clear pending interrupts

von Rene (Gast)


Lesenswert?

Und wohin genau gehüpft werden soll steht da aber nicht

von holger (Gast)


Lesenswert?

>Wenn man hier Infos gibt, dann sollte man das auch richtig machen damit
>alle was davon haben. Das ist das Prinzip einer community

Sach ma, gehts noch?

von Lukas K. (carrotindustries)


Lesenswert?

Uwe Bonnes schrieb:
> Neben den Adresses steht da auch:
>  In addition to patterns described above, user can execute bootloader
>  by performing a jump t system memory from user code. Before jumping
>  to Bootloader user must:
> ·    Disable all peripheral clocks
> ·    Disable used PLL
> ·    Disable interrupts
> ·    Clear pending interrupts

Um das ganze sicher zu erschlagen, kann man auch einen Reset machen und 
dann im startup in den Bootloader springen:

Im startup macht man dann in etwa sowas:
1
Reset_Handler:  
2
 ldr        R0, =0x2001fff4
3
 ldr        R2, [R0]
4
 str        R0, [R0] 
5
 
6
 ldr        R1, =0x1BADB007
7
 cmp        R2, R1
8
 bne        MainAppStart
9
10
11
        ldr     r0, =0x1fff0000 //adresse von bootloader
12
        ldr             sp, [r0]
13
        ldr     r0, [r0, #4]
14
    bx      R0
15
16
17
MainAppStart:
18
ldr   sp, =_estack     /* set stack pointer */
19
....

Um in den dfu zu springen:
1
void dfu_start(void) {
2
        *((uint32_t *)0x2001fff4) = 0x1BADB007; //just above stack pointer
3
        NVIC_SystemReset();
4
        while(1)
5
                ;
6
}

Bleibt natürlich eine 1/4e9 Chance, dass bei zufälligem SRAM-Inhalt man 
direkt in den Bootloader fällt.

von Uwe Bonnes (Gast)


Lesenswert?

Falls der Reset ueber NVIC_SystemReset ausgeloest wurde, ist auch in 
RCC->CSR das Bit RCC_CSR_SFTRSTF gesetzt.

von eagle user (Gast)


Lesenswert?

Rene schrieb:
> Uwe Bonnes schrieb:
>> Schon mal eine Blick in die ST AN2606 geworfen?
>
> Natürlich habe ich das, aber da stehen die Adressen die Bülent verwendet
> hat ja auch nicht drinne.

Doch.
Sogar an zwei Stellen.

von Bülent C. (mirki)


Lesenswert?

Rene schrieb:
> Uwe Bonnes schrieb:
> Schon mal eine Blick in die ST AN2606 geworfen?
>
> Natürlich habe ich das, aber da stehen die Adressen die Bülent verwendet
> hat ja auch nicht drinne. Wenn man hier Infos gibt, dann sollte man das
> auch richtig machen damit alle was davon haben. Das ist das Prinzip
> einer community

Was soll der kack?
IIch habe doch alles geschrieben was hierzu notwendig ist. Wenn Du nicht 
lesen kannst ist das dein Problem

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.