cancel
Showing results for 
Search instead for 
Did you mean: 

Running a software from a flash STM32F779II

Ahmed Tolba
Associate II

I would like to run my firmware from the flash address :0x08040000

so I partitioned the memory layout for the software as shown:

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 = 0x1000;      /* required amount of heap  */
 
_Min_Stack_Size = 0x2000; /* required amount of stack */
 
 
 
/* Specify the memory areas */
 
MEMORY
 
{
 
  FLASH  (rx)  : ORIGIN = 0x08040000, LENGTH = 768K
 
  FLASH2 (r)   : ORIGIN = 0x08100000, LENGTH = 1024K
 
  SRAM1 (xrw)     : ORIGIN = 0x20020000, LENGTH = 368K
 
  SRAM2 (xrw)     : ORIGIN = 0x2007C000, LENGTH = 16K
 
  DTCMRAM (wal) : ORIGIN = 0x20000000, LENGTH = 128K
 
  MEMORY_B1 (rx)  : ORIGIN = 0x60000000, LENGTH = 0K
 
}
 
 
 
main_stack_base = _estack;
 
/* used by the startup code to populate variables used by the C code */
 
data_lma = LOADADDR(.data);
 
data_vma = ADDR(.data);
 
data_size = SIZEOF(.data);
 
 
 
/* used by the startup code to wipe memory */
 
ccmram_start = ORIGIN(SRAM1);
 
ccmram_end = ORIGIN(SRAM1) + 4;
 
 
 
/* used by the startup code to wipe memory */
 
sram_start = ORIGIN(SRAM1);
 
sram_end = ORIGIN(SRAM1) + LENGTH(SRAM1);
 
_ram_start = sram_start;
 
_ram_end = sram_end;
 
 
 
_codelen = LENGTH(FLASH);
 
_flash_start = ORIGIN(FLASH);
 
_flash_end = ORIGIN(FLASH) + LENGTH(FLASH);
 
 
 
_heap_start = ADDR(.heap);
 
_heap_end = ADDR(.heap) + SIZEOF(.heap);
 
 
 
 
 
 
 
 
 
 
 
/* Define output sections */
 
SECTIONS
 
{
 
  /* The startup code goes first into FLASH */
 
  .isr_vector :
 
  {
 
    . = ALIGN(4);
 
    KEEP(*(.isr_vector)) /* Startup code */
 
    . = ALIGN(4);
 
  } >FLASH
 
 
 
 
 
  .flash2 : ALIGN(512) {
 
    build/firmware_rnc/frozen_mpy.o(.rodata*);
 
    build/firmware_rnc/vendor/secp256k1-zkp/src/secp256k1.o(.rodata*);
 
    . = ALIGN(512);
 
  } >FLASH2 AT>FLASH2
 
 
 
 
 
  /* The program code and other data goes into FLASH */
 
  .text :
 
  {
 
    . = ALIGN(4);
 
    *(.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
 
 
 
  /* Constant data goes into FLASH */
 
  .rodata :
 
  {
 
    . = ALIGN(4);
 
    *(.rodata)         /* .rodata sections (constants, strings, etc.) */
 
    *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
 
    . = ALIGN(4);
 
  } >FLASH2 AT>FLASH2
 
 
 
  .ARM.extab   : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
 
  .ARM : {
 
    __exidx_start = .;
 
    *(.ARM.exidx*)
 
    __exidx_end = .;
 
  } >FLASH
 
 
 
  .preinit_array     :
 
  {
 
    PROVIDE_HIDDEN (__preinit_array_start = .);
 
    KEEP (*(.preinit_array*))
 
    PROVIDE_HIDDEN (__preinit_array_end = .);
 
  } >FLASH
 
  .init_array :
 
  {
 
    PROVIDE_HIDDEN (__init_array_start = .);
 
    KEEP (*(SORT(.init_array.*)))
 
    KEEP (*(.init_array*))
 
    PROVIDE_HIDDEN (__init_array_end = .);
 
  } >FLASH
 
  .fini_array :
 
  {
 
    PROVIDE_HIDDEN (__fini_array_start = .);
 
    KEEP (*(SORT(.fini_array.*)))
 
    KEEP (*(.fini_array*))
 
    PROVIDE_HIDDEN (__fini_array_end = .);
 
  } >FLASH
 
 
 
  /* used by the startup to initialize data */
 
  _sidata = LOADADDR(.data);
 
 
 
  /* Initialized data sections goes into RAM, load LMA copy after code */
 
  .data : 
 
  {
 
    . = 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 */
 
  } >SRAM1 AT> FLASH
 
 
 
  _sidtcmram = LOADADDR(.dtcmram);
 
 
 
  /* DTCMRAM section 
 
  * 
 
  * IMPORTANT NOTE! 
 
  * If initialized variables will be placed in this section, 
 
  * the startup code needs to be modified to copy the init-values.  
 
  */
 
  .dtcmram :
 
  {
 
    . = ALIGN(4);
 
    _sdtcmram = .;       /* create a global symbol at dtcmram start */
 
    *(.dtcmram)
 
    *(.dtcmram*)
 
 
 
    . = ALIGN(4);
 
    _edtcmram = .;       /* create a global symbol at dtcmram end */
 
  } >DTCMRAM AT> FLASH
 
 
 
 _sisram2 = LOADADDR(.sram2);
 
 
 
  /* SRAM2 section 
 
  * 
 
  * IMPORTANT NOTE! 
 
  * If initialized variables will be placed in this section, 
 
  * the startup code needs to be modified to copy the init-values.  
 
  */
 
  .sram2 :
 
  {
 
    . = ALIGN(4);
 
    _ssram2 = .;       /* create a global symbol at sram2 start */
 
    *(.sram2)
 
    *(.sram2*)
 
 
 
    . = ALIGN(4);
 
    _esram2 = .;       /* create a global symbol at sram2 end */
 
  } >SRAM2 AT> FLASH
 
 
 
 
 
  /* 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;
 
  } >SRAM1
 
 
 
 
 
 
 
   .heap : ALIGN(4) {
 
    . = 37K; /* this acts as a build time assertion that at least this much memory is available for heap use */
 
    . = ABSOLUTE(sram_end - 16K); /* this explicitly sets the end of the heap effectively giving the stack at most 16K */
 
  } >SRAM1
 
 
 
  .stack : ALIGN(8) {
 
    . = 4K; /* this acts as a build time assertion that at least this much memory is available for stack use */
 
  } >SRAM1
 
 
 
 
 
 
 
  /* MEMORY_bank1 section, code must be located here explicitly            */
 
  /* Example: extern int foo(void) __attribute__ ((section (".mb1text"))); */
 
  .memory_b1_text :
 
  {
 
    *(.mb1text)        /* .mb1text sections (code) */
 
    *(.mb1text*)       /* .mb1text* sections (code)  */
 
    *(.mb1rodata)      /* read-only data (constants) */
 
    *(.mb1rodata*)
 
  } >MEMORY_B1
 
 
 
  /* Remove information from the standard libraries */
 
  /DISCARD/ :
 
  {
 
    libc.a ( * )
 
    libm.a ( * )
 
    libgcc.a ( * )
 
  }
 

.ARM.attributes 0 : { *(.ARM.attributes) }

}

My startup looks like this:

 .syntax unified
 
  .cpu cortex-m7
 
  .fpu softvfp
 
  .thumb
 
 
 
.global  g_pfnVectors
 
.global  Default_Handler
 
 
 
/* start address for the initialization values of the .data section. 
 
defined in linker script */
 
.word  _sidata
 
/* start address for the .data section. defined in linker script */  
 
.word  _sdata
 
/* end address for the .data section. defined in linker script */
 
.word  _edata
 
/* start address for the .bss section. defined in linker script */
 
.word  _sbss
 
/* end address for the .bss section. defined in linker script */
 
.word  _ebss
 
/* stack used for SystemInit_ExtMemCtl; always internal RAM used */
 
 
 
/**
 
 * @brief  This is the code that gets called when the processor first
 
 *          starts execution following a reset event. Only the absolutely
 
 *          necessary set is performed, after which the application
 
 *          supplied main() routine is called. 
 
 * @param  None
 
 * @retval : None
 
*/
 
 
 
    .section  .text.Reset_Handler
 
  .weak  Reset_Handler
 
  .type  Reset_Handler, %function
 
Reset_Handler:  
 
  ldr   sp, =_estack      /* set stack pointer */
 
 
 
/* Copy the data segment initializers from flash to SRAM */  
 
  movs  r1, #0
 
  b  LoopCopyDataInit
 
 
 
CopyDataInit:
 
  ldr  r3, =_sidata
 
  ldr  r3, [r3, r1]
 
  str  r3, [r0, r1]
 
  adds  r1, r1, #4
 
 
 
LoopCopyDataInit:
 
  ldr  r0, =_sdata
 
  ldr  r3, =_edata
 
  adds  r2, r0, r1
 
  cmp  r2, r3
 
  bcc  CopyDataInit
 
  ldr  r2, =_sbss
 
  b  LoopFillZerobss
 
/* Zero fill the bss segment. */  
 
FillZerobss:
 
  movs  r3, #0
 
  str  r3, [r2], #4
 
 
 
LoopFillZerobss:
 
  ldr  r3, = _ebss
 
  cmp  r2, r3
 
  bcc  FillZerobss
 
 
 
/* Call the clock system intitialization function.*/
 
  bl  SystemInit   
 
/* Call static constructors */
 
 
 
/* Call the application's entry point.*/
 
  bl  main
 
  bx  lr    
 
.size  Reset_Handler, .-Reset_Handler
 

The problem is: The firmware doesn't enter the main function and it jumps somewhere in one of the .c files always doing that. Where is the problem ?

7 REPLIES 7

The formatting of the post is less than helpful.

I'd guess your SystemInit() function sets the wrong vector table address in SCB->VTOR

>>The problem is: The firmware doesn't enter the main function and it jumps somewhere in one of the .c files always doing that. 

That really isn't very illuminating.

Turn off "Run to main()" and step the code in from the Reset_Handler entry point.

The processor isn't going to magically start from a vector table at 0x08040000, you'd have to transfer control there.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Ahmed Tolba
Associate II

When I step through the Reset Handler Assembly code, the first instruction as shown above it moves the stack pointer. At that execution of that instruction, it jumps to one of the source files as a break point is halted in one of these files. I really don't know what's wrong.

When I use the FLASH1 as 0x80000 it works fine, but I need to section the flash memory to start working from that flash address 0x0804000

When I step through the Reset Handler Assembly code, the first instruction as shown above it moves the stack pointer. At that execution of that instruction, it jumps to one of the source files as a break point is halted in one of these files. I really don't know what's wrong.

When I use the FLASH1 as 0x80000 it works fine, but I need to section the flash memory to start working from that flash address 0x0804000

The processor expects to start with a table at 0x08000000, or 0x08100000 in a bank switched mode

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Since it only starts at the mentioned address 0x80000000​ what are the steps that let me erase section 22,23.

For example, I started with address FLASH at 0x08000000. I allocated 768K as Length. Is it possible to erase and write to section 22,23? I tried but it can't be erase, I get write error protection.

There are 25 section headers, starting at offset 0x80c364:
 
Section Headers:
 
 [Nr] Name Type Addr Off Size ES Flg Lk Inf Al
 
 [ 0] NULL 00000000 000000 000000 00 0 0 0
 
 [ 1] .data PROGBITS 20020000 0b0000 000284 00 WA 0 0 8
 
 [ 2] .heap NOBITS 20048a24 1c0288 02f5dc 00 WA 0 0 4
 
 [ 3] .isr_vector PROGBITS 08000000 010000 0001f8 00 A 0 0 1
 
 [ 4] .text PROGBITS 08000200 010200 091bbc 00 AX 0 0 64
 
 [ 5] .rodata PROGBITS 08100000 0c0000 0f31a4 00 A 0 0 16
 
 [ 6] .ARM ARM_EXIDX 08091dbc 0a1dbc 000008 00 AL 4 0 4
 
 [ 7] .dtcmram PROGBITS 20000000 1b31a4 000000 00 W 0 0 1
 
 [ 8] .sram2 PROGBITS 2007c000 1b31a4 000000 00 W 0 0 1
 
 [ 9] .bss NOBITS 20020288 1c0288 02879c 00 WA 0 0 8
 
 [10] .stack NOBITS 20078000 1c0288 001000 00 WA 0 0 8

I would like to erase sectors 10,11. They can't be erased at all.