cancel
Showing results for 
Search instead for 
Did you mean: 

Self made bootloader

tiago
Associate II
Posted on May 14, 2010 at 18:52

Self made bootloader

#it''s-deja-vu-all-over-again #bootloader #bootloader
10 REPLIES 10
chikos332
Associate II
Posted on May 17, 2011 at 13:50

Hi,

This subject has been discussed in several topics before, have a look on history...

But to make it easy for you, try this code from DFU demo provided by ST:

typedef  void (*pFunction)(void);

pFunction Jump_To_Application;

uint32_t JumpAddress;

/* Test if user code is programmed starting from address ApplicationAddress*/

    if (((*(__IO uint32_t*)ApplicationAddress) & 0x2FFE0000 ) == 0x20000000)

    { /* Jump to user application */

      JumpAddress = *(__IO uint32_t*) (ApplicationAddress + 4);

      Jump_To_Application = (pFunction) JumpAddress;

      /* Initialize user application's Stack Pointer */

      __set_MSP(*(__IO uint32_t*) ApplicationAddress);

      Jump_To_Application();

    }

///for you, ApplicationAddress should be defined as follows:

#define ApplicationAddress     0x08006400

ONE IMPORTANT NOTE:

 In your image code (that you will load into flash @ 0x08006400), Don't forget to set the vector table to the address 0x08006400.

You can use this function in your main, after clock configuration:

  /* Set the Vector Table base location at 0x6400 */

  NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x6400); 

Is it the kind of information you're looking for ?  

For more details, please get the the IAP application note: AN2557 @  http://www.st.com/stonline/products/support/micro/files/an2557.zip and http://www.st.com/stonline/products/literature/an/13588.pdf. or the DFU demo if you want to use USB.

tiago
Associate II
Posted on May 17, 2011 at 13:50

Hi chikos, thanks for your response.

I'm sorry, I've forgot to mention that I had already searched and read many threads in the forum, even that you sent.

I can't see what is different from my code posted above from the code you sent me...

For me,

''JumpAddress = *(__IO uint32_t*) (ApplicationAddress + 4);

Jump_To_Application = (pFunction) JumpAddress;

Jump_To_Application();''

is the same that (correct me, if I'm wrong):

''

#define BASE_ADDR    0x08006400

void (*app)(void);

app = (void(*)(void))(BASE_ADDR+4);

app(); //I forgot this line in the firts post!

''

In fact, this works when I put directly the base address of my app's ''main()'' function, but don't work when I make BASE_ADDR equal to 0x08006400! This is the most obscure for me...

I think I should always use the base address that I set in my linker file (in this case 0x08006400) because the app's main function may have it's address changed as the code grows, right?

So, what is the correct way to do that? Or how to discover where is placed app's main() address?

Sorry if I'm not so clear, but its how I see this problem...

Ah! I don't know if it makes any difference but I'm using Extended Embedded C++ Compiler...

Thanks a lot!

Posted on May 17, 2011 at 13:50

The former is loading the address stored at 0x08006404, the latter is trying to execute code at 0x08006404.

Remember the front of the image is a vector table, NOT code.

The value stored at 0x08006404 is going to be ODD because it is THUMB code. In the case of IAR it should be the address for __program_start or __iar_program_start, which initializes the C run time environment (copies statics to RAM, and initialize other variable space to zero) BEFORE calling main()

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
chikos332
Associate II
Posted on May 17, 2011 at 13:50

Hi,

The point is : Normally, you don't need to load the address of main(), what you need is the address of the stack and the vector table.

I think that you should look at your image code rather than your booting code. May be the compiler you are using is placing code in some weired method... I advise you to first to make a try with some other images built with other compilers (just some simple examples).

Cheers.

tiago
Associate II
Posted on May 17, 2011 at 13:50

Now I can see what was wrong...

I was forgetting about vector table and C initialization code and was trying to execute code from an invalid address! As I'm not experient in editing linker files, I was looking for an error in that... But now, everything works great!

Just another question: why do I need to set vector table using ''NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x6400);''? if I set linker file to 0x08006400 why it doesn't generate code to automaticaly allocate vector table to that? This is not a problem, just want to know more about!

I'm realy thankful for your help, chikos and clive!

Posted on May 17, 2011 at 13:50

NVIC_SetVectorTable() sets the hardware settings, and is not really the job of the compiler/linker.

The reason you can set the hardware is two fold. One, it permits the vector table to be moved and provide flexibility. You can also have more than one vector table, so different parts of you boot sequence can point to different tables. With the original ARM and 68K for example the vector tables are fixed, meaning the often needed to be fixed in ROM/FLASH. Second, the way the chip boots means the RAM/FLASH/ROM (as set by BOOT[0..1]) are mapped to address 0 (Zero) as well as there normal addresses. As execution proceeds it is wise to set the address to the real location in memory.

Also having the vector table in RAM, even though you have booted from FLASH, will permit you change some vectors after you have copied the table to RAM.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
microeval
Associate II
Posted on June 07, 2013 at 07:28

Hi Clive1

Where exactly the __iar_program_start() function definition for STM32L152 board in IAR IDE? After searching all example programs in IAR IDE i couldn't find out the definition for __iar_program_start() function.

Thanks,

Ram. 

Posted on June 07, 2013 at 13:45

It should be part of the IAR run-time library code, along with ?main, it initializes the BSS section in RAM, ie copies and clears static spaces. Then it calls your main() routine.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
eedsp
Associate
Posted on January 26, 2016 at 17:59

I have code attempting to use the Jump_to_application for a STM32F405 with the intention of performing BootLoad via USART1. The application fails to go bootload.

I believe I'm following AN3155 and AN2606 to the letter... 

Using ST Programmer in debug mode, I can enter into Jump_to_Application() and toggle HSEON = 1 and now micro in USART1 boot load mode.

 

I can also pulldown (w/ 220 ohm) one of the 8Mhz External Oscillator pins and power cycle  and now Jump_to_application() will go USART1 Boot Load Mode.

Any ideas?

I'm guessing that by disabling the external oscillator that I'm creating an unstable clock and the micro reboots using the internal Oscillator, which jives with EXT OSC must be disabled to use USART1 but why does Jump_to_Application clear the HSEON bit and why when I force SET the HSEON bit does the app place micro into USART boot load mode.