2015-07-16 05:12 AM
Hi,
I have an application running on the stm32F030.It has a 'bootloader' application at 0x08000000, which successfully jumps to the 'real' application, at 0x08002000.The jump and relocation was done according to/public/STe2ecommunities/mcu/Lists/STM32Discovery/Flat.aspx?RootFolder=https://my.st.com/public/STe2ecommunities/mcu/Lists/STM32Discovery/Cortex%20M0%20Vector%20relocation%20issue&FolderCTID=0x01200200770978C69A1141439FE559EB459D75800084C20D8867EAD444A5987D47BE638E0F¤tviews=1159
.Till now everything was working fine - SPI, 2 UARTs, GPIOs, etc.My problem:I added code waiting on an external interrupt.This code works fine when the code is linked normally (0x08000000, no relocation), but the interrupt isn't called when relocated.I see the interrupt happening on a scope.Thanks. #stm32f0 #vector-table #code-relocation2015-07-16 05:19 AM
So what code exactly are you using?
Make sure you're enabling the SYSCFG clock, not resetting it.Confirm that your new vector table (ie via it's content) is visible in the base of RAM (0x20000000), and at address ZERO (0x00000000).2015-07-16 08:12 AM
My code, called first thing from
main()
:
#define APPLICATION_ADDRESS 0x08002000
#pragma location = 0x20000000
__no_init __IO uint32_t VectorTable[48];
static
void
Main_RelocateVectorTable(
void
)
{
for
(byte i = 0; i < 48; i++) {
VectorTable[i] = *(__IO ulint *)(APPLICATION_ADDRESS + (i << 2));
}
/* Enable the SYSCFG peripheral clock*/
RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG, ENABLE);
/* Remap SRAM at 0x00000000 */
SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_SRAM);
}
And my
stm32f0xx_flash-0x8002000.icf, changes marked in red:
/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile=''$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml'' */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ =
0x08002000
;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__ =
0x08002000
;
define symbol __ICFEDIT_region_ROM_end__ = 0x0800FFFF;
define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
define symbol __ICFEDIT_region_RAM_end__ = 0x20001FFF;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x400;
define symbol __ICFEDIT_size_heap__ = 0x200;
/**** End of ICF editor section. ###ICF###*/
define memory mem with size = 4G;
define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
export symbol __ICFEDIT_region_RAM_start__;
export symbol __ICFEDIT_region_RAM_end__;
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
initialize by copy { readwrite };
do not initialize { section .noinit };
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place in ROM_region { readonly };
place in RAM_region { readwrite,
block CSTACK, block HEAP };
Seems like I'm resetting theSYSCFG clock, not resetting it - should I call
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE)
? I don't have the HW open now, can try later tonight. Thanks2015-07-16 09:04 AM
Seems like I'm resetting the SYSCFG clock, not resetting it - should I call RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE) ?
Correct, it came from the ST ISP examples, and was wrong. I've fixed other threads, but can't edit my older posts (old email address, now defunct), plus this broken forum software alters the time-line of the thread.2015-07-16 11:25 AM
Thanks, it worked.
I owe you a beer :)2015-07-16 11:50 AM
1 more question:
I noticed that my 'Release' code (highest optimization level, SIZE) fails to work, but with no optimization it works.I'm using IAR 7.20.2.7431.Any ideas?2015-07-16 04:33 PM
Hi Clive,
I've been banging my head on this exact same problem, and finally narrowed it down to something observable - mainly, I could not get my external interrupt on PB15 to trigger, and finally noticed in the registers that while SYSCFG was enabled in the RCC, the EXTI15 bits in EXTICR4 were stuck at 000 (Port A) - not 001 for Port B! I came online, and found this post simply because it is newest! Making the exact same change (changing theRCC_APB2PeriphResetCmd
call toRCC_APB2PeriphClockCmd
) fixes it!But I have a new problem - my faulty bootloader has already been delivered, and I need to fix it up. Should I be able to simply relocate the vector table at the start of my app?Fortunately, the bootloader has only been delivered for a pre-production run, so I do have time to recover...Thanks for being such a valuable resource!2015-07-16 05:00 PM
This is code that's typically placed at the front of main() in the application image, the boot loader shouldn't need to change it's vector table as there is a direct map of 0x08000000 to 0x00000000
The app should also carve out space in the front of RAM for the table, either via the linker script or scatter file, so it's not use by the app code for other things.2015-07-16 11:04 PM
Found the problem - missed a 'volatile'...
2015-11-04 12:29 AM
Hi clive,
I am working the same function, booting from one image (Image A) from address 0x0800000 and jump to another image ( Image B ) from address 0x0x08004000, and I reference the code ,try to setting the jump function as follow, but it is not work..... could you kindly help me to check what I missed? =============================================================Image A :
main.c
#define APPLICATION_ADDRESS
0x08004000
__no_init __IO uint32_t VectorTable[48]; static void Main_RelocateVectorTable(void) { int i; for(i = 0; i < 48; i++) { VectorTable[i] = *(__IO uint32_t*)(APPLICATION_ADDRESS + (i << 2)); } /* Enable the SYSCFG peripheral clock*/ RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG, ENABLE); } int main(void) { Main_RelocateVectorTable(); typedef void (*pFunction)(void); pFunction Jump_To_Application; uint32_t JumpAddress; // 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(); }icf file setting:
/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/ /* IcfEditorFile=''$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml'' */ /*-Specials-*/ define symbol __ICFEDIT_intvec_start__ =0x08000000;
/*-Memory Regions-*/ define symbol __ICFEDIT_region_ROM_start__ =0x08000000 ;
define symbol __ICFEDIT_region_ROM_end__ = 0x0800FFFF; define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; define symbol __ICFEDIT_region_RAM_end__ = 0x20001FFF; /*-Sizes-*/ define symbol __ICFEDIT_size_cstack__ = 0x800; define symbol __ICFEDIT_size_heap__ = 0x300; /**** End of ICF editor section. ###ICF###*/and I download the bin file ( Image A ) from start address 0x08000000 by ST-LINK Utility.
Image B :
main.c
int main(void)
{ while (1) { (*MainTable[cMainIndex])(); // it should be do some initial and print message. } }icf file setting:
/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/ /* IcfEditorFile=''$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml'' */ /*-Specials-*/ define symbol __ICFEDIT_intvec_start__ =0x08004000;
/*-Memory Regions-*/ define symbol __ICFEDIT_region_ROM_start__ =0x08004000 ;
define symbol __ICFEDIT_region_ROM_end__ = 0x0800FFFF; define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; define symbol __ICFEDIT_region_RAM_end__ = 0x20001FFF; /*-Sizes-*/ define symbol __ICFEDIT_size_cstack__ = 0x800; define symbol __ICFEDIT_size_heap__ = 0x300; /**** End of ICF editor section. ###ICF###*/ and I download the bin file ( Image B ) from start address0x08004000
by ST-LINK Utility. ============================================================= I have checked the size of Image A not over 0x08004000 ( not overwrite to Image B area ), but it seems not jump to Image B successfully, could you have some suggest for me? Thanks a lot