This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Cortex-M3, initializing heap in DDR before its initialized

Hi
I have been trying to solve problem with a Cortex-M3 in how to configure the scatter file to place my heap/stack in DDR memory. I am writing a bootloader program which will run out of NVM but after start up it will need a large heap space in the DDR. I have been struggling with finding the right directives to put into the scatter file.

I have a mulitproject workspace where startup/cmsis stuff is in one and creates a library and my boot loader is in the other and links the library. Startup must use esram for its stack until the DDR is initialized or any access to DDR will crash the system. No heap needed for startup.

startup_m2sxxx.s configuration wizard allows me to define a stack and heap size which I assume is for the entire bootloader code to use. Not just startup.

Below is my current scatter file and below that is a snippet of the map it creates. This one is locates the HEAP into the DDR memory.

If I add * (HEAP) to the scatter file within the ER_DDR region, the HEAP will be located in the DDR memory space. It looks like the HEAP which is now in the DDR wants to be zeroed. The problem I have with that is when the DDR initializes, the system crashes. I assume that that HEAP is being touched before initialization which is will cause a crash. Locating the HEAP in DDR is the only thing I changed.

I need to start debugging my main design/code and get past this memory initialization.

What am I missing to get the memories placed and used correctly?

LR_IROM1 0x00000000 0x0007FFFF { ; load region size_region ER_RO 0x00000000 0x0007FFFF { ; load address = execution address *.o (RESET, +First) *(InRoot$$Sections) * (+RO) } ER_RW 0x20000000 0xFFFF { ; RW data esram * (+RW +ZI)

} ER_DDR 0xA0000000 0x1FFFFFFF { ; RW data DDR flashdiskio.o (+RW +ZI) bootloader.o (+RW +ZI) mss_uart.o (+RW +ZI) mss_spi.o (+RW +ZI) * (HEAP) }
; ARM_LIB_STACKHEAP +0 EMPTY 0x200000 ; Heap and stack growing towards
; { } ; each other in the same region
}

Execution Region ER_RW (Base: 0x20000000, Size: 0x00001080, Max: 0x0000ffff, ABSOLUTE)

Base Addr Size Type Attr Idx E Section Name Object

0x20000000 0x0000001c Data RW 422 .data M2S050T_MSS_CM3_hw_platform.lib(system_m2sxxx.o) 0x2000001c 0x00000004 Data RW 951 .data c_w.l(heapauxa.o) 0x20000020 0x00000060 Zero RW 696 .bss c_w.l(libspace.o) 0x20000080 0x00001000 Zero RW 504 STACK M2S050T_MSS_CM3_hw_platform.lib(startup_m2sxxx.o)

Execution Region ER_DDR (Base: 0xa0000000, Size: 0x000012e8, Max: 0x1fffffff, ABSOLUTE)

Base Addr Size Type Attr Idx E Section Name Object

0xa0000000 0x00000020 Data RW 99 .data flashdiskio.o 0xa0000020 0x00000078 Data RW 249 .data bootloader.o 0xa0000098 0x00000080 Zero RW 4 .bss mss_uart.o 0xa0000118 0x00000108 Zero RW 68 .bss mss_spi.o 0xa0000220 0x00001000 Zero RW 98 .bss flashdiskio.o 0xa0001220 0x000000c8 Zero RW 247 .bss bootloader.o 0xa00012e8 0x00000000 Zero RW 505 HEAP M2S050T_MSS_CM3_hw_platform.lib(startup_m2sxxx.o)

  • Hi

    This is a follow up to my post. After experimenting some more today, I now see that it is getting past the DDR initialization and finally branching to main().

    The first thing main() does is branch to __scatterload which gets into a loop doing something (__scatterload_null, __scatterload_copy, __scatterload_zeroinit) and it finally ends up stuck in a branch to itself, never getting back to main().

    It looks like this scatterload is zeroing memory and copying/initializing memory but then ends up at this strange place.

    It looks like I almost have this working, sooo close to main().

    Does any one have any ideas as to what this is doing and why it is not succeeding?

    I am using the same scatter file and map as in the post above

    __main:
    0x00000188 F000F802 BL.W __scatterload (0x00000190)
    0x0000018C F000F848 BL.W __rt_entry (0x00000220)

    stuck here: _ZSt9terminatev:
    0x00004632 B508 PUSH {r3,lr}
    0x00004634 4669 MOV r1,sp
    0x00004636 F88D0000 STRB r0,[sp,#0x00]
    0x0000463A 2003 MOVS r0,#0x03
    0x0000463C BEAB BKPT 0xAB
    0x0000463E BD08 POP {r3,pc}

  • Set up whatever stack/heap allocation you want in startup_ARCH.s

    Set where the linker places them in the scatter file.

    Modify the root vector in startup_ARCH.s to point to the TOP of internal SRAM, the processor USES this, NOT initial_sp

    Modify the code in system_ARCH.c and under SystemInit() to initialize your hardware, buses, clocks, memory, etc.

    Reset_Handler should call SystemInit, then __main, the latter is the C runtime start up code, it sets the stack to initial_sp, and jumps to your main(). As you've set the system up in SystemInit(), all memory is available for use, and the runtime can zero out, or copy, the statics.

  • If you uncheck "run to main" can you access the DDR memory via the debugger's memory view?

    Can you code a small routine after you initialize the DDR to do some basic test? ie walking pattern, and verify. Are the clocks all at run-time rates, or at boot-time rates?

    Do you have any code doing printf(), check what OS function is #3 (via SWI/BKPT)

    Are you getting a Hard Fault?

    The static initialization should basically traverse a ROM/FLASH based table, zero regions of memory and copying over others. Observe if it does that, and what DESTINATION addresses are inducing failure.

  • Hi

    I was able to track down what the exception was being caused by I am embarrassed to say. Apparently with all of my back and forth changing the HEAP size I had left it as size 0 but in the scatter file located it in my DDR.

    so it seems the scatterload was doing what it should do, initialize the HEAP but there is none and it get stuck in that exception.

    I suppose that should have raised a warning during link time that the HEAP is size 0 but nothing. It would have save me from myself.

    Once I changed the HEAP to a actually value bigger than 0 everything worked and I could get to my code that is inside of main(). Yea.

    Setting up the scatter file as I mentioned in the post above was the right thing to do for my bootloader. The stack is in esram and the heap in the larger DDR memory. system init only needs to use the stack so the DDR has time to get initialize.

    Thank you for your suggestions and help. I learned a LOT about scatter files this week so far!!

  • Linkers should normally not warn for zero-size segments, because they are sometimes used as place markers - to let runtime code get access to the address of the segment for performing computations. So an empty segment directly after the data segment can be used to compute the size of the data segment and so how large block of RAM that should be initialized.

  • That makes sense. Unfortunately that feature also caused me trouble scatterload. I guess that is what really needs to be looked into.

    Thank you