Forum: Mikrocontroller und Digitale Elektronik stm32 - eigener Bootloader


von peter m. (bastler788)


Lesenswert?

hallo,

ich möchte einen eigenen bootloader schreiben. diesen schreibe ich ganz 
normal in den stm32f2xx ab adresse 0x08000000.

ab adresse 0x08003000 speicher ich ein weiteres programm in dem ich die 
Hex File eines zuvor getesteten programms ab dieser adresse im flash 
hinterlegt.

anschließend will ich mit dieser funktion das weitere Programm starten:

 __asm void jump_to_application(void)
{
    ; program stack pointer of application
  LDR     R0, =0x08003000
        LDR     SP, [R0]

    ; extract entry point into application
  LDR     R0, =0x08003004

    ; jump
    LDR     PC, [R0]
}

aber das programm startet nicht. im debug modus sehe ich das der 
prozessor immer in der funktion herumspringt.

kann mir jemand helfen?

von Uwe B. (Firma: TU Darmstadt) (uwebonnes)


Lesenswert?

Fuer die Blackmagic debug probe verwenden wir:

void dfu_jump_app_if_valid(void)
{
        /* Boot the application if it's valid */
        if((*(volatile u32*)APP_ADDRESS & 0x2FFE0000) == 0x20000000) {
                /* Set vector table base address */
                SCB_VTOR = APP_ADDRESS & 0x1FFFFF; /* Max 2 MByte 
Flash*/
                /* Initialise master stack pointer */
                asm volatile ("msr msp, %0"::"g"
                                (*(volatile u32*)APP_ADDRESS));
                /* Jump to application */
                (*(void(**)())(APP_ADDRESS + 4))();
        }
}

von peter m. (bastler788)


Lesenswert?

das hilft mir leider nicht weiter

von John-eric K. (mockup)


Lesenswert?

Lade dir die USB-Lib 
http://www.mikrocontroller.net/articles/STM32_USB-FS-Device_Lib herunter 
und schaue dort im DFU Beispiel hinein.

Hier ein Auszug für den Sprung
1
  if (((*(__IO uint32_t*)0x08003000) & 0x2FFE0000 ) == 0x20000000)
2
  { /* Jump to user application */
3
  
4
    JumpAddress = *(__IO uint32_t*) (0x08003000 + 4);
5
    Jump_To_Application = (pFunction) JumpAddress;
6
    /* Initialize user application's Stack Pointer */
7
    __set_MSP(*(__IO uint32_t*) 0x08003000);
8
    Jump_To_Application();
9
  }
10
11
  // starte Bootloader wenn Firmware nicht vorhanden

Mit Assembler kann ich aber nicht dienen.

Oder zum Teil, das in den Klammern sieht doch nach Assembler aus um den 
Stackpointer zu initialisieren.
1
/** \brief  Set Main Stack Pointer
2
3
    This function assigns the given value to the Main Stack Pointer (MSP).
4
5
    \param [in]    topOfMainStack  Main Stack Pointer value to set
6
 */
7
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
8
{
9
  __ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) );
10
}

von peter m. (bastler788)


Lesenswert?

danke

aber leider passiert dort einfach nix. kennt jemand ein beispiel für ein 
stm32f2xx?

von red cruiser (Gast)


Lesenswert?

Geht bei mit Keil und STM32F103 so

addr := IROM1


void  StartApplication( Tu32 addr)
{
  __set_MSP( *(Tu32 *)addr);     // set application stackpointer
  __DSB();

  addr = *(Tu32 *)(addr + 4);   // get the reset vector

  ((void(*)(void))addr)();    // jump to application
}

von peter m. (bastler788)


Lesenswert?

nein funbktioniert leider auch nicht

von peter m. (bastler788)


Lesenswert?

also der interne bootloader funktioniert, aber der schreibt die hex file 
ja auch an die startadresse 0x08000000, aber das kann mein bootloader ja 
nicht, da dieser an der adresse ist. und der sprung zu einer anderen 
adresse scheint nicht zu funktionieren

von Uwe B. (Firma: TU Darmstadt) (uwebonnes)


Lesenswert?

Also bei mir funktioniert der interne Bootloader, und laedt das Programm 
an 0x0800000 oder sonstwo im Flash und springt dann an den 
Programmstart. Bei dfu-util http://dfu-util.gnumonks.org/ ist dazu aber 
im Moment noch ein patch noetig...

von peter m. (bastler788)


Lesenswert?

Uwe Bonnes schrieb:
> Also bei mir funktioniert der interne Bootloader, und laedt das Programm
> an 0x0800000 oder sonstwo im Flash und springt dann an den
> Programmstart. Bei dfu-util http://dfu-util.gnumonks.org/ ist dazu aber
> im Moment noch ein patch noetig...

der interne funktioniert bei mir ja auch, aber ich möchte einen eigenen 
schreiben und der funktioniert nicht. die hex file steht ab adresse 
0x08004000 und ich spring auch dort hin, aber ab dann passiert nix mehr.

von Christian (Gast)


Lesenswert?

Du solltest vor dem Sprung noch die Adresse der IRQ Vector Tabelle 
ändern. Das war zumindest bei mir das Problem.

Mit der ST Lib geht das z.B. so:
NVIC_SetVectorTable(NVIC_VectTab_FLASH, (0x08004000));

von peter m. (bastler788)


Lesenswert?

Christian schrieb:
> Du solltest vor dem Sprung noch die Adresse der IRQ Vector Tabelle
> ändern. Das war zumindest bei mir das Problem.
>
> Mit der ST Lib geht das z.B. so:
> NVIC_SetVectorTable(NVIC_VectTab_FLASH, (0x08004000));

danke, aber des hatte ich bereits schon drin. also ich schreib die hex 
ins flash ab adresse 0x08004000, ruf die funktion Flash_Lock() auf, 
änder die Adresse der IRQ Vector Tabelle und ruf dann die funktion auf, 
in der ich springen möchte

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.