STM32F7 ITCM Posted by devcal on 2016-03-24 11:21 Hi, Does any one has an example of a startup and linkerscript for loading some functions into the ITCM by the STM32F7? Regards
Posted by tarek bouchkati on 2016-03-24 14:48 Hello, There no need to modify the startup file, the only modif is in linker file : instead of FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K, you should have FLASH (rx) : ORIGIN = 0x00200000, LENGTH = 1024K Edit : The only problem is that openocd included in the current version of SystemWorkbench cannot program the ITCM Flash. The only solution (for now) is to use ST-Link Utility version 3.9 (will be released by the end of next week) to program your MCU 's ITCM Flash. Note: You have to set the Boot address option bytes (possible through ST-Link Utility > Option Bytes) Best Regards, Tarek BOUCHKATI STMicroelectronics
Posted by bobesch on 2016-04-22 16:58 Flash _write_access can _not_ be done at 0x00200000. It has to be done at 0x08000000. To get openocd to load a flash with code linked for ITCM access, something like MEMORY { ITCM (rwx) : ORIGIN = 0x00000000, LENGTH = itcm_length ITCMFL (rx) : ORIGIN = 0x00200000, LENGTH = flash0_length FLASH0 (rx) : ORIGIN = 0x08000000, LENGTH = flash0_length SRAM0 (rwx) : ORIGIN = 0x20000000, LENGTH = ram0_length } SECTIONS { .itcmtext : { . = ALIGN(4); _svect = .; KEEP(*(.isr_vector)) _evect = .; *(.nutinit) *(.text .text.* .gnu.linkonce.t.*) *(.glue_7t) *(.glue_7) *(.gcc_except_table) = ALIGN(4); } > ITCMFL AT > FLASH0 has to be written in the linker script.
Posted by devcal on 2016-03-24 16:15 Hi Tarek , Thanks for your answer can I use until then the 16K ITCM-RAM for that ? I have some critical and deterministic code that must run as fast as possible. if I load in the startup this function into the ITCM-RAM how can I tell my compiler to use the functions from the ITCM and not from the flash? Regards Dev.
Posted by tarek bouchkati on 2016-03-24 20:49 Sorry but I have misunderstood your question, thought you are talking about ITCM FLASH ๐. It is not the case ? Anyway, In my previous post I was talking about ITCM-FLASH. If you want to load a specific function into a specific RAM region (in this case ITCM-RAM) you have to use the section feature: example : main.cCopy to clipboardvoid routine_name __attribute__((section(".section_name"))) (void) { // code } linker.ldCopy to clipboard/*...................*/ /* Specify the memory areas */ MEMORY { ITCM_RAM (rx) : ORIGIN = 0x00000000, LENGTH = 16K FLASH (rx) : ORIGIN = 0x00200000, LENGTH = 1024K RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 320K QSPI (xrw) : ORIGIN = 0x90000000, LENGTH = 16M } /* Define output sections */ SECTIONS { /*........*/ .section_name : { . = ALIGN(4); *(.section_name) /* .section_name section */ *(.section_name*) /* .section_name* sub-sections if any */ . = ALIGN(4); } >ITCM_RAM AT> FLASH /*........*/ } I hope that this can help you ๐
Posted by marioleone on 2016-04-14 23:26 Hi, I have a question referent FLASH-ITCM, can i put code on this region from the RAM? Let me to explain: in a STM32F7406 there is 2 memories flash, one ITCM and other AXI, in AXI put the normal code to process but i need to more space to save a data, these data don't change anymore, but i need maybe 900 Kbyte and I can't use the AXI region because my code have almost 500 Kbyte for this reason i want to use the ITCM region. How i can write this region using the HAL? I try to use these function: "Flash_If_Init()" "Flash_If_Write(Buff, FLASHAXI_BASE, len)" from the HAL library but always i got hard fault. Thanks and Best Regards.
Posted by hervelg on 2016-10-27 10:29 Hi, Adding to what tarek said, you also have to modify the startup assembly code to load the itcm code from flash to ITCM at each restart. You have to do the same as for initializes data. Best regards
Posted by bugmenot on 2017-04-08 19:27 If you want to modify an existing linker script for ITCM, don't forget to use ALIGN_WITH_INPUT section attribute, or you'd have aligned sections slipping if previous section doesn't completely fill the aligned size. An example script (modified from STM32CubeMX boilerplate) STM32F765VITx_FLASH.ld: Copy to clipboard/* Generated by STM32CubeMX */ /* Modified for GDB+OpenOCD */ /* Entry Point */ ENTRY(Reset_Handler) /* Highest address of the user mode stack */ _estack = 0x20080000; /* end of RAM */ /* Generate a link error if heap and stack don't fit into RAM */ _Min_Heap_Size = 0x200; /* required amount of heap */ _Min_Stack_Size = 0x400; /* required amount of stack */ /* Specify the memory areas */ MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 512K FLASH (rx) : ORIGIN = 0x00200000, LENGTH = 2048K AXIFLASH (rx) : ORIGIN = 0x08000000, LENGTH = 2048K } /* Define output sections */ SECTIONS { /* The startup code goes first into FLASH */ .isr_vector : ALIGN_WITH_INPUT { . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } >FLASH AT > AXIFLASH /* The program code and other data goes into FLASH */ .text : ALIGN_WITH_INPUT { . = ALIGN(32); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH AT > AXIFLASH /* Constant data goes into FLASH */ .rodata : ALIGN_WITH_INPUT { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH AT > AXIFLASH .ARM.extab : ALIGN_WITH_INPUT { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH AT > AXIFLASH .ARM : ALIGN_WITH_INPUT { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } >FLASH AT > AXIFLASH .preinit_array : ALIGN_WITH_INPUT { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH AT > AXIFLASH .init_array : ALIGN_WITH_INPUT { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH AT > AXIFLASH .fini_array : ALIGN_WITH_INPUT { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH AT > AXIFLASH /* used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections goes into RAM, load LMA copy after code */ .data : ALIGN_WITH_INPUT { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> AXIFLASH /* Uninitialized data section */ . = ALIGN(4); .bss : { /* This is used by the startup in order to initialize the .bss secion */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough RAM left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the standard libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } }