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?
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))(); } }
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 | }
|
danke aber leider passiert dort einfach nix. kennt jemand ein beispiel für ein stm32f2xx?
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 }
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
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...
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.
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));
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.