1

I'm working on project on STM32L152RCT6, where i have to build a mechanism to self update the code from the newly gated file(HEX file). For that i have implemented such mechanism like boot loader where it checks for the new firmware if there it it has to cross verify and if found valid it has to store on "Application location".

I'm taking following steps.

  1. Boot loader address = 0x08000000
  2. Application address = 0x08008000
  3. Somewhere on specified location it has to check for new file through Boot loader program.
  4. If found valid it has to be copy all the HEX on location(as per the guide).
  5. Than running the application code through jump on that location.

Now problem comes from step 5, all the above steps I've done even storing of data has been done properly(verify in STM32 utility), but when i'm jump to the application code it won't work.

Is there i have to cross check or something i'm missing?

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Huzaifah
  • 60
  • 6

4 Answers4

0

Have you changed the application according to the new falsh position?

For example the Vector Table has to be set correctl via

SCB->VTOR = ...
theSealion
  • 1,082
  • 7
  • 13
  • Thanks for reply, Yes i did those things like setting up vector table and jump to the appropriate location. – Huzaifah Jul 23 '18 at 11:43
0

When your bootloader starts the app it has to configure everything back to the reset state as the application may relay on the default reset values. Espessially you need to:

  1. Return values of all hardware registers to its reset values
  2. Switch off all peripheral clocks (do not forget about the SysTick)
  3. Disable all enabled interrupts
  4. Return all clock domains to its reset values.
  5. Set the vector table address
  6. Load the stack pointer from the beginning of the APP vector table.
  7. Call the APP entry point.(vertor table start + 4)

Your app has to be compiled and linked using the custom linker script where the FLASH start point is 0x8008000

for example:

FLASH (rx) : ORIGIN = 0x8000000 + 32K, LENGTH = 512K - 32K

0___________
  • 60,014
  • 4
  • 34
  • 74
  • Thanks for the reply, "Switch off all peripheral clocks (do not forget about the SysTick)" I try to disable the SysTick, but once again it jumps to the main(Bootloader) program. – Huzaifah Jul 23 '18 at 11:46
  • I gave you the all steps. You need to study the documentation of the Cortex cores to understand how it works. You need also to know how to compile and link your app to placed at the particular start address. – 0___________ Jul 23 '18 at 12:11
0

Unlike other ARM controllers that directly jump to address 0 at reset, the Cortex-M series takes the start address from a vector table. If the program is loaded directly (without a bootloader), the vector table is at the start of the binary (loaded or mapped to address 0). First entry at offset 0 is the initial value of the stack pointer, second entry at address 4 is called the reset vector, it contains the address of the first instruction to be executed.

Programs loaded with a bootloader usually preserve this arrangement, and put the vector table at the start of the binary, 0x08008000 in your case. Then the reset vector would be at 0x08008004. But it's your application, you should check where did you put your vector table. Hint: look at the .map file generated by the linker to be sure. If it's indeed at 0x08008000, then you can transfer control to the application reset vector so:

void (*app)(void);                   // declare a pointer to a function
app = *(void (**)(void))0x08008004;  // see below
app();                               // invoke the function through the pointer

The complicated cast in the second line converts the physical address to a pointer to a pointer to a function, takes the value pointed to it, which is now a pointer to a function, and assigns it to app.

Then you should manage the switchover to the application vector table. You can do it either in the bootloader or in the application, or divide the steps between them.

  • Disable all interrupts and stop SysTick. Note that SysTick is not an interrupt, don't call NVIC_DisableIRQ() on it. I'd do this step in the bootloader, so it gets responsible to disable whatever it has enabled.
  • Assign the new vector table address to SCB->VTOR. Beware that the boilerplate SystemInit() function in system_stm32l1xx.c unconditionally changes SCB->VTOR back to the start of the flash, i.e. to 0x08000000, you should edit it to use the proper offset.

You can load the stack pointer value from the vector table too, but it's tricky to do it properly, and not really necessary, the application can just continue to use the stack that was set up in the bootloader. Just check it to make sure it's reasonable.

-1
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET;

where FLASH_BASE's value must be equal to the address of your IROM's value in KEIL

example:

#define FLASH_BASE      0x08004000

Keil configuration

Halley
  • 1
  • 2
  • It does not have. You may have many vectors tables at the same time, using different memories (not necessarily FLASH) and switch between them when you want. It is not the answer at all , and it is wrong. I would suggest deletion – 0___________ Jun 23 '19 at 07:19