This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

How to implement mbed uVisor on NRF52832

I would like to implement the mbed uVisor on the NRF52832 SoC with the softdevice s132. So I created the configuration files and wrote some code.

Now I have problems with the linker:

Link: uvisor_example2
./BUILD/NRF52_DK/GCC_ARM/.link_script.ld:178 cannot move location counter backwards (from 000000002001a260 to 000000002000f800)
collect2: error: ld returned 1 exit status
[ERROR] ./BUILD/NRF52_DK/GCC_ARM/.link_script.ld:178 cannot move location counter backwards (from 000000002001a260 to 000000002000f800)
collect2: error: ld returned 1 exit status

in "link_script.ld" ln177 ff:
(177)        ASSERT(. <= (ORIGIN(RAM) + LENGTH(RAM) - 0x800), "heap region overflowed into stack");
(178)        . += (ORIGIN(RAM) + LENGTH(RAM) - 0x800) - .;

Can anybody help, to solve this problem?

  • NRF52832.ld:

    /*
     * Copyright (c) 2015 ARM Limited
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *     www.apache.org/.../LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /* Linker script to configure memory regions. */
    
    MEMORY
    {
      FLASH (rx) : ORIGIN = 0x1C000, LENGTH = 0x64000
      RAM (rwx) :  ORIGIN = 0x20004000, LENGTH = 0xC000
    }
    
    
    OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
    
    /* Linker script to place sections and symbol values. Should be used together
     * with the other linker script that defines memory regions FLASH and RAM.
     * It references the following symbols that must be defined in code:
     *   Reset_Handler : Entry of reset handler
     *
     * It defines the following symbols that the code can use without definition:
     *   __exidx_start
     *   __exidx_end
     *   __etext
     *   __data_start__
     *   __preinit_array_start
     *   __preinit_array_end
     *   __init_array_start
     *   __init_array_end
     *   __fini_array_start
     *   __fini_array_end
     *   __data_end__
     *   __bss_start__
     *   __bss_end__
     *   __end__
     *   end
     *   __HeapLimit
     *   __StackLimit
     *   __StackTop
     *   __stack
     */
    ENTRY(Reset_Handler)
    
    /* Heap 1/4 of ram and stack 1/8 */
    __stack_size__ = 0x2000;
    __heap_size__ = 0x4000;
    
    HEAP_SIZE  = DEFINED(__heap_size__)  ? __heap_size__  : 0x0400;
    STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x0400;
    
    SECTIONS
    {
    /*----------------------------------------*
     *             FLASH                      *
     *----------------------------------------*/
    
        /* Note: The uVisor expects this section at a fixed location, as specified
                 by the porting process configuration parameter: FLASH_OFFSET. */
        __UVISOR_TEXT_OFFSET = 0x0;
        __UVISOR_TEXT_START = ORIGIN(FLASH) + __UVISOR_TEXT_OFFSET;
        .text __UVISOR_TEXT_START :
        {
    	/* uVisor code and data */
            . = ALIGN(4);
            __uvisor_main_start = .;
            *(.uvisor.main)
            __uvisor_main_end = .;
            
    	KEEP(*(.Vectors))
            *(.text*)
    
            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*)
    
            KEEP(*(.eh_frame*))
        } > FLASH
    
        .ARM.extab :
        {
            *(.ARM.extab* .gnu.linkonce.armextab.*)
            . = ALIGN(4);
        } > FLASH
    
        __exidx_start = .;
        .ARM.exidx :
        {
            *(.ARM.exidx* .gnu.linkonce.armexidx.*)
            . = ALIGN(4);
        } > FLASH
        __exidx_end = .;
    
    /*----------------------------------------*
     *               UVISOR                   *
     *----------------------------------------*/
        /* ensure that uvisor bss is at the beginning of memory */
        /* Note: The uVisor expects this section at a fixed location, as specified by
         * the porting process configuration parameter: SRAM_OFFSET. */
        __UVISOR_SRAM_OFFSET = 0x0;
        __UVISOR_BSS_START = ORIGIN(RAM) + __UVISOR_SRAM_OFFSET;
        .uvisor.bss __UVISOR_BSS_START (NOLOAD):
        {
            . = ALIGN(32);
            __uvisor_bss_start = .;
    
            /* protected uvisor main bss */
            . = ALIGN(32);
            __uvisor_bss_main_start = .;
            KEEP(*(.keep.uvisor.bss.main))
            . = ALIGN(32);
            __uvisor_bss_main_end = .;
    
            /* protected uvisor secure boxes bss */
            . = ALIGN(32);
            __uvisor_bss_boxes_start = .;
            KEEP(*(.keep.uvisor.bss.boxes))
            . = ALIGN(32);
            __uvisor_bss_boxes_end = .;
    
            . = ALIGN((1 << LOG2CEIL(LENGTH(RAM))) / 8);
            __uvisor_bss_end = .;
        } > RAM
    
        /* Heap space for the page allocator */
        .page_heap (NOLOAD) :
        {
            . = ALIGN(32);
            __uvisor_page_start = .;
            KEEP(*(.keep.uvisor.page_heap))
            . = ALIGN(32);
            __uvisor_page_end = .;
        } > RAM
    
        .data :
        {
            PROVIDE(__etext = LOADADDR(.data));
            . = ALIGN(4);
            __data_start__ = .;
            *(vtable)
            *(.data)
            *(.data*)
    
            . = ALIGN(4);
            /* preinit data */
            PROVIDE (__preinit_array_start = .);
            KEEP(*(.preinit_array))
            PROVIDE (__preinit_array_end = .);
    
            . = ALIGN(4);
            /* init data */
            PROVIDE (__init_array_start = .);
            KEEP(*(SORT(.init_array.*)))
            KEEP(*(.init_array))
            PROVIDE (__init_array_end = .);
    
    
            . = ALIGN(4);
            /* finit data */
            PROVIDE (__fini_array_start = .);
            KEEP(*(SORT(.fini_array.*)))
            KEEP(*(.fini_array))
            PROVIDE (__fini_array_end = .);
    
            . = ALIGN(4);
            /* All data end */
            __data_end__ = .;
    
        } > RAM AT > FLASH
    
        /* uvisor configuration data */
        .uvisor.secure :
        {
            . = ALIGN(32);
            __uvisor_secure_start = .;
    
            /* uvisor secure boxes configuration tables */
            . = ALIGN(32);
            __uvisor_cfgtbl_start = .;
            KEEP(*(.keep.uvisor.cfgtbl))
            . = ALIGN(32);
            __uvisor_cfgtbl_end = .;
    
            __uvisor_cfgtbl_ptr_start = .;
            KEEP(*(.keep.uvisor.cfgtbl_ptr_first))
            KEEP(*(.keep.uvisor.cfgtbl_ptr))
            __uvisor_cfgtbl_ptr_end = .;
    
            /* Pointers to all boxes register gateways. These are grouped here to allow
             * discoverability and firmware verification. */
            __uvisor_register_gateway_ptr_start = .;
            KEEP(*(.keep.uvisor.register_gateway_ptr))
            __uvisor_register_gateway_ptr_end = .;
    
            . = ALIGN(32);
            __uvisor_secure_end = .;
        } > FLASH
    
    /*----------------------------------------*
     *          RAM from before UVISOR        *
     *----------------------------------------*/
     
        __etext = .;
    
        .data : AT (__etext)
        {
            __data_start__ = .;
            *(vtable)
            *(.data*)
    
            . = 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);
            PROVIDE(__start_fs_data = .);
            KEEP(*(.fs_data))
            PROVIDE(__stop_fs_data = .);
            
            *(.jcr)
            . = ALIGN(4);
            /* All data end */
            __data_end__ = .;
    
        } > RAM
    
        __edata = .;
    
        .noinit :
        {
          PROVIDE(__start_noinit = .);
          KEEP(*(.noinit))
          PROVIDE(__stop_noinit = .);
        } > RAM
        
       
        .bss :
        {
            . = ALIGN(4);
            __bss_start__ = .;
            *(.bss*)
            *(COMMON)
            . = ALIGN(4);
            __bss_end__ = .;
        } > RAM
    
    /* Note: The uVisor requires the original heap start and end addresses to be provided. */
        
        .heap (NOLOAD):
        {
            . = ALIGN(8);
            __end__ = .;
            end = .;
            __uvisor_heap_start = .;
            __HeapBase = .;
            . += HEAP_SIZE;
            __HeapLimit = .;
            __uvisor_heap_end = .;
            *(.heap*);
    
            /* Expand the heap to reach the stack boundary. */
            ASSERT(. <= (ORIGIN(RAM) + LENGTH(RAM) - 0x800), "heap region overflowed into stack");
            . += (ORIGIN(RAM) + LENGTH(RAM) - 0x800) - .;
        } > RAM
        PROVIDE(__heap_start = ADDR(.heap));
        PROVIDE(__heap_size = SIZEOF(.heap));
        PROVIDE(__mbed_sbrk_start = ADDR(.heap));
        PROVIDE(__mbed_krbs_start = ADDR(.heap) + SIZEOF(.heap));
    
        /* .stack_dummy section does not contain any symbols. It is only
         * used for the linker script to calculate the size of stack sections
         * and assign values to stack symbols later. */
        .stack (NOLOAD):
        {
            __StackLimit = .;
            *(.stack*)
            . += (ORIGIN(RAM) + LENGTH(RAM) - .);
        } > RAM
    
        /* Set the stack top to the end of RAM and move down the stack limit by
         * the size of the stack_dummy section. */
        __StackTop = ORIGIN(RAM) + LENGTH(RAM);
        __StackLimit = __StackTop - SIZEOF(.stack);
        PROVIDE(__stack = __StackTop);
    
    /*----------------------------------------------------*
     *        UVISOR RAM limits check                     *
     *----------------------------------------------------*/
       /* Check if data + heap + stack exceeds RAM limit */
        ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
        /* Provide physical memory boundaries for uVisor. */
        __uvisor_flash_start = ORIGIN(FLASH);
        __uvisor_flash_end = ORIGIN(FLASH) + LENGTH(FLASH);
        __uvisor_sram_start = ORIGIN(RAM);
        __uvisor_sram_end = ORIGIN(RAM) + LENGTH(RAM);
    
    }
    
    /***************************************************************************************************/
    

    startup_NRF52832.S:

    /* 
     * Copyright (c) 2013 Nordic Semiconductor ASA
     * All rights reserved.
     * 
     * Redistribution and use in source and binary forms, with or without modification,
     * are permitted provided that the following conditions are met:
     * 
     *   1. Redistributions of source code must retain the above copyright notice, this list 
     *      of conditions and the following disclaimer.
     *
     *   2. Redistributions in binary form, except as embedded into a Nordic Semiconductor ASA 
     *      integrated circuit in a product or a software update for such product, 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.
     *
     *   3. Neither the name of Nordic Semiconductor ASA nor the names of its contributors may be 
     *      used to endorse or promote products derived from this software without specific prior 
     *      written permission.
     *
     *   4. This software, with or without modification, must only be used with a 
     *      Nordic Semiconductor ASA integrated circuit.
     *
     *   5. Any software provided in binary or object form under this license must not be reverse 
     *      engineered, decompiled, modified and/or disassembled. 
     * 
     * 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.
     * 
     */
    
    
    /*
    NOTE: Template files (including this one) are application specific and therefore
    expected to be copied into the application project folder prior to its use!
    */
    
        .syntax unified
        .arch armv7e-m
    
        .section .Vectors
        .align 2
        .globl __Vectors
    __Vectors:
        .long   __StackTop                  /* Top of Stack */
        .long   Reset_Handler
        .long   NMI_Handler
        .long   HardFault_Handler
        .long   MemoryManagement_Handler
        .long   BusFault_Handler
        .long   UsageFault_Handler
        .long   0                           /*Reserved */
        .long   0                           /*Reserved */
        .long   0                           /*Reserved */
        .long   0                           /*Reserved */
        .long   SVC_Handler
        .long   0                           /*Reserved */
        .long   0                           /*Reserved */
        .long   PendSV_Handler
        .long   SysTick_Handler
    
      /* External Interrupts */
        .long   POWER_CLOCK_IRQHandler
        .long   RADIO_IRQHandler
        .long   UARTE0_UART0_IRQHandler_v
        .long   SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler_v
        .long   SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler_v
        .long   NFCT_IRQHandler_v
        .long   GPIOTE_IRQHandler_v
        .long   SAADC_IRQHandler_v
        .long   TIMER0_IRQHandler_v
        .long   TIMER1_IRQHandler_v
        .long   TIMER2_IRQHandler_v
        .long   RTC0_IRQHandler
        .long   TEMP_IRQHandler_v
        .long   RNG_IRQHandler
        .long   ECB_IRQHandler
        .long   CCM_AAR_IRQHandler
        .long   WDT_IRQHandler_v
        .long   RTC1_IRQHandler_v
        .long   QDEC_IRQHandler_v
        .long   COMP_LPCOMP_IRQHandler_v
        .long   SWI0_EGU0_IRQHandler_v
        .long   SWI1_EGU1_IRQHandler_v
        .long   SWI2_EGU2_IRQHandler_v
        .long   SWI3_EGU3_IRQHandler_v
        .long   SWI4_EGU4_IRQHandler
        .long   SWI5_EGU5_IRQHandler
        .long   TIMER3_IRQHandler_v
        .long   TIMER4_IRQHandler_v
        .long   PWM0_IRQHandler_v
        .long   PDM_IRQHandler_v
        .long   0                           /*Reserved */
        .long   0                           /*Reserved */
        .long   MWU_IRQHandler
        .long   PWM1_IRQHandler_v
        .long   PWM2_IRQHandler_v
        .long   SPIM2_SPIS2_SPI2_IRQHandler_v
        .long   RTC2_IRQHandler_v
        .long   I2S_IRQHandler_v
        .long   FPU_IRQHandler_v
    
    
        .size    __Vectors, . - __Vectors
    
    /* Reset Handler */
    
        .text
        .thumb
        .thumb_func
        .align 1
        .globl    Reset_Handler
        .type    Reset_Handler, %function
    Reset_Handler:
        .fnstart
    
    
    /*     Loop to copy data from read only memory to RAM. The ranges
     *      of copy from/to are specified by following symbols evaluated in
     *      linker script.
     *      __etext: End of code section, i.e., begin of data sections to copy from.
     *      __data_start__/__data_end__: RAM address range that data should be
     *      copied to. Both must be aligned to 4 bytes boundary.  */
    
        ldr    r1, =__etext
        ldr    r2, =__data_start__
        ldr    r3, =__data_end__
    
        subs    r3, r2
        ble     .LC0
    
    .LC1:
        subs    r3, 4
        ldr    r0, [r1,r3]
        str    r0, [r2,r3]
        bgt    .LC1
    .LC0:
    
        LDR     R0, =SystemInit
        BLX     R0
    #if defined(FEATURE_UVISOR) && defined(TARGET_UVISOR_SUPPORTED)
        LDR	    R0, =uvisor_init    /* [*] Insert this. */
        BLX     R0                  /* [*] Insert this. */
    #endif /* defined(FEATURE_UVISOR) && defined(TARGET_UVISOR_SUPPORTED) */
        LDR     R0, =nrf_reloc_vector_table
        BLX     R0
        LDR     R0, =_start
        BX      R0
    
        .pool
        .cantunwind
        .fnend
        .size   Reset_Handler,.-Reset_Handler
    
        .section ".text"
    
    
    /* Dummy Exception Handlers (infinite loops which can be modified) */
    
        .weak   NMI_Handler
        .type   NMI_Handler, %function
    NMI_Handler:
        B       .
        .size   NMI_Handler, . - NMI_Handler
    
    
        .weak   HardFault_Handler
        .type   HardFault_Handler, %function
    HardFault_Handler:
        B       .
        .size   HardFault_Handler, . - HardFault_Handler
    
    
        .weak   MemoryManagement_Handler
        .type   MemoryManagement_Handler, %function
    MemoryManagement_Handler:
        B       .
        .size   MemoryManagement_Handler, . - MemoryManagement_Handler
    
    
        .weak   BusFault_Handler
        .type   BusFault_Handler, %function
    BusFault_Handler:
        B       .
        .size   BusFault_Handler, . - BusFault_Handler
    
    
        .weak   UsageFault_Handler
        .type   UsageFault_Handler, %function
    UsageFault_Handler:
        B       .
        .size   UsageFault_Handler, . - UsageFault_Handler
    
    
        .weak   SVC_Handler
        .type   SVC_Handler, %function
    SVC_Handler:
        B       .
        .size   SVC_Handler, . - SVC_Handler
    
    
        .weak   PendSV_Handler
        .type   PendSV_Handler, %function
    PendSV_Handler:
        B       .
        .size   PendSV_Handler, . - PendSV_Handler
    
    
        .weak   SysTick_Handler
        .type   SysTick_Handler, %function
    SysTick_Handler:
        B       .
        .size   SysTick_Handler, . - SysTick_Handler
    
    
    /* IRQ Handlers */
    
        .globl  Default_Handler
        .type   Default_Handler, %function
    Default_Handler:
        B       .
        .size   Default_Handler, . - Default_Handler
    
        .macro  IRQ handler
        .weak   \handler
        .set    \handler, Default_Handler
        .endm
    
        IRQ  POWER_CLOCK_IRQHandler                          /* restricted */
        IRQ  RADIO_IRQHandler                                /* blocked    */
        IRQ  UARTE0_UART0_IRQHandler_v
        IRQ  SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler_v
        IRQ  SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler_v
        IRQ  NFCT_IRQHandler_v
        IRQ  GPIOTE_IRQHandler_v
        IRQ  SAADC_IRQHandler_v
        IRQ  TIMER0_IRQHandler_v
        IRQ  TIMER1_IRQHandler_v
        IRQ  TIMER2_IRQHandler_v
        IRQ  RTC0_IRQHandler                                 /* blocked    */
        IRQ  TEMP_IRQHandler_v
        IRQ  RNG_IRQHandler                                  /* restricted */
        IRQ  ECB_IRQHandler                                  /* restricted */
        IRQ  CCM_AAR_IRQHandler                              /* blocked    */
        IRQ  WDT_IRQHandler_v
        IRQ  RTC1_IRQHandler_v
        IRQ  QDEC_IRQHandler_v
        IRQ  COMP_LPCOMP_IRQHandler_v
        IRQ  SWI0_EGU0_IRQHandler_v
        IRQ  SWI1_EGU1_IRQHandler_v                          /* restricted for Radio Notification */
        IRQ  SWI2_EGU2_IRQHandler_v                          /* blocked for SoftDevice Event */
        IRQ  SWI3_EGU3_IRQHandler_v
        IRQ  SWI4_EGU4_IRQHandler                            /* blocked    */
        IRQ  SWI5_EGU5_IRQHandler                            /* blocked    */
        IRQ  TIMER3_IRQHandler_v
        IRQ  TIMER4_IRQHandler_v
        IRQ  PWM0_IRQHandler_v
        IRQ  PDM_IRQHandler_v
        IRQ  MWU_IRQHandler                                  /* restricted */
        IRQ  PWM1_IRQHandler_v
        IRQ  PWM2_IRQHandler_v
        IRQ  SPIM2_SPIS2_SPI2_IRQHandler_v
        IRQ  RTC2_IRQHandler_v
        IRQ  I2S_IRQHandler_v
        IRQ  FPU_IRQHandler_v
        
      .end
    
  • Sounds like your heap size is too big. Do you need 16 kB of heap?

Related