Loading...
 

SW4STM32 and SW4Linux fully supports the STM32MP1 asymmetric multicore Cortex/A7+M4 MPUs

   With System Workbench for Linux, Embedded Linux on the STM32MP1 family of MPUs from ST was never as simple to build and maintain, even for newcomers in the Linux world. And, if you install System Workbench for Linux in System Workbench for STM32 you can seamlessly develop and debug asymmetric applications running partly on Linux, partly on the Cortex-M4.
You can get more information from the ac6-tools website and download (registration required) various documents highlighting:

System Workbench for STM32


STM32F7 ITCM

Hi,
Does any one has an example of a startup and linkerscript for loading some functions into the ITCM by the STM32F7?

Regards

Tunisia

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

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.


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.


Tunisia

Sorry but I have misunderstood your question, thought you are talking about ITCM FLASH confused. 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.c
void routine_name __attribute__((section(".section_name"))) (void)
{
  // code
}

linker.ld
/*...................*/
/* 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 smile


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.


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


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:

/* 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) }
}