cancel
Showing results for 
Search instead for 
Did you mean: 

Bootloader - jump to APPLICATION_ADDRESS

paul2
Senior
Posted on October 30, 2015 at 14:22

Hi,

I'm having some issue loading my application from the APPLICATION_ADDRESS -Using a STM32F4 Discovery board -As bootloader application I'm using the STM32F4 example

http://www.st.com/web/en/catalog/tools/PF257904

-I'm using the bootloader firmware with default APPLICATION_ADDRESS

#define APPLICATION_ADDRESS (uint32_t)0x08008000

-When I'm loading the STSW-STM32068 .bin example on my USB-stick, the demo gets loaded and runs like it should. so far so good.. -Next step is to create a bin file of my own application. -I used the following settings for my application:

mem.ld file (.map file is updated accordingly):
FLASH (rx) : ORIGIN = 0x08008000, LENGTH = 1024K
system_stm32f4xx.c file:
#define VECT_TAB_OFFSET 0x8000 /*!< Vector Table base offset field.

-Building the .bin file and rename it ''image.bin'' as needed by the bootloader firmware -According to the LED's the .bin is loaded to the Flash memory correctly. Also checked with a debugger (memory is filled from 0x08008000). -When I press the USER button the bootloader starts all over again, loading the .bin file from the USB-stick. I would expect that it will jump the loaded application @ 0x08008000 Do I miss something? Why is the bootloader not jumping to the APPLICATION_ADDRESS?
11 REPLIES 11
Posted on October 30, 2015 at 16:03

No idea.

Can you use a debugger? Step through the transition code to understand why it doesn't work.

The memory will no longer be 1024K, but rather 32K less. Make sure you don't have a bogus stack address. Consider 0x2001FFFC

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
paul2
Senior
Posted on October 30, 2015 at 17:52

Hi,

yes, I have a debugger. Make sure you don't have a bogus stack address. Consider 0x2001FFFC What do you exactly mean with a bogus stack address? According to AN3990 the bootloader firmware checks if the user button is pressed after startup, and also checks if there a user vector table available or not. When not; the firmware upgrade application is executed. That's exactly what's happening.

/* Test if User button on the Discovery kit is pressed */
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);
Jump_To_Application();
}
}

What's the best way to check if the user vector table is available or not?
Posted on October 30, 2015 at 19:00

One that fails the primary test before trying to jump to the application image?

Look at the file in a viewer (file manager, hex editor, etc), decode the bytes at the front of the image into the 32-bit words that compose the vector table.

Look at the .MAP files

Look at a disassembly output.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
paul2
Senior
Posted on October 30, 2015 at 21:03

One that fails the primary test before trying to jump to the application image?

Yes, that specific test I added some code to check the vector table:

/* Check Vector Table: Test if user code is programmed starting from address 
''APPLICATION_ADDRESS'' */
StartAddress = ((*(__IO uint32_t*)APPLICATION_ADDRESS) & 0x2FFE0000 );
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);
Jump_To_Application();
}
}

When I load the image that comes with the example: StartAddress = 0x20000000 -> check is valid When I load my own application image: StartAddress = 0x20020000 -> check is invalid So it seems to be related to my vector table. Any idea what needs to be changed? Just checked the .map file:

0x0000000020020000 __stack = (ORIGIN (RAM) + 0x20000)
0x0000000020020000 _estack = __stack
0x0000000000000400 __Main_Stack_Size = 0x400

Could ''ORIGIN (RAM) + 0x20000'' cause the issue I have?
Posted on October 30, 2015 at 22:03

__stack = (ORIGIN (RAM) + 0x1FFFC)

While technically workable 0x20020000 fails the test, the CPU pre-decrements the SP when it pushes a value. You could change the test.

/public/STe2ecommunities/mcu/Lists/STM32Java/Flat.aspx?RootFolder=https://my.st.com/public/STe2ecommunities/mcu/Lists/STM32Java/Bootloader.%20Load%20program%20with%20stack%20on%20CCM&FolderCTID=0x01200200770978C69A1141439FE559EB459D758000F9A0E3A95BA69146A17C2E80209ADC21&currentviews=47

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
paul2
Senior
Posted on October 31, 2015 at 07:00

Hi,

I made some changes based on the suggested topic;

/* Check Vector Table: Test if user code is programmed starting from address 
''APPLICATION_ADDRESS'' */
initsp = ((*(__IO uint32_t*)APPLICATION_ADDRESS) & 0x2FFE0000 );
if ( ((initsp & 3) == 0) && ((initsp > 0x20000000) && (initsp <= 0x20020000))) // in regular RAM region 128KB
{ 
/* 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);
Jump_To_Application();
}

Now it works, and the application is started like it should. Thanks for your support.
paul2
Senior
Posted on November 09, 2015 at 21:57

Hi,

now I'm facing a new issue.

The application is successfully loaded by the bootloader. After a reset the application starts correctly, throwing out some debug characters via UART. After a few characters the application stops. The debugger doesn't show anything strange.

When I load the application on a Discovery board without bootloader (changed linker settings and APPLICATION_ADDRESS), the application doesn't stop and works like it should.

Can it be related to RAM/heap? Any idea?

 

Posted on November 09, 2015 at 22:19

There should be no hold-over between the loader/app for RAM usage. I'd look at the clocks and what's going on with SystemInit().

And if you use a debugger, where is the app code ending up? It's real hard to debug things with random symptoms.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
paul2
Senior
Posted on November 10, 2015 at 22:04

Hi,

according to the debugger, the application holds at a _write() function within retarget.c (printing some startup information). The application always stops after printing the same amount of startup characters. So it doesn’t seems to be random.

How can clocks/SystemInit cause this kind of issue? Or what could be wrong?

Thanks.