infineon4engineers Facebook

infineon@google+ Google+

infineon@linkedin linkedin

infineon4engi@twitter twitter

infineon@youtube youtube

+ Reply to Thread
Results 1 to 7 of 7

Thread: Execute all code from RAM

  1. #1
    New Member New Member jay is on a distinguished road
    Join Date
    Aug 2017
    Posts
    3
    Points
    40

    Execute all code from RAM

    Hey everyone,
    I'm a new XMC1100 user, and I'm trying to modify my linker script in DAVE to put all code in RAM. I modified the ".text" section to look like the ".ram_code" section, however, my program is restarting at the __copy_data branch instruction. I suspect I need to keep this startup code in text, but move everything else.

    Does anyone have a linker script that loads all code into RAM, and then executes from there instead of flash?

    I'm trying to get power consumption down, and I realized the memory capacity on this XMC1100 part is "backwards" — it has 16K of RAM, and 8K of flash :-)

    Thanks! Excited to get started with XMC!

  2. #2
    Advanced Advanced aurixuser is on a distinguished road
    Join Date
    Jan 2017
    Location
    China
    Posts
    167
    Points
    870
    XMC1100 has a cortex M0 core.

    It will always start from Flash. If you would run the code in the RAM, you need to move the code into RAM and jump to it. Remember to remap the vector map.

    Do you have an external storage device on your board. If not your code size is limited by the ROM size.

  3. #3
    New Member New Member jay is on a distinguished road
    Join Date
    Aug 2017
    Posts
    3
    Points
    40
    Quote Originally Posted by aurixuser View Post
    XMC1100 has a cortex M0 core. It will always start from Flash. If you would run the code in the RAM, you need to move the code into RAM and jump to it. Remember to remap the vector map.
    Yes, I understand all this. But what are the specific changes I need to make to the linker file and startup file to implement this?

    Quote Originally Posted by aurixuser View Post
    Do you have an external storage device on your board. If not your code size is limited by the ROM size.
    No external storage, but everything fits fine in flash and RAM. It's a tiny little program.

  4. #4
    Advanced Advanced aurixuser is on a distinguished road
    Join Date
    Jan 2017
    Location
    China
    Posts
    167
    Points
    870
    Split your program into two parts: a bootloader and an application. Each program occupy different space in the flash, and the two programs will generate two .hex files. You flash the two or a merged one into the flash.

    The bootloader will load your application code from flash into RAM , remap the vector table, then jump to it.

  5. #5
    New Member New Member rst is on a distinguished road
    Join Date
    Nov 2016
    Posts
    12
    Points
    149.375
    Quote Originally Posted by jay View Post
    Yes, I understand all this. But what are the specific changes I need to make to the linker file and startup file to implement this?
    I do not know how to do this in DAVE, but in IAR (for example) you just need to specify the prefix __ramfunc for the target function. Startup-code will copy it into RAM and just need to call it.
    I think that in DAVE it is done similarly.

  6. #6
    New Member New Member jay is on a distinguished road
    Join Date
    Aug 2017
    Posts
    3
    Points
    40
    Quote Originally Posted by aurixuser View Post
    Split your program into two parts: a bootloader and an application. [...] The bootloader will load your application code from flash into RAM , remap the vector table, then jump to it.
    Sure, but that's a ton of work. Why on earth doesn't someone just have a linker file that does this? Why reinvent the wheel?

    Other platforms I've worked on have included example projects / linker files / start-up scripts for doing stuff like this. Given the fact that the XMC1100 has no intelligent flash prefetching and has to wait-state for anything above an 8 MHz clock — and then combine that with the fact that these parts have a whopping 16 KB of RAM — I feel like this would be super common for this platform. And you're telling me I have to write a freaking bootloader from scratch just to do this? That seems insane.

    Quote Originally Posted by rst View Post
    I do not know how to do this in DAVE, but in IAR (for example) you just need to specify the prefix __ramfunc for the target function.
    Yeah, sure, as I mentioned in my original post, there's a ".ram_code" section; I can explicitly decorate all of my functions, plus all of the DAVE code-gen functions, plus all the peripheral library functions... but that's a ton of work, and the moment I re-generate my code, it will all get erased.

    Does Infineon monitor these forums? I posted this topic 4 days ago — sort of expected to get more official feedback by now.

    Like I said, super new to Infineon / XMC stuff, and obviously this forum, too. Thanks for the help!

  7. #7
    New Member New Member
    Infineon Employee
    Infineon Employee
    RSKearney is on a distinguished road
    Join Date
    Nov 2011
    Posts
    2
    Points
    30
    Hi,
    I only checked the .map file and did not execute this as I do not have the device XMC1100-T016F0008.

    Please replace your linker_script.ld file with this:

    /**
    * @file XMC1100x0008.ld
    * @date 2017-04-20
    *
    * @cond
    ************************************************** ************************************************** *****************
    * Linker file for the GNU C Compiler v1.11
    * Supported devices: XMC1100-T016F0008
    * XMC1100-Q024F0008
    *
    * Copyright (c) 2015-2017, Infineon Technologies AG
    * All rights reserved.
    *
    * Redistribution and use in source and binary forms, with or without modification,are permitted provided that the
    * following conditions are met:
    *
    * Redistributions of source code must retain the above copyright notice, this list of conditions and the following
    * disclaimer.
    *
    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
    * disclaimer in the documentation and/or other materials provided with the distribution.
    *
    * Neither the name of the copyright holders nor the names of its contributors may be used to endorse or promote
    * products derived from this software without specific prior written permission.
    *
    * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
    * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
    * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
    * WHETHER IN CONTRACT, STRICT LIABILITY,OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    *
    * To improve the quality of the software, users are encouraged to share modifications, enhancements or bug fixes with
    * Infineon Technologies AG dave@infineon.com).
    ************************************************** ************************************************** *****************
    *
    * Change History
    * --------------
    *
    * 2015-07-07:
    * - Product splitting
    * - Copyright notice update
    *
    * 2015-11-24:
    * - Compatibility with GCC 4.9 2015q2
    *
    * 2016-03-15:
    * - Add assertion to check that region SRAM_combined does not overflowed no_init section
    *
    * 2016-10-28:
    * - Fix linker not complaining if sum of data + text sections is bigger that physical FLASH size
    *
    * 2017-04-07:
    * - Added new symbols __text_size and eText
    *
    * 2017-04-20:
    * - Change vtable location to flash area to save ram
    *
    * @endcond
    *
    */

    OUTPUT_FORMAT("elf32-littlearm")
    OUTPUT_ARCH(arm)
    ENTRY(Reset_Handler)

    MEMORY
    {
    FLASH(RX) : ORIGIN = 0x10001000, LENGTH = 0x2000
    SRAM(!RX) : ORIGIN = 0x20000000, LENGTH = 0x4000
    }

    stack_size = DEFINED(stack_size) ? stack_size : 1024;
    no_init_size = 4;

    SECTIONS
    {
    /* TEXT section */

    .text :
    {
    sText = .;
    KEEP(*(.reset));
    /* M0 always executes from Flash after reset.*/
    /* Only load necessary startup code here*/
    *(.text.SystemInit .text.SystemCoreSetup .text.SystemCoreClockSetup .text.SystemCoreClockUpdate .gnu.linkonce.t.*);

    /* C++ Support */
    KEEP(*(.init))
    KEEP(*(.fini))

    /* .ctors */
    *crtbegin.o(.ctors)
    *crtbegin?.o(.ctors)
    *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
    *(SORT(.ctors.*))
    *(.ctors)

    /* .dtors */
    *crtbegin.o(.dtors)
    *crtbegin?.o(.dtors)
    *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
    *(SORT(.dtors.*))
    *(.dtors)

    *(.rodata .rodata.*)
    *(.gnu.linkonce.r*)

    *(vtable)

    . = ALIGN(4);
    } > FLASH

    .eh_frame_hdr : ALIGN (4)
    {
    KEEP (*(.eh_frame_hdr))
    } > FLASH

    .eh_frame : ALIGN (4)
    {
    KEEP (*(.eh_frame))
    } > FLASH

    /* Exception handling, exidx needs a dedicated section */
    .ARM.extab : ALIGN(4)
    {
    *(.ARM.extab* .gnu.linkonce.armextab.*)
    } > FLASH

    . = ALIGN(4);
    __exidx_start = .;
    .ARM.exidx : ALIGN(4)
    {
    *(.ARM.exidx* .gnu.linkonce.armexidx.*)
    } > FLASH
    __exidx_end = .;
    . = ALIGN(4);

    /* DSRAM layout (Lowest to highest)*/
    /* Veneer <-> Stack <-> DATA <-> BSS <-> HEAP */

    .VENEER_Code ABSOLUTE(0x2000000C):
    {
    . = ALIGN(4); /* section size must be multiply of 4. See startup.S file */
    VeneerStart = .;
    KEEP(*(.XmcVeneerCode));
    . = ALIGN(4); /* section size must be multiply of 4. See startup.S file */
    VeneerEnd = .;
    } > SRAM AT > FLASH
    eROData = LOADADDR (.VENEER_Code);
    VeneerSize = ABSOLUTE(VeneerEnd) - ABSOLUTE(VeneerStart);

    /* Dummy section for stack */
    Stack (NOLOAD) : AT(0)
    {
    . = ALIGN(8);
    . = . + stack_size;
    __initial_sp = .;
    } > SRAM

    /* Standard DATA and user defined DATA/BSS/CONST sections */
    .data :
    {
    . = ALIGN(4); /* section size must be multiply of 4. See startup.S file */
    __data_start = .;
    * (.data);
    * (.data*);
    *(*.data);
    *(.gnu.linkonce.d*)

    . = ALIGN(4);
    /* preinit data */
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP(*(.preinit_array))
    PROVIDE_HIDDEN (__preinit_array_end = .);

    . = ALIGN(4);
    /* init data */
    PROVIDE_HIDDEN (__init_array_start = .);
    KEEP(*(SORT(.init_array.*)))
    KEEP(*(.init_array))
    PROVIDE_HIDDEN (__init_array_end = .);


    . = ALIGN(4);
    /* finit data */
    PROVIDE_HIDDEN (__fini_array_start = .);
    KEEP(*(SORT(.fini_array.*)))
    KEEP(*(.fini_array))
    PROVIDE_HIDDEN (__fini_array_end = .);

    . = ALIGN(4); /* section size must be multiply of 4. See startup.S file */
    __data_end = .;
    } > SRAM AT > FLASH
    DataLoadAddr = LOADADDR (.data);
    __data_size = __data_end - __data_start;

    .ram_code :
    {
    . = ALIGN(4); /* section size must be multiply of 4. See startup.S file */
    __ram_code_start = .;
    /* functions with __attribute__ ((section (".ram_code")))*/
    *(.ram_code)
    /* All Default text code goes here */
    *(.text .text.*)
    . = ALIGN(4); /* section size must be multiply of 4. See startup.S file */
    __ram_code_end = .;
    } > SRAM AT > FLASH
    __ram_code_load = LOADADDR (.ram_code);
    __ram_code_size = __ram_code_end - __ram_code_start;

    __text_size = (__exidx_end - sText) + VeneerSize + __data_size + __ram_code_size;
    eText = sText + __text_size;

    /* BSS section */
    .bss (NOLOAD) :
    {
    . = ALIGN(4); /* section size must be multiply of 4. See startup.S file */
    __bss_start = .;
    * (.bss);
    * (.bss*);
    * (COMMON);
    *(.gnu.linkonce.b*)
    . = ALIGN(4); /* section size must be multiply of 4. See startup.S file */
    __bss_end = .;
    . = ALIGN(8);
    Heap_Bank1_Start = .;
    } > SRAM
    __bss_size = __bss_end - __bss_start;

    /* .no_init section contains SystemCoreClock. See system.c file */
    .no_init ORIGIN(SRAM) + LENGTH(SRAM) - no_init_size (NOLOAD) :
    {
    Heap_Bank1_End = .;
    * (.no_init);
    } > SRAM

    /* Heap - Bank1*/
    Heap_Bank1_Size = Heap_Bank1_End - Heap_Bank1_Start;

    ASSERT(Heap_Bank1_Start <= Heap_Bank1_End, "region SRAM overflowed no_init section")

    /DISCARD/ :
    {
    *(.comment)
    }

    .stab 0 (NOLOAD) : { *(.stab) }
    .stabstr 0 (NOLOAD) : { *(.stabstr) }

    /* DWARF 1 */
    .debug 0 : { *(.debug) }
    .line 0 : { *(.line) }

    /* GNU DWARF 1 extensions */
    .debug_srcinfo 0 : { *(.debug_srcinfo) }
    .debug_sfnames 0 : { *(.debug_sfnames) }

    /* DWARF 1.1 and DWARF 2 */
    .debug_aranges 0 : { *(.debug_aranges) }
    .debug_pubnames 0 : { *(.debug_pubnames) }
    .debug_pubtypes 0 : { *(.debug_pubtypes) }

    /* DWARF 2 */
    .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
    .debug_abbrev 0 : { *(.debug_abbrev) }
    .debug_line 0 : { *(.debug_line) }
    .debug_frame 0 : { *(.debug_frame) }
    .debug_str 0 : { *(.debug_str) }
    .debug_loc 0 : { *(.debug_loc) }
    .debug_macinfo 0 : { *(.debug_macinfo) }

    /* DWARF 2.1 */
    .debug_ranges 0 : { *(.debug_ranges) }

    /* SGI/MIPS DWARF 2 extensions */
    .debug_weaknames 0 : { *(.debug_weaknames) }
    .debug_funcnames 0 : { *(.debug_funcnames) }
    .debug_typenames 0 : { *(.debug_typenames) }
    .debug_varnames 0 : { *(.debug_varnames) }

    /* Build attributes */
    .build_attributes 0 : { *(.ARM.attributes) }
    }
    The views expressed here are my personal opinions, have not been reviewed or authorized by Infineon and do not necessarily represent the views of Infineon.

+ Reply to Thread

Tags for this Thread

Disclaimer

All content and materials on this site are provided “as is“. Infineon makes no warranties or representations with regard to this content and these materials of any kind, whether express or implied, including without limitation, warranties or representations of merchantability, fitness for a particular purpose, title and non-infringement of any third party intellectual property right. No license, whether express or implied, is granted by Infineon. Use of the information on this site may require a license from a third party, or a license from Infineon.


Infineon accepts no liability for the content and materials on this site being accurate, complete or up- to-date or for the contents of external links. Infineon distances itself expressly from the contents of the linked pages, over the structure of which Infineon has no control.


Content on this site may contain or be subject to specific guidelines or limitations on use. All postings and use of the content on this site are subject to the Usage Terms of the site; third parties using this content agree to abide by any limitations or guidelines and to comply with the Usage Terms of this site. Infineon reserves the right to make corrections, deletions, modifications, enhancements, improvements and other changes to the content and materials, its products, programs and services at any time or to move or discontinue any content, products, programs, or services without notice.