Using newlib's malloc in an ARM Cortex-M3

前端 未结 1 1833
刺人心
刺人心 2021-01-31 00:04

I\'m creating code for an ARM Cortex-M3 (NXP\'s LCP17xx). I\'ve been using static memory up to now and everything worked well. I tried to add dynamic memory support, but once I

1条回答
  •  予麋鹿
    予麋鹿 (楼主)
    2021-01-31 00:27

    So, after some 10 hours spent debugging this, I have finally made it work. The problem was in the linker script. However, it was not in the bss section that I had posted, but in the text and data section. Here's the script that works.

    OUTPUT_FORMAT("elf32-littlearm")
    OUTPUT_ARCH(arm)
    ENTRY(_startup)
    
    MEMORY
    {
        rom (rx)  : ORIGIN = 0x00000000, LENGTH = 512K
        ram (rwx) : ORIGIN = 0x10000000, LENGTH =  32K
    }
    
    /* Define the top our stack at the end of SRAM */
    _end_stack = 0x10008000;
    
    EXTERN(__interrupt_vector_table);
    
    SECTIONS
    {
        .text :
        {
            /* Insert the interrupt vector table first */
            __interrupt_vector_table = .;
            *(.interrupt_vector_table)
            /* Startup assembly */
            *(.startup)
            /* Rest of the code (C) */
            *(.text) *(.text.*) *(.glue_7) *(.glue_7t)
            *(.vfp11_veneer)
            *(.ARM.extab* .gnu.linkonce.armextab.*)
            *(.rodata) *(.rodata.*)
            . = ALIGN(8);
            _end_text = .;
            _start_datai = .;
        } >rom
    
        .data :
        {
            _start_data = .;
            *(vtable)
            *(.data) *(.data.*)
            . = ALIGN (8);
            _end_data = .;
        } >ram AT >rom
    
        .data_init : { _end_datai = .; } >rom
    
        __exidx_start = .;
        .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > rom
        __exidx_end = .;
    
        .bss :
        {
            _start_bss = .;
            *(.bss)
            *(COMMON)
        } >ram 
    
        . = ALIGN(4);
        _end_bss = .;
        . = ALIGN(256);
    
        _start_heap = .;
        PROVIDE( __cs3_heap_start = _start_heap);
    
        /* Linker wants .eh_frame section defined because of gcc 4.4.X bug,
         * just discard it here. */
        /DISCARD/ : { *(.eh_*) }
    }
    
    _end = .;
    PROVIDE(end = .);
    

    I also had to add some variable initialization to my init code:

    extern unsigned int _start_data;
    extern unsigned int _end_data;
    extern unsigned int _start_datai;
    extern unsigned int _end_datai;
    
    void init(void) {
    
        // (...) Other stuff
    
        // Initialize Global Variables
        uint32_t* data_begin  = (uint32_t*) &_start_data;
        uint32_t* data_end    = (uint32_t*) &_end_data;
        uint32_t* datai_begin = (uint32_t*) &_start_datai;
        uint32_t* datai_end   = (uint32_t*) &_end_datai;
        while(data_begin < data_end)
        {
            *data_begin = *datai_begin;
            data_begin++;
            datai_begin++;
        }
    

    These two pages were quite helpful, although it still took me a lot to understand what was going on: http://fun-tech.se/stm32/linker/index.php and http://e2e.ti.com/support/microcontrollers/stellaris_arm_cortex-m3_microcontroller/f/473/t/44452.aspx?pi23648=1

    I hope this might be useful to somebody else experiencing the same problems I was experiencing.

    0 讨论(0)
提交回复
热议问题