2020-08-08 11:20 AM
STM32L4R5ZI has SRAM1 (0x20000000 - 0x2002FFFF) , SRAM2 (0x20030000 - 0x2003FFFF) and SRAM 3 (0x20040000 - 0x2009FFFF).
I move VTOR table as per my Application Flash starting address. In code, I relocate Interrupt table to RAM for my own ISR handlers ( HalInterruptTableRelocate( uint32_t address) )
I face issue while relocating interrupt vector table to RAM.
If Relocate interrupt table to 0x2003000(SRAM2 base address) locations, everything works normal.
if i relocate to any other RAM location(ex.0x20000000) , application doesn't run. I attached my target to debug, where i notice, control hits SystemInit() and then generate a hardfault instead of entering to Main().
------------------------
An instruction executed with an invalid EPSR.T or EPSR.IT field (CFSR.INVSTATE)
--------------------------
I've considered 'Interrupt Table Relocation RAM address shall be MOD of 4".
Theoretically, I should be able to relocate to any SRAM address , is not it??
Can any one please help me on this?
--------------------
void SystemInit(void)
{
/* FPU settings ------------------------------------------------------------*/
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */
#endif
/* Reset the RCC clock configuration to the default reset state ------------*/
/* Set MSION bit */
RCC->CR |= RCC_CR_MSION;
/* Reset CFGR register */
RCC->CFGR = 0x00000000U;
/* Reset HSEON, CSSON , HSION, and PLLON bits */
RCC->CR &= 0xEAF6FFFFU;
/* Reset PLLCFGR register */
RCC->PLLCFGR = 0x00001000U;
/* Reset HSEBYP bit */
RCC->CR &= 0xFFFBFFFFU;
/* Disable all interrupts */
RCC->CIER = 0x00000000U;
/* Configure the Vector Table location add offset address ------------------*/
#ifdef VECT_TAB_SRAM
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
#else
SysTick->CTRL &= ~(SysTick_CTRL_TICKINT_Msk);
HAL_NVIC_DisableIRQ( LPUART1_IRQn );
SCB->VTOR = (unsigned int)&__intvec_start__; /* Vector Table Relocation in Internal FLASH */
#endif
}
------------------------
relocate code::
if i pass: 0x20030000 , it works, but doesn't work for 0x20000000 or 0x20040000.
#ifdef __ICCARM__
#if (__VER__ < 500)
#pragma segment="VTABLE"
#else
#pragma section="VTABLE"
#endif // #if (__VER__ < 500)
#pragma data_alignment=256
__no_init unsigned int IvtRamMain[IVT_ENTRIES] @ "VTABLE";
#else
#error "The position should be forced in RAM @ a specific address
#endif /* __ICCARM__ */
HalInterruptTableRelocate( uint32_t Address ) {
HalStatus Result = HAL_SUCCESS;
uint32_t OriginalNvicAddress = 0U;
uint32_t IrqNvicId = 0U;
uint32_t ReadAddress = 0U;
uint32_t WriteAddress = 0U;
uint32_t IrqCallbackAddress = 0U;
/* Get Start address of original Vector Table */
OriginalNvicAddress = SCB->VTOR;
/* Copy IVT from Original to RAM */
ReadAddress = OriginalNvicAddress;
WriteAddress = Address;
while (IrqNvicId < IVT_ENTRIES) {
IrqCallbackAddress = *(volatile uint32_t *) ReadAddress;
*(volatile uint32_t *) WriteAddress = (uint32_t) IrqCallbackAddress;
IrqNvicId++;
ReadAddress += sizeof(&ReadAddress);
WriteAddress += sizeof(&WriteAddress);
}
/* Shift of Vector Table at specified address that is RAM segment */
/* Null offset applied */
SCB->VTOR = Address | (NULL_VTOR_OFFSET & (uint32_t) SCB_VTOR_TBLOFF_Msk);
Result = HAL_SUCCESS;
}
----------------------
ICF FILE ::
define exported symbol __intvec_start__ = 0x0802A200; /* Used when not relocated in RAM */
/*-Memory Regions-*/
define symbol __region_ROM_start__ = 0x0802A200;
define symbol __region_ROM_end__ = 0x080C9FFF;
define symbol __region_RAM_start__ = 0x20000200;
define symbol __region_RAM_end__ = 0x2009FFFF;
/* [RAM = 192kb + 64kb + 384kb = 0xA0000] */
define symbol __region_vtor__start__ = 0x20000000; /* Used when relocated in RAM */
define symbol __region_vtor__end__ = 0x200001BF; /* Aligned on 8 bytes (448 = 112 x 8) */
define symbol __region_SRAM1_start__ = 0x20000000;
define symbol __region_SRAM1_end__ = 0x2002FFFF;
define symbol __region_SRAM2_start__ = 0x20030000;
define symbol __region_SRAM2_end__ = 0x2003FFFF;
define symbol __region_SRAM3_start__ = 0x20040000;
define symbol __region_SRAM3_end__ = 0x2009FFFF;
/*-Sizes-*/
define symbol __size_heap__ = 0X1000;
define symbol __size_cstack__ = 0x2000;
/* Memory regions */
define memory mem with size = 4G;
define region EXPLOIT_HEADER_ROM_region = mem:[from 0x0802A000 to 0x0802A1FF];
define region EXPLOIT_ROM_region = mem:[from 0x0802A400 to __region_ROM_end__];
define region intRAM_region = mem:[from __region_RAM_start__ to __region_RAM_end__];
define region VTOR_region = mem:[from __region_vtor__start__ to __region_vtor__end__];
define block CSTACK with alignment = 8, size = __size_cstack__ { };
define block HEAP with alignment = 8, size = __size_heap__ { };
initialize by copy { readwrite };
do not initialize { section .noinit };
place at address mem:__intvec_start__ { readonly section .intvec };
/* SRAM1 Configuration */
/*place at address mem:0x20000000 {readwrite section VTABLE};*/
/* SRAM2 Configuration */
place at address mem:0x20030000 {readwrite section VTABLE};
place at address mem:0x20000200 {readwrite section INT_RAM }; /* Aligned on 8 bytes (448 = 112 x 8) - 0x1BF */
place in EXPLOIT_HEADER_ROM_region {readonly section file_header};
place in EXPLOIT_ROM_region {readonly};
place in intRAM_region { readwrite,
block CSTACK, block HEAP};
2020-08-08 11:26 AM
my Flash/RAM consumption details in Application.
431 747 bytes of readonly code memory
159 216 bytes of readonly data memory
373 892 bytes of readwrite data memory (+ 440 absolute)
2020-08-08 01:41 PM
Check where linker is actually placing things via the .MAP file.
Perhaps create additional RAM sections so there is no opportunity for conflicting usage.
You don't want variables and stack on top of the vectors.
2020-08-09 07:01 AM
Hi,
Thanks for your reply. If you look into the code i provided, i'm creating a space in RAM in this way.
#ifdef __ICCARM__
#pragma location=0x20000000 //SRAM1 base address,total size: 192KB
//#pragma location=0x20030000 //SRAM2 base address,total size: 64KB
#else
#error "The position should be forced in RAM @ a specific address
#endif /* __ICCARM__ */
uint32_t IvtRam1Main[IVT_ENTRIES];
void InterruptVectorTableRelocate(void)
{
uint32_t RamTargetAddress = 0;
/* Relocate the IVT in user's defined RAM 2 segment */
RamTargetAddress = (uint32_t) &IvtRam1Main[0];
(void) HalInterruptTableRelocate(RamTargetAddress);
}
I've allocated 440bytes for Interrupt Relocation in RAM.
.MAP FILE
--------------
IvtRam1Main 0x2000'0000 0x1b8 Data Gb HalCommon.o [1]
431 747 bytes of readonly code memory
159 216 bytes of readonly data memory
373 892 bytes of readwrite data memory (+ 440 absolute)
My Application with bootloader works with location=0x20030000 (SRAM2 base address),
but it doesn't work with 0x20000000.
Do you find anything i've bad configuration?
You don't want variables and stack on top of the vectors.
I'm not clear on this point. when I set 0x20000000, i think variable and stacks will come below this vectors, is not it?
is it mandatory to keep on top?
Regard's
Asish