RAM HAL library code relocation firmware update on single back flash controller (STM32G070)
Hi,
I wrote a flash bootloader for STM32G070 using IAR ide.
It gets via modbus RTU the command/data to manage the FSM that does the update procedure.
Because the master during erasing/programming needs a real time update on overall progression, the .intvec table, the main, the modbus stack and the updaing FSM are all relocated in RAM.
With firmware in RAM and a management of FLASH delete/program via IT the firmware can handle modbus during flash programming.
The .intvec relocation is done programmtically, copying it from FLASH (0x08000000) to RAM (0x20000000) (0xB8 bytes): I did via explicit firmware because I’m not able to do it via .icf
Also relocated in RAM stm32g0xx_hal_flash*.o via “initialize by copy” in .icf.
VTOR set to 0x20000000
main entry point and other self-made function as well as modbus stack’s marked as __ramfunc.
Great, you say, if everyhing works why this topic?
The truth is: to do all above I did a workaround because a problem came when I linked HAL_FLASH_IRQHandler.
With HAL_FLASH_IRQHandler linked all the code related to stm32g0xx_hal_flash*.o goes in FLASH, so “initialize by copy” seems failing
But if I clone the HAL_FLASH_IRQHandler or change the signature in __ramfunc void FLASH_IRQHandler(void) stm32g0xx_hal_flash*.o return “initialize by copy”.
I don’t want to change or rewrite HAL function, but use it.
At the moment with the workaround the firmware works.
Do you have any idea why linking HAL_FLASH_IRQHandler from HAL does “initialize by copy” failing?
Thanks all for your attention.
Below I report my .icf file.
/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_4.xml" */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x08000000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_IROM1_start__ = 0x08000000;
define symbol __ICFEDIT_region_IROM1_end__ = 0x08006FFF;
define symbol __ICFEDIT_region_IROM2_start__ = 0x0;
define symbol __ICFEDIT_region_IROM2_end__ = 0x0;
define symbol __ICFEDIT_region_EROM1_start__ = 0x0;
define symbol __ICFEDIT_region_EROM1_end__ = 0x0;
define symbol __ICFEDIT_region_EROM2_start__ = 0x0;
define symbol __ICFEDIT_region_EROM2_end__ = 0x0;
define symbol __ICFEDIT_region_EROM3_start__ = 0x0;
define symbol __ICFEDIT_region_EROM3_end__ = 0x0;
define symbol __ICFEDIT_region_IRAM_intvec_start__ = 0x20000000;
define symbol __ICFEDIT_region_IRAM_intvec_end__ = 0x200000B7;
define symbol __ICFEDIT_region_IRAM1_start__ = 0x200000B8;
define symbol __ICFEDIT_region_IRAM1_end__ = 0x20007FFF;
define symbol __ICFEDIT_region_IRAM2_start__ = 0x20008000;
define symbol __ICFEDIT_region_IRAM2_end__ = 0x20008FFF;
define symbol __ICFEDIT_region_ERAM1_start__ = 0x0;
define symbol __ICFEDIT_region_ERAM1_end__ = 0x0;
define symbol __ICFEDIT_region_ERAM2_start__ = 0x0;
define symbol __ICFEDIT_region_ERAM2_end__ = 0x0;
define symbol __ICFEDIT_region_ERAM3_start__ = 0x0;
define symbol __ICFEDIT_region_ERAM3_end__ = 0x0;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x400;
define symbol __ICFEDIT_size_proc_stack__ = 0x0;
define symbol __ICFEDIT_size_heap__ = 0x800;
/**** End of ICF editor section. ###ICF###*/
define memory mem with size = 4G;
define symbol use_IROM1 = (__ICFEDIT_region_IROM1_start__ != 0x0 || __ICFEDIT_region_IROM1_end__ != 0x0);
define symbol use_IROM2 = (__ICFEDIT_region_IROM2_start__ != 0x0 || __ICFEDIT_region_IROM2_end__ != 0x0);
define symbol use_EROM1 = (__ICFEDIT_region_EROM1_start__ != 0x0 || __ICFEDIT_region_EROM1_end__ != 0x0);
define symbol use_EROM2 = (__ICFEDIT_region_EROM2_start__ != 0x0 || __ICFEDIT_region_EROM2_end__ != 0x0);
define symbol use_EROM3 = (__ICFEDIT_region_EROM3_start__ != 0x0 || __ICFEDIT_region_EROM3_end__ != 0x0);
define symbol use_RAM_intvec = (__ICFEDIT_region_IRAM_intvec_start__ != 0x0 || __ICFEDIT_region_IRAM_intvec_end__ != 0x0);
define symbol use_IRAM1 = (__ICFEDIT_region_IRAM1_start__ != 0x0 || __ICFEDIT_region_IRAM1_end__ != 0x0);
define symbol use_IRAM2 = (__ICFEDIT_region_IRAM2_start__ != 0x0 || __ICFEDIT_region_IRAM2_end__ != 0x0);
define symbol use_ERAM1 = (__ICFEDIT_region_ERAM1_start__ != 0x0 || __ICFEDIT_region_ERAM1_end__ != 0x0);
define symbol use_ERAM2 = (__ICFEDIT_region_ERAM2_start__ != 0x0 || __ICFEDIT_region_ERAM2_end__ != 0x0);
define symbol use_ERAM3 = (__ICFEDIT_region_ERAM3_start__ != 0x0 || __ICFEDIT_region_ERAM3_end__ != 0x0);
if (use_IROM1)
{
define region IROM1_region = mem:[from __ICFEDIT_region_IROM1_start__ to __ICFEDIT_region_IROM1_end__];
}
else
{
define region IROM1_region = [];
}
if (use_IROM2)
{
define region IROM2_region = mem:[from __ICFEDIT_region_IROM2_start__ to __ICFEDIT_region_IROM2_end__];
}
else
{
define region IROM2_region = [];
}
define region IROM_region = IROM1_region | IROM2_region;
if (use_EROM1)
{
define region EROM1_region = mem:[from __ICFEDIT_region_EROM1_start__ to __ICFEDIT_region_EROM1_end__];
}
else
{
define region EROM1_region = [];
}
if (use_EROM2)
{
define region EROM2_region = mem:[from __ICFEDIT_region_EROM2_start__ to __ICFEDIT_region_EROM2_end__];
}
else
{
define region EROM2_region = [];
}
if (use_EROM3)
{
define region EROM3_region = mem:[from __ICFEDIT_region_EROM3_start__ to __ICFEDIT_region_EROM3_end__];
}
else
{
define region EROM3_region = [];
}
define region EROM_region = EROM1_region | EROM2_region | EROM3_region;
if (use_RAM_intvec)
{
define region RAM_region_intvec = mem:[from __ICFEDIT_region_IRAM_intvec_start__ to __ICFEDIT_region_IRAM_intvec_end__];
}
else
{
define region IRAM1_region_intvec = [];
}
if (use_IRAM1)
{
define region IRAM1_region = mem:[from __ICFEDIT_region_IRAM1_start__ to __ICFEDIT_region_IRAM1_end__];
}
else
{
define region IRAM1_region = [];
}
if (use_IRAM2)
{
define region IRAM2_region = mem:[from __ICFEDIT_region_IRAM2_start__ to __ICFEDIT_region_IRAM2_end__];
}
else
{
define region IRAM2_region = [];
}
define region IRAM_region = IRAM1_region | IRAM2_region;
if (use_ERAM1)
{
define region ERAM1_region = mem:[from __ICFEDIT_region_ERAM1_start__ to __ICFEDIT_region_ERAM1_end__];
}
else
{
define region ERAM1_region = [];
}
if (use_ERAM2)
{
define region ERAM2_region = mem:[from __ICFEDIT_region_ERAM2_start__ to __ICFEDIT_region_ERAM2_end__];
}
else
{
define region ERAM2_region = [];
}
if (use_ERAM3)
{
define region ERAM3_region = mem:[from __ICFEDIT_region_ERAM3_start__ to __ICFEDIT_region_ERAM3_end__];
}
else
{
define region ERAM3_region = [];
}
define region ERAM_region = ERAM1_region | ERAM2_region | ERAM3_region;
do not initialize { section .noinit };
initialize by copy { readwrite };
if (isdefinedsymbol(__USE_DLIB_PERTHREAD))
{
// Required in a multi-threaded application.o
initialize by copy with packing = none { section __DLIB_PERTHREAD };
}
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
// place at address mem:__ICFEDIT_region_IRAM_intvec_start__ { section .intvec_init };
//initialize by copy { object utils.o };
initialize by copy { object stm32g0xx_hal_flash.o };
initialize by copy { object stm32g0xx_hal_flash_ex.o };
//initialize by copy { object stm32g0xx_it.o };
//initialize by copy {
// object stm32g0xx_hal.o ,
// object stm32g0xx_hal_cortex.o ,
// object stm32g0xx_hal_flash.o ,
// object stm32g0xx_hal_gpio.o ,
// object stm32g0xx_hal_tim.o ,
// object stm32g0xx_hal_tim_ex.o ,
// object stm32g0xx_ll_rcc.o ,
// object stm32g0xx_ll_usart.o ,
// object stm32g0xx_ll_utils.o,
// object ABImemcpy.o ,
// object I32DivModFast.o,
// object uread4.o,
// object lz77_init.o,
// object system_stm32g0xx.o,
// section .intvec
// };
initialize by copy { readwrite };
if (!isempty(IROM_region))
{
place in IROM_region { readonly };
}
if (!isempty(EROM_region))
{
place in EROM_region { readonly section application_specific_ro };
}
//if (!isempty(RAM_region_intvec))
//{
// define block RAM_INTVEC { section .intvec_rw };
// place in RAM_region_intvec { block RAM_INTVEC };
//
//}
if (!isempty(IRAM_region))
{
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
define block PROC_STACK with alignment = 8, size = __ICFEDIT_size_proc_stack__ { };
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
place in IRAM_region { readwrite, block CSTACK, block PROC_STACK, block HEAP };
}
if (!isempty(ERAM_region))
{
place in ERAM_region { readwrite section application_specific_rw };
}
