Skip to main content
paul2
Associate III
October 30, 2015
Question

Bootloader - jump to APPLICATION_ADDRESS

  • October 30, 2015
  • 11 replies
  • 4339 views
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?
    This topic has been closed for replies.

    11 replies

    Tesla DeLorean
    Guru
    October 30, 2015
    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 (See Profile) Up vote any posts that you find helpful, it shows what's working..
    paul2
    paul2Author
    Associate III
    October 30, 2015
    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?
    Tesla DeLorean
    Guru
    October 30, 2015
    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 (See Profile) Up vote any posts that you find helpful, it shows what's working..
    paul2
    paul2Author
    Associate III
    October 30, 2015
    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?
    Tesla DeLorean
    Guru
    October 30, 2015
    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 (See Profile) Up vote any posts that you find helpful, it shows what's working..
    paul2
    paul2Author
    Associate III
    October 31, 2015
    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
    paul2Author
    Associate III
    November 9, 2015
    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?

     

    Tesla DeLorean
    Guru
    November 9, 2015
    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 (See Profile) Up vote any posts that you find helpful, it shows what's working..
    paul2
    paul2Author
    Associate III
    November 10, 2015
    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.

    Tesla DeLorean
    Guru
    November 10, 2015
    Posted on November 10, 2015 at 22:18

    The thing is, I'm a savant, not a psychic, so I'm not going to try an imagine what you've created. If you want to show me what you've created it would be helpful in diagnosing the problem, rather than keep telling me symptoms for something I can't touch or see.

    Does the failure correlate with the size of the buffer you've allocated for your output device? Is it using a USART or SWV for output? Is the output from the buffer dependent on an IRQ firing? Is it firing?

    You said ''

    the application doesn't stop and works like it should

    '', I don't know what that means, you suggested RAM, I countered with clocks and stuff.

    Are you calling the other code in an IRQ Handler?

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..