cancel
Showing results for 
Search instead for 
Did you mean: 

How to make program start from a customized address?

song
Associate II
Posted on January 08, 2015 at 04:51

I understand this question has been asked before. I searched the forum and view these three threads: 

''How to program the application flash file (hex file) in chosen flash area by using ST-LINK for STM32F0''

''Flash Address setting to write main program starting from specific address''

''How start running STM32 firmware from IROM2 ?''

However, I still have some doubts. For STM32F407, there are 12 flash sectors. If I define the IROM1 address to be 0x080E0000, which is the 12th sector, can I then store data in the first 11 sectors, including sector 0 starting from 0x08000000? From the threads, it seems that I can't because some vectors are located in sector 0. Does it mean I can only use sector 1~11?

#know-your-tools #flash #boot #stm32f4
15 REPLIES 15
song
Associate II
Posted on January 14, 2015 at 06:49

I think I understand the concepts and what I should do, my question is how to do it. I already went through  the example code with AN3965. This example program still starts from 0x08000000 and it can perform a jump to user code that starts from 0x08004000, but the problem I had is that the program can't even reach main entry if it is located at the customized address. I have tried Keil's configuration for IROM1, linker memory layout, flash download memory and changed VECT_TAB_OFFSET in SystemInit(), but none of them works. So when the MCU can't find the main entry, I can't use code in main() to change table address or jump, as the example does. That only leaves me Keil target setup and linker configurations, or maybe bootload handling which I currently don't know much. So I really need some advice about HOW to solve the problem.

Posted on January 14, 2015 at 13:01

The memory mapped at zero at reset is controlled by the BOOTx pins, these define THREE addresses, 0x080E0000 is NOT one of them.

http://www.keil.com/forum/59235/

You'd need to create an IROM2 section at 0x08000000 of at least EIGHT bytes in size, and place TWO vectors in there.

; Vector Table Mapped to Address 0 at Reset
AREA RESETZERO, DATA, READONLY
DCD __initial_sp ; Top of Stack
DCD Reset_Handler ; Reset Handler

; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************
LR_IROM1 0x080E0000 0x00020000 { ; load region size_region
ER_IROM1 0x080E0000 0x00020000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
RW_IRAM1 0x20000000 0x00020000 { ; RW data
.ANY (+RW +ZI)
}
}
LR_IROM2 0x08000000 0x00000010 { ; load region size_region
ER_IROM2 0x08000000 0x00000010 { ; load address = execution address
*.o (RESETZERO)
}
}

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
song
Associate II
Posted on January 15, 2015 at 05:03

My biggest mistake. The program still can't run. It was the one that previously burned to 0x8000000 which runs even though the modified one was burned to 0x80E0000. So back to square 1. :(

song
Associate II
Posted on January 15, 2015 at 08:01

Does it mean I have to write my won startup code? In the default onestartup_stm32f4xx.s

; Vector Table Mapped to Address 0 at Reset
AREA RESET, DATA, READONLY
EXPORT __Vectors
EXPORT __Vectors_End
EXPORT __Vectors_Size
__Vectors DCD __initial_sp ; Top of Stack
DCD Reset_Handler ; Reset Handler

After I set IROM2, the scatter file shows

LR_IROM1 0x080E0000 0x00020000 { ; load region size_region
ER_IROM1 0x080E0000 0x00020000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
RW_IRAM1 0x20000000 0x00001000 { ; RW data
.ANY (+RW +ZI)
}
}
LR_IROM2 0x08000000 0x00000100 {
ER_IROM2 0x08000000 0x00000100 { ; load address = execution address
.ANY (+RO)
}
}

If I manually change the code in LR_IROM2 from

.ANY (+RO) to

*.o (RESET), the compiler will complain:

Error: L6223E: Ambiguous selectors found for startup_stm32f4xx.o(RESET) from Exec regions ER_IROM1 and ER_IROM2.

So any advice about how I can map vector table to IROM2?
GAJOBAR
Associate II

Hello,

The post is to ancient, but if someone need start de App in a specific location on memory, need to do the next steps:

Step 1: Open xxxx_FLASH.Id and change the line #50 or when you can find the text
"FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 1024K" (for STM32F407, p.e.) and modify the ORIGIN with
the FLASH_ADDR_APP_JUMP_EN and the LENGTH subtracting the DFU and EEPROM sizes. P.E.:

If FLASH_ADDR_APP_JUMP_EN = 0x08010000, put in ORIGIN = 0x08010000 and LENGHT = 960K

 

Step 2: Open ../Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32F407xx.h and change the line
#906 or when you can find the text "#define FLASH_BASE 0x08000000UL" and
modify the value with the FLASH_ADDR_APP_JUMP_EN. P.E.:

If FLASH_ADDR_APP_JUMP_EN = 0x08010000, put in FLASH_BASE the value 0x08010000

 

Step 3: In the sysetm_stm32f4xx.c file, in line #94, uncomment the definition
"#define USER_VECT_TAB_ADDRESS" for relocate the vector table and, in the line #108
put the offset value. P.E.:

FLASH_ADDR_APP_JUMP_EN = 0x08010000 => #define VECT_TAB_OFFSET 0x00010000U

 

With this simples steps, you can configure all, position for code and table vectors. Only need to jump to this position to run without a DFU or another program in the empty space.

 

Regards

Yeah a NINE year old thread, where the OP was using KEIL, not GNU/GCC

Or use a linker symbol for the Vector Table so you don't have to edit multiple files and change defines, and allow the same files to build correctly at the address defined in the linker script / scatter file.

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