1

I'm using a standard code to flash an other program to flash memory of my stm32f4 board using keil uvision. I need to have both the codes on my board. But how can i shift my Program Counter from one location to another to execute both the programs as and when required.
Below is the piece of code i'm using but the PC is not jumping. I think there is a problem with Jump to Application

#include "usbh_core.h"
#include "usbh_usr.h"
#include "usbh_msc_core.h"
#include "flash_if.h"

USB_OTG_CORE_HANDLE          USB_OTG_Core;
USBH_HOST                    USB_Host;

pFunction Jump_To_Application;
uint32_t JumpAddress;


int main(void)
{

BSP_Init();


FLASH_If_FlashUnlock();



if (STM_EVAL_PBGetState(BUTTON_USER) == Bit_RESET)
{
/* Check Vector Table: Test if user code is programmed starting from address 
   "APPLICATION_ADDRESS" */
 if (((*(__IO uint32_t*)APPLICATION_ADDRESS) & 0x2FFE0000 ) == 0x20000000)
{
  /* Jump to user application */
  JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS + 4);
  Jump_To_Application = (pFunction) JumpAddress;
  /* Initialize user application's Stack Pointer */
 __set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS);
         __set_PSP(*(__IO uint32_t*) APPLICATION_ADDRESS);

  Jump_To_Application();
}
}

  /* Init Host Library */
 USBH_Init(&USB_OTG_Core, USB_OTG_FS_CORE_ID, &USB_Host, &USBH_MSC_cb, &USR_Callbacks);

while (1)
 {
   /* Host Task handler */
    USBH_Process(&USB_OTG_Core, &USB_Host);
 }
}


 #ifdef USE_FULL_ASSERT
    void assert_failed(uint8_t* file, uint32_t line)
   {

    /* Infinite loop */
    while (1)
     {}
    }
     #endif
ABHISHEK N
  • 11
  • 2
  • It's usual to communicate via interrupt vectors. Many controllers alllow temporary vector table mapping to RAM to facilitate boot/flash loaders. – ThingyWotsit Mar 28 '17 at 18:22
  • Possible duplicate of http://stackoverflow.com/questions/26891432/jump-to-bootloader-in-stm32-through-appliction-i-e-using-boot-0-and-boot-1-pins – B. Wolf Mar 29 '17 at 03:03

1 Answers1

1
.global BRANCHTO
BRANCHTO:
   bx r0

EDIT

A few seconds worth of googling found function pointer basics (at StackOverflow no less)

void (*funadd) ( void );
void fun ( void )
{
    funadd=(void *)0x12345678;
    (*funadd)();
}

00000000 <fun>:
   0:   e59f2008    ldr r2, [pc, #8]    ; 10 <fun+0x10>
   4:   e59f1008    ldr r1, [pc, #8]    ; 14 <fun+0x14>
   8:   e5821000    str r1, [r2]
   c:   e12fff11    bx  r1
  10:   00000000    andeq   r0, r0, r0
  14:   12345678    eorsne  r5, r4, #120, 12    ; 0x7800000

which as my assembly function showed does the same thing (basically a tail optimization)

But if you want to see it setup a return address then you have to force that

unsigned int (*funadd) ( void );
unsigned int fun ( void )
{
    funadd=(unsigned int *)0x12345678;
    return((*funadd)()+1);
}

00000000 <fun>:
   0:   e59f201c    ldr r2, [pc, #28]   ; 24 <fun+0x24>
   4:   e59f101c    ldr r1, [pc, #28]   ; 28 <fun+0x28>
   8:   e92d4010    push    {r4, lr}
   c:   e5821000    str r1, [r2]
  10:   e1a0e00f    mov lr, pc
  14:   e12fff11    bx  r1
  18:   e8bd4010    pop {r4, lr}
  1c:   e2800001    add r0, r0, #1
  20:   e12fff1e    bx  lr
  24:   00000000    andeq   r0, r0, r0
  28:   12345678    eorsne  r5, r4, #120, 12    ; 0x7800000

EDIT2:

void BRANCHTO ( unsigned int );
void fun ( void )
{
    BRANCHTO(0x12345678);
}

00000000 <fun>:
   0:   e92d4010    push    {r4, lr}
   4:   e59f0008    ldr r0, [pc, #8]    ; 14 <fun+0x14>
   8:   ebfffffe    bl  0 <BRANCHTO>
   c:   e8bd4010    pop {r4, lr}
  10:   e12fff1e    bx  lr
  14:   12345678    eorsne  r5, r4, #120, 12    ; 0x7800000

LR is handled by the bl to BRANCHTO, branchto is just a tail optimization to pass that only would be a waste to push lr there and branch link then return then pop then return.

Could implement the branch as inline assembly, but inline assembly is very ugly in general, not as portable, just a mess, real assembly is far superior, and a somet toolchains to allow you to feed it directly to the compiler if it is a case of you dont know how to call the assembler. I almost never run Windows so dont have Kiel installed as much as I might like to (they used to include a reduced RVCT compiler that would be fun to play with).

old_timer
  • 69,149
  • 8
  • 89
  • 168
  • 2
    While this code snippet may solve the question, [including an explanation](http://meta.stackexchange.com/questions/114762/explaining-entirely-‌​code-based-answers) really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. – Rosário Pereira Fernandes Mar 28 '17 at 21:24
  • Whilst this will work, the question is for C, and using a function pointer rather than assembler. The behavior will be slightly different too, calling a function pointer will create a branch and link, whereas your version doesn't update `LR`. – Colin Mar 29 '17 at 07:38
  • When you call BRANCHTO from C it will setup LR for a return, there is no problem there. C compiles to assembly language then is assembled into an object, the cleanest way to get exactly what you want is to skip the step and go straight to assembler. To do this in c you make a dummy void function and change its address then call it. – old_timer Mar 29 '17 at 14:44