cancel
Showing results for 
Search instead for 
Did you mean: 

IAP programming

Jimis
Associate II

Hi

I'm trying use In App programming for the STM32L432KC board. Unfortunately there is no working example provided (app note AN4657 has STM3210C_EVAL and STM32L476G_EVAL which is dual bank).

I have managed to modify the example and written correctly the Flash (verified with debugger). The problem is when jumping to the address I get a hardfault_handler error.

The details of my setup are these:

I have separated flash in 2 areas since I don't have dual banks

area A 0x0800 0000

area B 0x0802 0000

I write my new binary (blink code) file in area B and I jump using the following code, where APPLICATION_ADDRESS=0x0802 0000 (area B):

     //SCB->VTOR = APPLICATION_ADDRESS;
 
 
     /* execute the new program */
 
     JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS + 4);
 
     /* Jump to user application */
 
     JumpToApplication = (pFunction) JumpAddress;
 
 
     /* Initialize user application's Stack Pointer */
 
     __set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS);
 
     JumpToApplication();

I read in this post that you need to add SCB->VTOR = APPLICATION_ADDRESS; for the interrupt vectors to initialize to the new address but I still get the error

inside the hardfault_handler I read the SCB and get the following

0693W00000AOWdmQAH.jpgwhich gives a BFSR register error at address 0x20010000 which points to a reserved space

Any ideas what I'm doing wrong ? According to the example you don't need to do anything else after you have loaded new program to flash. Just set MSP and jump.

Thanks in advance

13 REPLIES 13

Is the code present? You should check the values are valid before jumping, and perhaps checksum or sign the image.

Have you tried stepping into the code?

The VTOR looks to be zero, check that the SystemInit() on the application side sets the address properly.

What's the address of the fault?

What happens if you don't set the MSP, but rather set the SP in the app's Reset_Handler ?

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

Hi,

In your application which is burned to Flash you have to change the line:

#define VECT_TAB_OFFSET 0x00000000UL /*!< Vector Table base offset field.

to the loading address offset and you have to change your linker that the flash starts at the same address.

Then compile and load it. Then it should work.

And dont forget that offset is 0X20000 for you , but in normal situation bootloader parts dont need 128k then you can use less and leave for application more.,.

And too you need give here info about IDE, for example KEIL need other setups as CubeIDE for this IAPs

Jimis
Associate II

I think I have some blanks here. My app is trying to upgrade itself by another code (blink). If I understand right the .bin files don't include the address info where to write in flash. For test purposes I tell my running app start writing the new code (blink) in area B but later the running app will decide depending on which area is currently being used. Why would I need to change anything in my blink code ? I just run it in another place in flash.

I assume that when the new blink code starts to run after the jump then the SystemInit() will run with the following

void SystemInit(void)
{
#if defined(USER_VECT_TAB_ADDRESS)
  /* Configure the Vector Table location -------------------------------------*/
  SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET;
#endif
 
....
}

But for SCB-> VTOR to get set I need to have defined the USER_VECT_TAB_ADDRESS

I tried this also below but still crashes

//      /* Configure the Vector Table location -------------------------------------*/
	  #define USER_VECT_TAB_ADDRESS								
	  #define VECT_TAB_BASE_ADDRESS (0x08000000UL)
	  #define VECT_TAB_OFFSET        APPLICATION_ADDRESS - FLASH_BASE 
      SCB->VTOR =  APPLICATION_ADDRESS;
 
      /* execute the new program */
      JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS + 4);
      /* Jump to user application */
      JumpToApplication = (pFunction) JumpAddress;
 
      /* Initialize user application's Stack Pointer */
      __set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS);
      JumpToApplication();

If I set SCB->VTOR = APPLICATION_ADDRESS;

without the defines I get the VTOR set correctly before jumping but after debugger crashes

0693W00000AOWu4QAH.jpg 

Still crashes where exactly?

Perhaps look at a disassembly of what the compiler has generated, and step across the transition.

Make sure you don't have random interrupts firing, disable interrupts at the peripheral, turn off SysTick, etc.

If you move the vector table the app will get them, but likely has different memory/instances that aren't initialized.

So get the system under control before transferring execution to the application code.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
MM..1
Chief III

You maybe miss understanding two code VTOR management.

  1. Code on address 0X08000000 is main loader after reset and uses offset 0
  2. when jump to application no VTOR change
  3. Code on address 0X08020000 is aplication and in system start need offset 0X20000

Example code to jump from A to B

				// Jump to user application
				JumpAddress = *(__IO uint32_t*) (USER_START_ADDRESS +4);
				Jump_To_Application = (pFunction) JumpAddress;
				// Initialize user application's Stack Pointer
				__set_MSP(*(__IO uint32_t*) USER_START_ADDRESS);
				Jump_To_Application();

when you compile B need change OFFSET and BASE for build. OFFSET in CubeIDE is in system_stm32l4xx.c

BASE is in linker ld file. Here only example you need edit your .

/* Specify the memory areas */
MEMORY
{
RAM (xrw)      : ORIGIN = 0x20000000, LENGTH = 192K
CCMRAM (rw)      : ORIGIN = 0x10000000, LENGTH = 64K
FLASH (rx)      : ORIGIN = 0x8008000, LENGTH = 2016K
}

Jimis
Associate II

I added  __disable_irq(); before jump. Disassembly just before it crashes

0693W00000AOX6AQAX.jpg0693W00000AOX6UQAX.jpgAbout the link file. I don't see why I need to change it. I'm transferring a binary file.

Is the flash area to be written included in .bin file ? I need to have same file run in area A or B.

I understand the offset I need to change which is done by the line below , but still won't work ( I tried with my defines in my previous messages)

#define VECT_TAB_OFFSET       APPLICATION_ADDRESS - FLASH_BASE // (=0x0002 0000)

MM..1
Chief III

About the link file. I don't see why I need to change it

Then sorry you dont know what you do. In normal code isnt place independent, only when you set PIC, but i mean first you need uderstand how compiler and linker generate code and why same bin cant run on any address. But for your better understanding vectors in interrupt table is addressed to code on absolute addr. Then code for example for USART interrupt in code A is on 0X08000475, but in code B when this code isnt totaly equal is for example on 0X08021355 and linker for B when you dont change ld script write to table 0X08001355. SEE YOU WHY???

Jimis
Associate II

Ok I think it's clear now that I can't use the same .bin file. I will have to ask the running app which area it uses to send the correct file.

I changed the link file like this

MEMORY

{

 RAM   (xrw)   : ORIGIN = 0x20000000,  LENGTH = 64K

 FLASH   (rx)   : ORIGIN = 0x8020000,  LENGTH = 256K

}

and set my defines before jumping

#define USER_VECT_TAB_ADDRESS

#define VECT_TAB_BASE_ADDRESS (0x08000000UL)

#define VECT_TAB_OFFSET APPLICATION_ADDRESS - FLASH_BASE (= 0x0002 0000)

program seems to jump at the right place but stops running at this point

0693W00000AOXEOQA5.jpg