2014-03-13 8:18 AM
Hi guys,
I've been working on a bootloader program which is loosely based around the FW_Upgrade demo for the STM32F4 discovery board. My Bootloader so far correctly finds a file on a USB stick and downloads it to flash in the right location(0x0800C000), but I'm having issues jumping to that location to run my downloaded program once I'm done putting it in flash. The demo from ST has the MCU reset after it has downloaded to flash and then jumps to the program. Is the reset necessary or can I just jump straight to the location in flash? Also, how do I actually do the jump. I'm using the code from st which looks like this, but it doesn't seem to work:/* 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 = (APPLICATION_ADDRESS + 4);
Jump_To_Application = (pFunction) JumpAddress;
/* Initialize user application's Stack Pointer */
__set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS);
Jump_To_Application();
}2014-03-13 8:36 AM
You should be able to jump to ANY code you want, remember that the Thumb code will be an ODD address.
The example you refer too expects a Vector Table, where the first entry is the new Stack Pointer, and the second points to the ResetHandler. If you are jumping to arbitrary code without the vector table, you can do that too, loading the code at X, and jumping to X+12014-03-13 9:05 AM
Thanks for the help Clive. Can't quite get my head around what I need to do though. Let's say I get rid of that code from the example that uses the vector table,and as you say, just jump to an arbitrary bit of code in flash, what would the code look like for doing that?
2014-03-13 9:25 AM
Posted on March 13, 2014 at 17:25
typedef int (*pFunction)(void);
void RamCode(void)
{
  static const uint16_t Code[] = { 0xF04F, 0x007B, 0x4770 }; // payload
  uint8_t Buffer[16]; // as big as required
  pFunction RunCode;
  memcpy(Buffer, Code, sizeof(Code)); // Copy code
  RunCode = (pFunction)&Buffer[1]; // +1 for Thumb code
  printf("%d\n",RunCode());
}  MOV R0, #123
  BX LR2014-03-13 10:45 AM
Hi
(I do not want to contradict clive1, since he has successfully helped so many.) '' My Bootloader so far correctly finds a file on a USB stick and downloads it to flash in the right location(0x0800C000)'' Is the vector table at 0x800c00? If so then the code snipet from ST should work, change the ''APPLICATION_ADDRESS2014-03-13 11:01 AM
Well you're likely to have to bring your own beer here, I'm trying to infer general methods which can be modified to suit.
typedef int (*pFunction)(void);
uint8_t *Buffer = (uint8_t *)0x0800C000;
RunCode = (pFunction)&Buffer[1]; // +1 for Thumb code
RunCode();startup.s (Keil, adjust syntax to taste)
..
IMPORT SystemInit
IMPORT __main
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
..
2014-03-14 3:30 AM
I'm not all that comfortable with assembler, so think I'm going to follow the vector table route you suggested Sung. So basically, you're saying I need to make sure my vector table is at location 0x0800C000. How do I do that? Is it a case of calling this?
NVIC_SetVectorTable(NVIC_VectTab_FLASH,0xC000);Or does it need to be defined in the code I'm downloading? Location 0x0800C000 is the base address of Flash Sector 3 so I'm guessing that isn't going to be a problem.2014-03-14 4:02 AM
Hi
''I'm not all that comfortable with assembler'' It has nothing to do with assembler. ''So basically, you're saying I need to make sure my vector table is at location 0x0800C000. How do I do that?'' Look at the map file that is (or can be) ouput during the build process. In my project it is called ''.isr_vector''. It is defined in the 'startup'.s file in my project. That is a good starting place to look for it. ''Or does it need to be defined in the code I'm downloading?'' Should already be done - or no interrupts will work! ''Location 0x0800C000 is the base address of Flash Sector 3 so I'm guessing that isn't going to be a problem.'' Sound OK but worth checking in the reference manual.2014-03-14 4:06 AM
Suggest you also review the USART IAP app note and code.
The vector table is normally reconfigured in SystemInit() within system_stm32f4xx.c, the code and the project need to define the base address the App code is going to reside at. The base address typically comes from the target configuration or scatter/linker script. The App is basically built as a stand-alone image, with it's own vector/interrupt table, and the Boot Loader transfers control via a mechanism like that shown in the first port. The vector table is stored in SCB->VTOR, you can check that, it should be the base 0x0800C000 when it leaves SystemInit()2014-03-14 6:56 AM
clive, are you saying that I need to into my app code and define the IROM1 start address as 0x0800C000 instead of 0x08000000?
