SAMS70 TCM setup

Go To Last Post
9 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm looking to setup some critical functions to run in ITCM and have my stack and heap in DTCM. All of the application notes only give pieces of the linker script and there isn't a TCM example that I can find in Atmel Studio.

 

Because of the Project needs I need to use the ITCM 64K, DTCM 64K, SRAM 256K configuration. I'd like to know how to put specific source files into the ITCM.

 

Could somebody point me to a complete example linker file?

This topic has a solution.
Last Edited: Thu. Jan 19, 2017 - 03:53 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

For anybody wanting a complete example of using the ITCM and DTCM of the SAME70/SAMS70/SAMV71 devices there is a complete example available in the SAMV71-XULT GNU Software Package 1.5 zip file (not install file) on this page:

http://www.atmel.com/tools/samv7...

 

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,

 

Here is my working example of ITCM and DTCM usage on a SAME70.

 

I use ITCM for the vector table and a lot of fast Code, like FreeRTOS, math routines and Interrupts.

The DTCM is used for all data, there is an additional Segment for 'slow' data pointing to the remainig System Memory.

 

The configuration is 128KByte for ITCM, DTCM and System RAM on a SAME70N21.

 

Hope it helps,

Martin Cibulski

 

 

 

The linker script with modifications:

 

/**

* \file

*

* Copyright (c) 2015 Atmel Corporation. All rights reserved.

*

* \asf_license_start

*

* \page License

*

* 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 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. The name of Atmel may not be used to endorse or promote products derived

* from this software without specific prior written permission.

*

* 4. This software may only be redistributed and used in connection with an

* Atmel microcontroller product.

*

* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED

* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF

* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE

* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL 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.

*

* \asf_license_stop

*

*/

/*------------------------------------------------------------------------------

* Linker script for running in internal FLASH on the ATSAME70Q21

*----------------------------------------------------------------------------*/

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")

OUTPUT_ARCH(arm)

SEARCH_DIR(.)

/* Memory Spaces Definitions */

MEMORY

{

itcm_vectors (rx) : ORIGIN = 0x00000000, LENGTH = 0x00000400 /* Vector table at beginning of ITCM */

itcm (rx) : ORIGIN = 0x00000400, LENGTH = 0x0001FC00 /* Fast code in ITCM */

rom (rx) : ORIGIN = 0x00400000, LENGTH = 0x00200000 /* Remaining Code in Flash Memory */

dtcm (rw) : ORIGIN = 0x20000000, LENGTH = 0x00020000 /* Fast data/bss in DTCM */

ram (rwx) : ORIGIN = 0x20400000, LENGTH = 0x00020000 /* Remaining data/bss in System RAM */

}

/* The stack size used by the application. NOTE: you need to adjust according to your application. */

STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : 0x2000;

__ram_end__ = ORIGIN(ram) + LENGTH(ram) - 4;

/* The heapsize used by the application. NOTE: you need to adjust according to your application. */

HEAP_SIZE = DEFINED(HEAP_SIZE) ? HEAP_SIZE : 0x200;

/* Section Definitions */

SECTIONS

{

.fast_vectors (NOLOAD) :

{

. = ALIGN(4);

_srelocate_vectors = .;

} > itcm_vectors

.fast_code : AT (_etext)

{

. = ALIGN(4);

_s_fast_code = .;

_s_fast_code_from = LOADADDR(.fast_code);

*lib_a*.o (.text.*)

*list.o (.text.*)

*queue.o (.text.*)

*tasks.o (.text.*)

*timers.o (.text.*)

*my_timer.o (.text.*)

*test.o (.text.*)

*(.ramfunc);

_e_fast_code = .;

_e_fast_code_from = LOADADDR(.fast_code) + SIZEOF(.fast_code);

} > itcm

.text :

{

. = ALIGN(4);

_sfixed = .;

KEEP(*(.vectors .vectors.*))

*(.text .text.* .gnu.linkonce.t.*)

*(.glue_7t) *(.glue_7)

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

*(.ARM.extab* .gnu.linkonce.armextab.*)

/* Support C constructors, and C destructors in both user code

and the C library. This also provides support for C++ code. */

. = ALIGN(4);

KEEP(*(.init))

. = ALIGN(4);

__preinit_array_start = .;

KEEP (*(.preinit_array))

__preinit_array_end = .;

. = ALIGN(4);

__init_array_start = .;

KEEP (*(SORT(.init_array.*)))

KEEP (*(.init_array))

__init_array_end = .;

. = ALIGN(0x4);

KEEP (*crtbegin.o(.ctors))

KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))

KEEP (*(SORT(.ctors.*)))

KEEP (*crtend.o(.ctors))

. = ALIGN(4);

KEEP(*(.fini))

. = ALIGN(4);

__fini_array_start = .;

KEEP (*(.fini_array))

KEEP (*(SORT(.fini_array.*)))

__fini_array_end = .;

KEEP (*crtbegin.o(.dtors))

KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))

KEEP (*(SORT(.dtors.*)))

KEEP (*crtend.o(.dtors))

. = ALIGN(4);

_efixed = .; /* End of text section */

} > rom

/* .ARM.exidx is sorted, so has to go in its own output section. */

PROVIDE_HIDDEN (__exidx_start = .);

.ARM.exidx :

{

*(.ARM.exidx* .gnu.linkonce.armexidx.*)

} > rom

PROVIDE_HIDDEN (__exidx_end = .);

. = ALIGN(4);

_etext = .;

/* Slow data segment listed first */

/* Only a few modules are listed here */

/* Uses system memory */

.data : AT (_etext + SIZEOF(.fast_code))

{

. = ALIGN(4);

_s_data = .;

_s_data_from = LOADADDR(.data);

. = ALIGN(4);

_e_data = .;

_e_data_from = LOADADDR(.data) + SIZEOF(.data);

} > ram

/* Slow BSS segment listed first */

/* Only a few modules are listed here */

/* Uses system memory */

.bss (NOLOAD) :

{

. = ALIGN(4);

_s_bss = . ;

_s_zero = .;

. = ALIGN(4);

_e_bss = . ;

_e_zero = .;

} > dtcm

/* Fast data segment takes all remaining */

/* modules, uses the TCM */

.fast_data : AT (_etext + SIZEOF(.fast_code) + SIZEOF(.data))

{

. = ALIGN(4);

_s_fast_data = .;

_s_fast_data_from = LOADADDR(.fast_data);

*(.data .data.*);

. = ALIGN(4);

_e_fast_data = .;

_e_fast_from = LOADADDR(.fast_data) + SIZEOF(.fast_data);

} > dtcm

/* Fast BSS segment takes all remaining */

/* modules, uses the TCM */

.fast_bss (NOLOAD) :

{

. = ALIGN(4);

_s_fast_bss = . ;

_s_fast_zero = .;

*(.bss .bss.*)

*(COMMON)

. = ALIGN(4);

_e_fast_bss = . ;

_e_fast_zero = .;

} > dtcm

/* stack section */

.stack (NOLOAD):

{

. = ALIGN(8);

_s_stack = .;

. = . + STACK_SIZE;

. = ALIGN(8);

_e_stack = .;

} > dtcm

/* heap section */

.heap (NOLOAD):

{

. = ALIGN(8);

_s_heap = .;

. = . + HEAP_SIZE;

. = ALIGN(8);

_e_heap = .;

} > dtcm

. = ALIGN(4);

_end = . ;

_ram_end_ = ORIGIN(ram) + LENGTH(ram) -1 ;

}

 

 

The Startup Code:

 

/**
 * \file
 *
 * Copyright (c) 2015 Atmel Corporation. All rights reserved.
 *
 * \asf_license_start
 *
 * \page License
 *
 * 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 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. The name of Atmel may not be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * 4. This software may only be redistributed and used in connection with an
 *    Atmel microcontroller product.
 *
 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
 *
 * \asf_license_stop
 *
 */
/*
 * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
 */

#include "same70.h"

#if __FPU_USED /* CMSIS defined value to indicate usage of FPU */
#include "fpu.h"
#endif

extern uint32_t _s_fast_code_from;
extern uint32_t _e_fast_code_from;
extern uint32_t _s_fast_code;
extern uint32_t _e_fast_code;

extern uint32_t _s_data;
extern uint32_t _e_data;
extern uint32_t _s_data_from;
extern uint32_t _e_data_from;

extern uint32_t _s_fast_data;
extern uint32_t _e_fast_data;
extern uint32_t _s_fast_data_from;
extern uint32_t _e_fast_data_from;

extern uint32_t _s_bss;
extern uint32_t _e_bss;

extern uint32_t _s_fast_bss;
extern uint32_t _e_fast_bss;

extern uint32_t _s_stack;
extern uint32_t _e_stack;

/** \cond DOXYGEN_SHOULD_SKIP_THIS */
int main(void);
/** \endcond */

void __libc_init_array(void);

/* Default empty handler */
void Dummy_Handler(void);

/* Cortex-M7 core handlers */
void NMI_Handler        ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
//void HardFault_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void MemManage_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void BusFault_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void UsageFault_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void SVC_Handler        ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void DebugMon_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void PendSV_Handler     ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void SysTick_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

/* Peripherals handlers */
void SUPC_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void RSTC_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void RTC_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void RTT_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void WDT_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void PMC_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void EFC_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void UART0_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void UART1_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void PIOA_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void PIOB_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
#ifdef _SAME70_PIOC_INSTANCE_
void PIOC_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
#endif /* _SAME70_PIOC_INSTANCE_ */
void USART0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void USART1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void USART2_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void PIOD_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
#ifdef _SAME70_PIOE_INSTANCE_
void PIOE_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
#endif /* _SAME70_PIOE_INSTANCE_ */
#ifdef _SAME70_HSMCI_INSTANCE_
void HSMCI_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
#endif /* _SAME70_HSMCI_INSTANCE_ */
void TWIHS0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void TWIHS1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void SPI0_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void SSC_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void TC0_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void TC1_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void TC2_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
#ifdef _SAME70_TC1_INSTANCE_
void TC3_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
#endif /* _SAME70_TC1_INSTANCE_ */
#ifdef _SAME70_TC1_INSTANCE_
void TC4_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
#endif /* _SAME70_TC1_INSTANCE_ */
#ifdef _SAME70_TC1_INSTANCE_
void TC5_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
#endif /* _SAME70_TC1_INSTANCE_ */
void AFEC0_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
#ifdef _SAME70_DACC_INSTANCE_
void DACC_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
#endif /* _SAME70_DACC_INSTANCE_ */
void PWM0_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void ICM_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void ACC_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void USBHS_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void MCAN0_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void MCAN1_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void GMAC_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void AFEC1_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
#ifdef _SAME70_TWIHS2_INSTANCE_
void TWIHS2_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
#endif /* _SAME70_TWIHS2_INSTANCE_ */
void SPI1_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void QSPI_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void UART2_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void UART3_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void UART4_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
#ifdef _SAME70_TC2_INSTANCE_
void TC6_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
#endif /* _SAME70_TC2_INSTANCE_ */
#ifdef _SAME70_TC2_INSTANCE_
void TC7_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
#endif /* _SAME70_TC2_INSTANCE_ */
#ifdef _SAME70_TC2_INSTANCE_
void TC8_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
#endif /* _SAME70_TC2_INSTANCE_ */
void TC9_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void TC10_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void TC11_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void AES_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void TRNG_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void XDMAC_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void ISI_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void PWM1_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
#ifdef _SAME70_SDRAMC_INSTANCE_
void SDRAMC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
#endif /* _SAME70_SDRAMC_INSTANCE_ */
void RSWDT_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

/* Exception Table */
__attribute__ ((section(".vectors")))
const DeviceVectors exception_table = {

        /* Configure Initial Stack Pointer, using linker-generated symbols */
        .pvStack = (void*) (&_e_stack),

        .pfnReset_Handler      = (void*) Reset_Handler,
        .pfnNMI_Handler        = (void*) NMI_Handler,
        .pfnHardFault_Handler  = (void*) HardFault_Handler,
        .pfnMemManage_Handler  = (void*) MemManage_Handler,
        .pfnBusFault_Handler   = (void*) BusFault_Handler,
        .pfnUsageFault_Handler = (void*) UsageFault_Handler,
        .pfnReserved1_Handler  = (void*) (0UL),          /* Reserved */
        .pfnReserved2_Handler  = (void*) (0UL),          /* Reserved */
        .pfnReserved3_Handler  = (void*) (0UL),          /* Reserved */
        .pfnReserved4_Handler  = (void*) (0UL),          /* Reserved */
        .pfnSVC_Handler        = (void*) SVC_Handler,
        .pfnDebugMon_Handler   = (void*) DebugMon_Handler,
        .pfnReserved5_Handler  = (void*) (0UL),          /* Reserved */
        .pfnPendSV_Handler     = (void*) PendSV_Handler,
        .pfnSysTick_Handler    = (void*) SysTick_Handler,

        /* Configurable interrupts */
        .pfnSUPC_Handler   = (void*) SUPC_Handler,   /* 0  Supply Controller */
        .pfnRSTC_Handler   = (void*) RSTC_Handler,   /* 1  Reset Controller */
        .pfnRTC_Handler    = (void*) RTC_Handler,    /* 2  Real Time Clock */
        .pfnRTT_Handler    = (void*) RTT_Handler,    /* 3  Real Time Timer */
        .pfnWDT_Handler    = (void*) WDT_Handler,    /* 4  Watchdog Timer */
        .pfnPMC_Handler    = (void*) PMC_Handler,    /* 5  Power Management Controller */
        .pfnEFC_Handler    = (void*) EFC_Handler,    /* 6  Enhanced Embedded Flash Controller */
        .pfnUART0_Handler  = (void*) UART0_Handler,  /* 7  UART 0 */
        .pfnUART1_Handler  = (void*) UART1_Handler,  /* 8  UART 1 */
        .pvReserved9       = (void*) (0UL),          /* 9  Reserved */
        .pfnPIOA_Handler   = (void*) PIOA_Handler,   /* 10 Parallel I/O Controller A */
        .pfnPIOB_Handler   = (void*) PIOB_Handler,   /* 11 Parallel I/O Controller B */
#ifdef _SAME70_PIOC_INSTANCE_
        .pfnPIOC_Handler   = (void*) PIOC_Handler,   /* 12 Parallel I/O Controller C */
#else
        .pvReserved12      = (void*) (0UL),          /* 12 Reserved */
#endif /* _SAME70_PIOC_INSTANCE_ */
        .pfnUSART0_Handler = (void*) USART0_Handler, /* 13 USART 0 */
        .pfnUSART1_Handler = (void*) USART1_Handler, /* 14 USART 1 */
        .pfnUSART2_Handler = (void*) USART2_Handler, /* 15 USART 2 */
        .pfnPIOD_Handler   = (void*) PIOD_Handler,   /* 16 Parallel I/O Controller D */
#ifdef _SAME70_PIOE_INSTANCE_
        .pfnPIOE_Handler   = (void*) PIOE_Handler,   /* 17 Parallel I/O Controller E */
#else
        .pvReserved17      = (void*) (0UL),          /* 17 Reserved */
#endif /* _SAME70_PIOE_INSTANCE_ */
#ifdef _SAME70_HSMCI_INSTANCE_
        .pfnHSMCI_Handler  = (void*) HSMCI_Handler,  /* 18 Multimedia Card Interface */
#else
        .pvReserved18      = (void*) (0UL),          /* 18 Reserved */
#endif /* _SAME70_HSMCI_INSTANCE_ */
        .pfnTWIHS0_Handler = (void*) TWIHS0_Handler, /* 19 Two Wire Interface 0 HS */
        .pfnTWIHS1_Handler = (void*) TWIHS1_Handler, /* 20 Two Wire Interface 1 HS */
        .pfnSPI0_Handler   = (void*) SPI0_Handler,   /* 21 Serial Peripheral Interface 0 */
        .pfnSSC_Handler    = (void*) SSC_Handler,    /* 22 Synchronous Serial Controller */
        .pfnTC0_Handler    = (void*) TC0_Handler,    /* 23 Timer/Counter 0 */
        .pfnTC1_Handler    = (void*) TC1_Handler,    /* 24 Timer/Counter 1 */
        .pfnTC2_Handler    = (void*) TC2_Handler,    /* 25 Timer/Counter 2 */
#ifdef _SAME70_TC1_INSTANCE_
        .pfnTC3_Handler    = (void*) TC3_Handler,    /* 26 Timer/Counter 3 */
#else
        .pvReserved26      = (void*) (0UL),          /* 26 Reserved */
#endif /* _SAME70_TC1_INSTANCE_ */
#ifdef _SAME70_TC1_INSTANCE_
        .pfnTC4_Handler    = (void*) TC4_Handler,    /* 27 Timer/Counter 4 */
#else
        .pvReserved27      = (void*) (0UL),          /* 27 Reserved */
#endif /* _SAME70_TC1_INSTANCE_ */
#ifdef _SAME70_TC1_INSTANCE_
        .pfnTC5_Handler    = (void*) TC5_Handler,    /* 28 Timer/Counter 5 */
#else
        .pvReserved28      = (void*) (0UL),          /* 28 Reserved */
#endif /* _SAME70_TC1_INSTANCE_ */
        .pfnAFEC0_Handler  = (void*) AFEC0_Handler,  /* 29 Analog Front End 0 */
#ifdef _SAME70_DACC_INSTANCE_
        .pfnDACC_Handler   = (void*) DACC_Handler,   /* 30 Digital To Analog Converter */
#else
        .pvReserved30      = (void*) (0UL),          /* 30 Reserved */
#endif /* _SAME70_DACC_INSTANCE_ */
        .pfnPWM0_Handler   = (void*) PWM0_Handler,   /* 31 Pulse Width Modulation 0 */
        .pfnICM_Handler    = (void*) ICM_Handler,    /* 32 Integrity Check Monitor */
        .pfnACC_Handler    = (void*) ACC_Handler,    /* 33 Analog Comparator */
        .pfnUSBHS_Handler  = (void*) USBHS_Handler,  /* 34 USB Host / Device Controller */
        .pfnMCAN0_Handler  = (void*) MCAN0_Handler,  /* 35 MCAN Controller 0 */
        .pvReserved36      = (void*) (0UL),          /* 36 Reserved */
        .pfnMCAN1_Handler  = (void*) MCAN1_Handler,  /* 37 MCAN Controller 1 */
        .pvReserved38      = (void*) (0UL),          /* 38 Reserved */
        .pfnGMAC_Handler   = (void*) GMAC_Handler,   /* 39 Ethernet MAC */
        .pfnAFEC1_Handler  = (void*) AFEC1_Handler,  /* 40 Analog Front End 1 */
#ifdef _SAME70_TWIHS2_INSTANCE_
        .pfnTWIHS2_Handler = (void*) TWIHS2_Handler, /* 41 Two Wire Interface 2 HS */
#else
        .pvReserved41      = (void*) (0UL),          /* 41 Reserved */
#endif /* _SAME70_TWIHS2_INSTANCE_ */
        .pfnSPI1_Handler   = (void*) SPI1_Handler,   /* 42 Serial Peripheral Interface 1 */
        .pfnQSPI_Handler   = (void*) QSPI_Handler,   /* 43 Quad I/O Serial Peripheral Interface */
        .pfnUART2_Handler  = (void*) UART2_Handler,  /* 44 UART 2 */
        .pfnUART3_Handler  = (void*) UART3_Handler,  /* 45 UART 3 */
        .pfnUART4_Handler  = (void*) UART4_Handler,  /* 46 UART 4 */
#ifdef _SAME70_TC2_INSTANCE_
        .pfnTC6_Handler    = (void*) TC6_Handler,    /* 47 Timer/Counter 6 */
#else
        .pvReserved47      = (void*) (0UL),          /* 47 Reserved */
#endif /* _SAME70_TC2_INSTANCE_ */
#ifdef _SAME70_TC2_INSTANCE_
        .pfnTC7_Handler    = (void*) TC7_Handler,    /* 48 Timer/Counter 7 */
#else
        .pvReserved48      = (void*) (0UL),          /* 48 Reserved */
#endif /* _SAME70_TC2_INSTANCE_ */
#ifdef _SAME70_TC2_INSTANCE_
        .pfnTC8_Handler    = (void*) TC8_Handler,    /* 49 Timer/Counter 8 */
#else
        .pvReserved49      = (void*) (0UL),          /* 49 Reserved */
#endif /* _SAME70_TC2_INSTANCE_ */
        .pfnTC9_Handler    = (void*) TC9_Handler,    /* 50 Timer/Counter 9 */
        .pfnTC10_Handler   = (void*) TC10_Handler,   /* 51 Timer/Counter 10 */
        .pfnTC11_Handler   = (void*) TC11_Handler,   /* 52 Timer/Counter 11 */
        .pvReserved53      = (void*) (0UL),          /* 53 Reserved */
        .pvReserved54      = (void*) (0UL),          /* 54 Reserved */
        .pvReserved55      = (void*) (0UL),          /* 55 Reserved */
        .pfnAES_Handler    = (void*) AES_Handler,    /* 56 AES */
        .pfnTRNG_Handler   = (void*) TRNG_Handler,   /* 57 True Random Generator */
        .pfnXDMAC_Handler  = (void*) XDMAC_Handler,  /* 58 DMA */
        .pfnISI_Handler    = (void*) ISI_Handler,    /* 59 Camera Interface */
        .pfnPWM1_Handler   = (void*) PWM1_Handler,   /* 60 Pulse Width Modulation 1 */
        .pvReserved61      = (void*) (0UL),          /* 61 Reserved */
#ifdef _SAME70_SDRAMC_INSTANCE_
        .pfnSDRAMC_Handler = (void*) SDRAMC_Handler, /* 62 SDRAM Controller */
#else
        .pvReserved62      = (void*) (0UL),          /* 62 Reserved */
#endif /* _SAME70_SDRAMC_INSTANCE_ */
        .pfnRSWDT_Handler  = (void*) RSWDT_Handler   /* 63 Reinforced Secure Watchdog Timer */
};

/**
 * \brief This is the code that gets called on processor reset.
 * To initialize the device, and call the main() routine.
 */
void Reset_Handler(void)
{
        uint32_t *pSrc;
        uint32_t *pSrcEnd;
        uint32_t *pDest;
        uint32_t *pDestEnd;

  // Configure TCM with maximum Size
  // 128 KByte Data
  // 128 KByte Program (currently not used)
  //
//#ifdef CONF_USE_DTCM
  EFC->EEFC_FCR = (EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FCMD_GGPB);
  //EFC->EEFC_FCR = (EEFC_FCR_FCMD_GGPB);
  uint32_t ulEEFC_bits = EFC->EEFC_FRR;

  if ((ulEEFC_bits & 0x180) != 0x180)
  {
   EFC->EEFC_FCR = (EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FCMD_SGPB | EEFC_FCR_FARG(7));
   EFC->EEFC_FCR = (EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FCMD_SGPB | EEFC_FCR_FARG(8));

   // Trigger Reset
   RSTC->RSTC_CR = RSTC_CR_PROCRST;
  }

  // Enable DTCM and ITCM
  //
  __DSB();
  __ISB();
  SCB->ITCMCR = (SCB_DTCMCR_EN_Msk | SCB_DTCMCR_RMW_Msk | SCB_DTCMCR_RETEN_Msk);
  SCB->DTCMCR = (SCB_DTCMCR_EN_Msk | SCB_DTCMCR_RMW_Msk | SCB_DTCMCR_RETEN_Msk);
  __DSB();
  __ISB();
//#endif

        // Copy Vector Table to beginning of ITCM (Address 0)
        //
        pSrc  = (uint32_t*)&exception_table;
        pDest  = (uint32_t*)0;
        pDestEnd = (uint32_t*)sizeof (DeviceVectors);

     for (; pDest < pDestEnd;)
  {
      *pDest++ = *pSrc++;
     }

        // Copy fast Code from Flash into ITCM
        //
        pSrc  = &_s_fast_code_from;
        pSrcEnd  = &_e_fast_code_from;
        pDest  = &_s_fast_code;
        pDestEnd = &_e_fast_code;

     for (; pDest < pDestEnd;)
  {
      *pDest++ = *pSrc++;
     }

        // Copy data segments into DTCM and System RAM
  //
  pSrc  = &_s_data_from;
  pSrcEnd  = &_e_data_from;
        pDest  = &_s_data;
        pDestEnd = &_e_data;

     while (pDest < pDestEnd)
  {
      *pDest++ = *pSrc++;
     }

  pSrc  = &_s_fast_data_from;
  pSrcEnd  = &_e_fast_data_from;
        pDest  = &_s_fast_data;
        pDestEnd = &_e_fast_data;

     while (pDest < pDestEnd)
  {
      *pDest++ = *pSrc++;
     }

        // Clear the zero segments in DTCM and System RAM
  //
        pDest  = &_s_bss;
  pDestEnd = &_e_bss;
        while (pDest < pDestEnd)
  {
                *pDest++ = 0;
        }

        pDest  = &_s_fast_bss;
        pDestEnd = &_e_fast_bss;
        while (pDest < pDestEnd)
        {
         *pDest++ = 0;
        }

        // Set the vector table base address
  // to the copied table in ITCM (Address 0)
  //
        pSrc = (uint32_t *) 0;
        SCB->VTOR = ((uint32_t) pSrc & SCB_VTOR_TBLOFF_Msk);

#if __FPU_USED
 fpu_enable();
#endif

        /* Initialize the C library */
        __libc_init_array();

        /* Branch to main function */
        main();

        /* Infinite loop */
        while (1);
}

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You are awesome, thank you! Your code is much easier to follow than what was in the softpack 1.5 example. Got it up and running immediately.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Just a quick word of warning for everyone, my application requires optimization to be set to O3. For whatever reason, the reset handler above would hang (with the program counter going off in the weeds) when it would try copy the vector table from flash to ITCM address 0. I couldn't figure out why, so I simply added an optimization attribute above the reset handler to keep it at 'O0'.

 

__attribute__ ((optimize("O0")))

void Reset_Handler(void)

{

 

...

}

 

Thank you again for posting this martin.c, it's been a huge help and time saver.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I found a few additional issues I thought worthwhile to present:

 

In the Reset_Handler() example above, specifically in the code to set GPNVM bits 8 & 7 to 1 and issue a reset, the line that issues the reset needs updated to include passing in the password key. The micro won't actually reset without it.

//Trigger Reset

RSTC->RSTC_CR = RSTC_CR_KEY_PASSWD | RSTC_CR_PROCRST;

 

In addition, for our application, we have designed in the capabilities to allow for remote updates to the firmware. This is done using variants of the Atmel Applets used on the SAM E70 Xplained board. This code runs out of System SRAM and Flash and requires TCM to be disabled. Therefore, when the loading is complete, it jumps into the reset handler and hangs. This is due to the example code above running everything out of TCM, including the stack. When reset_handler() tries to push to the stack, it tries to write to DTCM that is disabled at the time.

 

Therefore, I came up with a solution to create a "startup stack" of 256 bytes that lives in System SRAM. I also created a new "runtime stack" segment in the linker. Then, reset_handler() will always run out of the System SRAM startup stack. When code execution gets to the end of reset handler, it updates the system stack pointer with the address of the runtime stack in DTCM. It then jumps into main() and continues program execution using the stack in DTCM.

 

I've provided my updates to the linker and startup.c files below. Hopefully this will provide some help to those of you trying to get this up and running.

 

 

Linker:

 

/**

* \file

*

* Copyright (c) 2015 Atmel Corporation. All rights reserved.

*

* \asf_license_start

*

* \page License

*

* 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 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. The name of Atmel may not be used to endorse or promote products derived

* from this software without specific prior written permission.

*

* 4. This software may only be redistributed and used in connection with an

* Atmel microcontroller product.

*

* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED

* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF

* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE

* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL 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.

*

* \asf_license_stop

*

*/

/*------------------------------------------------------------------------------

* Linker script for running in internal FLASH on the ATSAME70Q21

*----------------------------------------------------------------------------*/

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")

OUTPUT_ARCH(arm)

SEARCH_DIR(.)

/* Memory Spaces Definitions */

MEMORY

{

itcm_vectors (rx) : ORIGIN = 0x00000000, LENGTH = 0x00000400 /* Vector table at beginning of ITCM */

itcm (rx) : ORIGIN = 0x00000400, LENGTH = 0x0001FC00 /* Fast code in ITCM */

rom (rx) : ORIGIN = 0x00400000, LENGTH = 0x00200000 /* Remaining Code in Flash Memory */

dtcm (rw) : ORIGIN = 0x20000000, LENGTH = 0x00020000 /* Fast data/bss in DTCM */

ram (rwx) : ORIGIN = 0x20400000, LENGTH = 0x00020000 /* Remaining data/bss in System RAM */

}

/* The stack size used by the application. NOTE: you need to adjust according to your application. */

STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : 0x100;

DTCM_STACK_SIZE = DEFINED(DTCM_STACK_SIZE) ? DTCM_STACK_SIZE : 0x2000;

__ram_end__ = ORIGIN(ram) + LENGTH(ram) - 4;

/* The heapsize used by the application. NOTE: you need to adjust according to your application. */

HEAP_SIZE = DEFINED(HEAP_SIZE) ? HEAP_SIZE : 0x1000;

/* Section Definitions */

SECTIONS

{

.fast_vectors (NOLOAD) :

{

. = ALIGN(4);

_srelocate_vectors = .;

} > itcm_vectors

 

.fast_code : AT (_etext)

{

. = ALIGN(4);

_s_fast_code = .;

_s_fast_code_from = LOADADDR(.fast_code);

*(.itcm_functions);

_e_fast_code = .;

_e_fast_code_from = LOADADDR(.fast_code) + SIZEOF(.fast_code);

} > itcm

 

.text :

{

. = ALIGN(4);

_sfixed = .;

KEEP(*(.vectors .vectors.*))

*(.text .text.* .gnu.linkonce.t.*)

*(.glue_7t) *(.glue_7)

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

*(.ARM.extab* .gnu.linkonce.armextab.*)

/* Support C constructors, and C destructors in both user code

and the C library. This also provides support for C++ code. */

. = ALIGN(4);

KEEP(*(.init))

. = ALIGN(4);

__preinit_array_start = .;

KEEP (*(.preinit_array))

__preinit_array_end = .;

. = ALIGN(4);

__init_array_start = .;

KEEP (*(SORT(.init_array.*)))

KEEP (*(.init_array))

__init_array_end = .;

. = ALIGN(0x4);

KEEP (*crtbegin.o(.ctors))

KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))

KEEP (*(SORT(.ctors.*)))

KEEP (*crtend.o(.ctors))

. = ALIGN(4);

KEEP(*(.fini))

. = ALIGN(4);

__fini_array_start = .;

KEEP (*(.fini_array))

KEEP (*(SORT(.fini_array.*)))

__fini_array_end = .;

KEEP (*crtbegin.o(.dtors))

KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))

KEEP (*(SORT(.dtors.*)))

KEEP (*crtend.o(.dtors))

. = ALIGN(4);

_efixed = .; /* End of text section */

} > rom

 

/* .ARM.exidx is sorted, so has to go in its own output section. */

PROVIDE_HIDDEN (__exidx_start = .);

.ARM.exidx :

{

*(.ARM.exidx* .gnu.linkonce.armexidx.*)

} > rom

PROVIDE_HIDDEN (__exidx_end = .);

. = ALIGN(4);

_etext = .;

 

/* Slow data segment listed first */

/* Only a few modules are listed here */

/* Uses system memory */

.data : AT (_etext + SIZEOF(.fast_code))

{

. = ALIGN(4);

_s_data = .;

_s_data_from = LOADADDR(.data);

. = ALIGN(4);

_e_data = .;

_e_data_from = LOADADDR(.data) + SIZEOF(.data);

} > ram

 

/* Slow BSS segment listed first */

/* Only a few modules are listed here */

/* Uses system memory */

.bss (NOLOAD) :

{

. = ALIGN(4);

_s_bss = . ;

_s_zero = .;

. = ALIGN(4);

_e_bss = . ;

_e_zero = .;

} > dtcm

 

/* Fast data segment takes all remaining */

/* modules, uses the TCM */

.fast_data : AT (_etext + SIZEOF(.fast_code) + SIZEOF(.data))

{

. = ALIGN(4);

_s_fast_data = .;

_s_fast_data_from = LOADADDR(.fast_data);

*(.data .data.*);

. = ALIGN(4);

_e_fast_data = .;

_e_fast_data_from = LOADADDR(.fast_data) + SIZEOF(.fast_data);

} > dtcm

 

/* Fast BSS segment takes all remaining */

/* modules, uses the TCM */

.fast_bss (NOLOAD) :

{

. = ALIGN(4);

_s_fast_bss = . ;

_s_fast_zero = .;

*(.bss .bss.*)

*(COMMON)

. = ALIGN(4);

_e_fast_bss = . ;

_e_fast_zero = .;

} > dtcm

 

/* heap section - needs to be listed before stack since heap grows up in address space*/

.heap (NOLOAD):

{

. = ALIGN(8);

_s_heap = .;

. = . + HEAP_SIZE;

. = ALIGN(8);

_e_heap = .;

} > dtcm

/* startup stack section. Stack needed just for reset_handler, just to get us through operation where we check TCM bits in GPNVM */

.stack (NOLOAD):

{

. = ALIGN(8);

_s_stack = .;

. = . + STACK_SIZE;

. = ALIGN(8);

_e_stack = .;

} > ram

 

.runtime_stack (NOLOAD):

{

. = ALIGN(8);

_s_runtime_stack = .;

. = . + DTCM_STACK_SIZE;

. = ALIGN(8);

_e_runtime_stack = .;

} > dtcm

. = ALIGN(4);

_end = . ;

_ram_end_ = ORIGIN(ram) + LENGTH(ram) -1 ;

}

 

 

 

 

Startup_same70q21.c

 

/*
  * \file
  *
  * Copyright (c) 2015 Atmel Corporation. All rights reserved.
  *
  * \asf_license_start
  *
  * \page License
  *
  * 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 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. The name of Atmel may not be used to endorse or promote products derived
  *    from this software without specific prior written permission.
  *
  * 4. This software may only be redistributed and used in connection with an
  *    Atmel microcontroller product.
  *
  * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
  * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
  *
  * \asf_license_stop
  *
  */
 /*
  * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
  */

#include "same70q21.h"

extern uint32_t _s_fast_code_from;
extern uint32_t _e_fast_code_from;
extern uint32_t _s_fast_code;
extern uint32_t _e_fast_code;

extern uint32_t _s_data;
extern uint32_t _e_data;
extern uint32_t _s_data_from;
extern uint32_t _e_data_from;

extern uint32_t _s_fast_data;
extern uint32_t _e_fast_data;
extern uint32_t _s_fast_data_from;
extern uint32_t _e_fast_data_from;

extern uint32_t _s_bss;
extern uint32_t _e_bss;

extern uint32_t _s_fast_bss;
extern uint32_t _e_fast_bss;

extern uint32_t _s_stack;
extern uint32_t _e_stack;

extern uint32_t _e_runtime_stack;

/** \cond DOXYGEN_SHOULD_SKIP_THIS */
 int main(void);
 /** \endcond */

void __libc_init_array(void);

/* Default empty handler */
 void Dummy_Handler(void);

/* Cortex-M7 core handlers */
 void NMI_Handler        ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void HardFault_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void MemManage_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void BusFault_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void UsageFault_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void SVC_Handler        ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void DebugMon_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void PendSV_Handler     ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void SysTick_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

/* Peripherals handlers */
 void SUPC_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void RSTC_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void RTC_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void RTT_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void WDT_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void PMC_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void EFC_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void UART0_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void UART1_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void PIOA_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void PIOB_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void PIOC_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void USART0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void USART1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void USART2_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void PIOD_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void PIOE_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void HSMCI_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void TWIHS0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void TWIHS1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void SPI0_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void SSC_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void TC0_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void TC1_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void TC2_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void TC3_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void TC4_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void TC5_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void AFEC0_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void DACC_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void PWM0_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void ICM_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void ACC_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void USBHS_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void MCAN0_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void MCAN1_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void GMAC_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void AFEC1_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void TWIHS2_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void SPI1_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void QSPI_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void UART2_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void UART3_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void UART4_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void TC6_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void TC7_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void TC8_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void TC9_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void TC10_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void TC11_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void AES_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void TRNG_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void XDMAC_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void ISI_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void PWM1_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void SDRAMC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void RSWDT_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

/* Exception Table */
 __attribute__ ((section(".vectors")))
 const DeviceVectors exception_table = {

 /* Configure Initial Stack Pointer, using linker-generated symbols */
 .pvStack = (void*) (&_e_stack),

 .pfnReset_Handler      = (void*) Reset_Handler,
 .pfnNMI_Handler        = (void*) NMI_Handler,
 .pfnHardFault_Handler  = (void*) HardFault_Handler,
 .pfnMemManage_Handler  = (void*) MemManage_Handler,
 .pfnBusFault_Handler   = (void*) BusFault_Handler,
 .pfnUsageFault_Handler = (void*) UsageFault_Handler,
 .pfnReserved1_Handler  = (void*) (0UL),          /* Reserved */
 .pfnReserved2_Handler  = (void*) (0UL),          /* Reserved */
 .pfnReserved3_Handler  = (void*) (0UL),          /* Reserved */
 .pfnReserved4_Handler  = (void*) (0UL),          /* Reserved */
 .pfnSVC_Handler        = (void*) SVC_Handler,
 .pfnDebugMon_Handler   = (void*) DebugMon_Handler,
 .pfnReserved5_Handler  = (void*) (0UL),          /* Reserved */
 .pfnPendSV_Handler     = (void*) PendSV_Handler,
 .pfnSysTick_Handler    = (void*) SysTick_Handler,

 /* Configurable interrupts */
 .pfnSUPC_Handler   = (void*) SUPC_Handler,   /* 0  Supply Controller */
 .pfnRSTC_Handler   = (void*) RSTC_Handler,   /* 1  Reset Controller */
 .pfnRTC_Handler    = (void*) RTC_Handler,    /* 2  Real Time Clock */
 .pfnRTT_Handler    = (void*) RTT_Handler,    /* 3  Real Time Timer */
 .pfnWDT_Handler    = (void*) WDT_Handler,    /* 4  Watchdog Timer */
 .pfnPMC_Handler    = (void*) PMC_Handler,    /* 5  Power Management Controller */
 .pfnEFC_Handler    = (void*) EFC_Handler,    /* 6  Enhanced Embedded Flash Controller */
 .pfnUART0_Handler  = (void*) UART0_Handler,  /* 7  UART 0 */
 .pfnUART1_Handler  = (void*) UART1_Handler,  /* 8  UART 1 */
 .pvReserved9       = (void*) (0UL),          /* 9  Reserved */
 .pfnPIOA_Handler   = (void*) PIOA_Handler,   /* 10 Parallel I/O Controller A */
 .pfnPIOB_Handler   = (void*) PIOB_Handler,   /* 11 Parallel I/O Controller B */
 .pfnPIOC_Handler   = (void*) PIOC_Handler,   /* 12 Parallel I/O Controller C */
 .pfnUSART0_Handler = (void*) USART0_Handler, /* 13 USART 0 */
 .pfnUSART1_Handler = (void*) USART1_Handler, /* 14 USART 1 */
 .pfnUSART2_Handler = (void*) USART2_Handler, /* 15 USART 2 */
 .pfnPIOD_Handler   = (void*) PIOD_Handler,   /* 16 Parallel I/O Controller D */
 .pfnPIOE_Handler   = (void*) PIOE_Handler,   /* 17 Parallel I/O Controller E */
 .pfnHSMCI_Handler  = (void*) HSMCI_Handler,  /* 18 Multimedia Card Interface */
 .pfnTWIHS0_Handler = (void*) TWIHS0_Handler, /* 19 Two Wire Interface 0 HS */
 .pfnTWIHS1_Handler = (void*) TWIHS1_Handler, /* 20 Two Wire Interface 1 HS */
 .pfnSPI0_Handler   = (void*) SPI0_Handler,   /* 21 Serial Peripheral Interface 0 */
 .pfnSSC_Handler    = (void*) SSC_Handler,    /* 22 Synchronous Serial Controller */
 .pfnTC0_Handler    = (void*) TC0_Handler,    /* 23 Timer/Counter 0 */
 .pfnTC1_Handler    = (void*) TC1_Handler,    /* 24 Timer/Counter 1 */
 .pfnTC2_Handler    = (void*) TC2_Handler,    /* 25 Timer/Counter 2 */
 .pfnTC3_Handler    = (void*) TC3_Handler,    /* 26 Timer/Counter 3 */
 .pfnTC4_Handler    = (void*) TC4_Handler,    /* 27 Timer/Counter 4 */
 .pfnTC5_Handler    = (void*) TC5_Handler,    /* 28 Timer/Counter 5 */
 .pfnAFEC0_Handler  = (void*) AFEC0_Handler,  /* 29 Analog Front End 0 */
 .pfnDACC_Handler   = (void*) DACC_Handler,   /* 30 Digital To Analog Converter */
 .pfnPWM0_Handler   = (void*) PWM0_Handler,   /* 31 Pulse Width Modulation 0 */
 .pfnICM_Handler    = (void*) ICM_Handler,    /* 32 Integrity Check Monitor */
 .pfnACC_Handler    = (void*) ACC_Handler,    /* 33 Analog Comparator */
 .pfnUSBHS_Handler  = (void*) USBHS_Handler,  /* 34 USB Host / Device Controller */
 .pfnMCAN0_Handler  = (void*) MCAN0_Handler,  /* 35 MCAN Controller 0 */
 .pvReserved36      = (void*) (0UL),          /* 36 Reserved */
 .pfnMCAN1_Handler  = (void*) MCAN1_Handler,  /* 37 MCAN Controller 1 */
 .pvReserved38      = (void*) (0UL),          /* 38 Reserved */
 .pfnGMAC_Handler   = (void*) GMAC_Handler,   /* 39 Ethernet MAC */
 .pfnAFEC1_Handler  = (void*) AFEC1_Handler,  /* 40 Analog Front End 1 */
 .pfnTWIHS2_Handler = (void*) TWIHS2_Handler, /* 41 Two Wire Interface 2 HS */
 .pfnSPI1_Handler   = (void*) SPI1_Handler,   /* 42 Serial Peripheral Interface 1 */
 .pfnQSPI_Handler   = (void*) QSPI_Handler,   /* 43 Quad I/O Serial Peripheral Interface */
 .pfnUART2_Handler  = (void*) UART2_Handler,  /* 44 UART 2 */
 .pfnUART3_Handler  = (void*) UART3_Handler,  /* 45 UART 3 */
 .pfnUART4_Handler  = (void*) UART4_Handler,  /* 46 UART 4 */
 .pfnTC6_Handler    = (void*) TC6_Handler,    /* 47 Timer/Counter 6 */
 .pfnTC7_Handler    = (void*) TC7_Handler,    /* 48 Timer/Counter 7 */
 .pfnTC8_Handler    = (void*) TC8_Handler,    /* 49 Timer/Counter 8 */
 .pfnTC9_Handler    = (void*) TC9_Handler,    /* 50 Timer/Counter 9 */
 .pfnTC10_Handler   = (void*) TC10_Handler,   /* 51 Timer/Counter 10 */
 .pfnTC11_Handler   = (void*) TC11_Handler,   /* 52 Timer/Counter 11 */
 .pvReserved53      = (void*) (0UL),          /* 53 Reserved */
 .pvReserved54      = (void*) (0UL),          /* 54 Reserved */
 .pvReserved55      = (void*) (0UL),          /* 55 Reserved */
 .pfnAES_Handler    = (void*) AES_Handler,    /* 56 AES */
 .pfnTRNG_Handler   = (void*) TRNG_Handler,   /* 57 True Random Generator */
 .pfnXDMAC_Handler  = (void*) XDMAC_Handler,  /* 58 DMA */
 .pfnISI_Handler    = (void*) ISI_Handler,    /* 59 Camera Interface */
 .pfnPWM1_Handler   = (void*) PWM1_Handler,   /* 60 Pulse Width Modulation 1 */
 .pvReserved61      = (void*) (0UL),          /* 61 Reserved */
 .pfnSDRAMC_Handler = (void*) SDRAMC_Handler, /* 62 SDRAM Controller */
 .pfnRSWDT_Handler  = (void*) RSWDT_Handler   /* 63 Reinforced Secure Watchdog Timer */
 };

/**
  * \brief This is the code that gets called on processor reset.
  * To initialize the device, and call the main() routine.

  *  With the compiler optimization set to O3, this Reset_Handler
  *   funciton would hang when it gets to the section of code where it copies the vector
  *   table to beginning of ITCM (Address 0)
  */
 __attribute__ ((optimize("O0")))
void Reset_Handler(void)
{
 uint32_t *pSrc;
 uint32_t *pSrcEnd;
 uint32_t *pDest;
 uint32_t *pDestEnd;
 uint32_t ulEEFC_bits;
 uint32_t dtcm_stack_pointer_addr;

 // Configure TCM with maximum Size
 // 128 KByte Data
 // 128 KByte Program

 __DSB();
 __ISB();
 EFC->EEFC_FCR = (EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FCMD_GGPB);
 __DSB();
 __ISB();
 
 while (!(EFC->EEFC_FSR & EEFC_FSR_FRDY));      //Wait until the status falls to 0 (EFFC command is complete)

 ulEEFC_bits = EFC->EEFC_FRR;

 if ((ulEEFC_bits & 0x180) != 0x180)
 {
  __DSB();
  __ISB();
  EFC->EEFC_FCR = (EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FCMD_SGPB | EEFC_FCR_FARG(7));  //issue command to clear bit 7
  __DSB();
  __ISB();

  while(!(EFC->EEFC_FSR & EEFC_FSR_FRDY));     //Wait until the status falls to 0 (EFFC command is complete)

  __DSB();
  __ISB();
  EFC->EEFC_FCR = (EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FCMD_SGPB | EEFC_FCR_FARG(8));  //issue command to clear bit 8
  __DSB();
  __ISB();

  while(!(EFC->EEFC_FSR & EEFC_FSR_FRDY));     //Wait until the status falls to 0 (EFFC command is complete)

  __DSB();
  __ISB();

  //Trigger Reset
  RSTC->RSTC_CR = RSTC_CR_KEY_PASSWD | RSTC_CR_PROCRST;

  __DSB();
  __ISB();
 }

 // Enable DTCM and ITCM
 __DSB();
 __ISB();
 SCB->ITCMCR = (SCB_DTCMCR_EN_Msk | SCB_DTCMCR_RMW_Msk | SCB_DTCMCR_RETEN_Msk);
 SCB->DTCMCR = (SCB_DTCMCR_EN_Msk | SCB_DTCMCR_RMW_Msk | SCB_DTCMCR_RETEN_Msk);
 __DSB();
 __ISB();

 // Copy Vector Table to beginning of ITCM (Address 0)
 pSrc  = (uint32_t*)&exception_table;
 pDest  = (uint32_t*)0;
 pDestEnd = (uint32_t*)sizeof (DeviceVectors);

 for (; pDest < pDestEnd;)
 {
  *pDest++ = *pSrc++;
 }

 // Copy fast Code from Flash into ITCM
 pSrc  = &_s_fast_code_from;
 pSrcEnd  = &_e_fast_code_from;
 pDest  = &_s_fast_code;
 pDestEnd = &_e_fast_code;

 for (; pDest < pDestEnd;)
 {
  *pDest++ = *pSrc++;
 }

 // Copy data segments into DTCM and System RAM
 pSrc  = &_s_data_from;
 pSrcEnd  = &_e_data_from;
 pDest  = &_s_data;
 pDestEnd = &_e_data;

 while (pDest < pDestEnd)
 {
  *pDest++ = *pSrc++;
 }

 pSrc  = &_s_fast_data_from;
 pSrcEnd  = &_e_fast_data_from;
 pDest  = &_s_fast_data;
 pDestEnd = &_e_fast_data;

 while (pDest < pDestEnd)
 {
  *pDest++ = *pSrc++;
 }

    // Clear the zero segments in DTCM and System RAM
 pDest  = &_s_bss;
 pDestEnd = &_e_bss;
 while (pDest < pDestEnd)
 {
  *pDest++ = 0;
 }

 pDest  = &_s_fast_bss;
 pDestEnd = &_e_fast_bss;
 while (pDest < pDestEnd)
 {
  *pDest++ = 0;
 }

 // Set the vector table base address
 // to the copied table in ITCM (Address 0)
 pSrc = (uint32_t *) 0;

 SCB->VTOR = ((uint32_t) pSrc & SCB_VTOR_TBLOFF_Msk);

 //Now that we're at the point in this routine where we don't need any stack variables,
 //update our stack pointer to the runtime stack pointer that lives in DTCM
 dtcm_stack_pointer_addr = (uint32_t)&_e_runtime_stack;

 //asm(code : output operand list : input operand list : clobber list);
 __ASM volatile ("mov.w r1, %0"::"r" (dtcm_stack_pointer_addr):"r1");    //write r1 with the address of DTCM where the beginning of the stack lives (per the linker)
 __ASM volatile("mov sp, r1");              //update the stack pointer with the stack address that lives in r1

 __DSB();
 __ISB();

 /* Initialize the C library */
 __libc_init_array(); 

 /* Branch to main function */
 main();

 /* Infinite loop */
 while (1);
 }

/**
* \brief Default interrupt handler for unused IRQs.
*/
void Dummy_Handler(void)
{
    while (1)
 {
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks agporsch. I was having trouble with release builds until I forced Reset_Handler() to get O0.

It makes me wonder what about the code is falling over because of this, though. I tried making more of the locals (like the loop variables) volatile, but that didn’t help.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello. There was a problem loading the data into DTCM.

 

linker script:

 

/*------------------------------------------------------------------------------
 *      Linker script for running in internal FLASH on the ATSAME70Q21
 *----------------------------------------------------------------------------*/

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
SEARCH_DIR(.)

/* Memory Spaces Definitions */
MEMORY
{
  itcm (rwx) : ORIGIN = 0x00000000, LENGTH = 0x00008000
  dtcm (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000
  rom (rx)  : ORIGIN = 0x00400000, LENGTH = 0x00200000
  ram (rwx) : ORIGIN = 0x20400000, LENGTH = 0x00060000
  sdram (rwxa) : ORIGIN = 0x70000000, LENGTH = 0x00200000
}

/* The stack size used by the application. NOTE: you need to adjust according to your application. */
STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : 0x2000;
__ram_end__ = ORIGIN(ram) + LENGTH(ram) - 4;

/*SDRAM*/
__sdram_end__ = ORIGIN(sdram) + LENGTH(sdram) - 4;

/* The heapsize used by the application. NOTE: you need to adjust according to your application. */
HEAP_SIZE = DEFINED(HEAP_SIZE) ? HEAP_SIZE : 0x1000;

/* Section Definitions */
SECTIONS
{
    .text :
    {
        . = ALIGN(4);
        _sfixed = .;
        KEEP(*(.vectors .vectors.*))
        *(.text .text.* .gnu.linkonce.t.*)
        *(.glue_7t) *(.glue_7)
        *(.rodata .rodata* .gnu.linkonce.r.*)
        *(.ARM.extab* .gnu.linkonce.armextab.*)

        /* Support C constructors, and C destructors in both user code
           and the C library. This also provides support for C++ code. */
        . = ALIGN(4);
        KEEP(*(.init))
        . = ALIGN(4);
        __preinit_array_start = .;
        KEEP (*(.preinit_array))
        __preinit_array_end = .;

        . = ALIGN(4);
        __init_array_start = .;
        KEEP (*(SORT(.init_array.*)))
        KEEP (*(.init_array))
        __init_array_end = .;

        . = ALIGN(0x4);
        KEEP (*crtbegin.o(.ctors))
        KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
        KEEP (*(SORT(.ctors.*)))
        KEEP (*crtend.o(.ctors))

        . = ALIGN(4);
        KEEP(*(.fini))

        . = ALIGN(4);
        __fini_array_start = .;
        KEEP (*(.fini_array))
        KEEP (*(SORT(.fini_array.*)))
        __fini_array_end = .;

        KEEP (*crtbegin.o(.dtors))
        KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
        KEEP (*(SORT(.dtors.*)))
        KEEP (*crtend.o(.dtors))

        . = ALIGN(4);
        _efixed = .;            /* End of text section */
    } > rom

    /* .ARM.exidx is sorted, so has to go in its own output section.  */
    PROVIDE_HIDDEN (__exidx_start = .);
    .ARM.exidx :
    {
      *(.ARM.exidx* .gnu.linkonce.armexidx.*)
    } > rom
    PROVIDE_HIDDEN (__exidx_end = .);

    . = ALIGN(4);
    _etext = .;

    .relocate : AT (_etext)
    {
        . = ALIGN(4);
        _srelocate = .;
        *(.ramfunc .ramfunc.*);
        *(.data .data.*);
        . = ALIGN(4);
        _erelocate = .;
    } > ram

    /* .bss section which is used for uninitialized data */
    .bss (NOLOAD) :
    {
        . = ALIGN(4);
        _sbss = . ;
        _szero = .;
        *(.bss .bss.*)
        *(COMMON)
        . = ALIGN(4);
        _ebss = . ;
        _ezero = .;
    } > ram

    /* stack section */
    .stack (NOLOAD):
    {
        . = ALIGN(8);
        _sstack = .;
        . = . + STACK_SIZE;
        . = ALIGN(8);
        _estack = .;
    } > ram

    /* heap section */
    .heap (NOLOAD):
    {
        . = ALIGN(8);
         _sheap = .;
        . = . + HEAP_SIZE;
        . = ALIGN(8);
        _eheap = .;
    } > ram

 .data_sdram ORIGIN(sdram) :
 {
  . = ALIGN(4);
  PROVIDE(_data_sdram = .);
  *(.data_sdram)
  . = ALIGN(8);
  PROVIDE(_edata_sdram = .);
 } >sdram

    . = ALIGN(4);
    _end = . ;
    _ram_end_ = ORIGIN(ram) + LENGTH(ram) -1 ;
 _sdram_end_ = ORIGIN(sdram) + LENGTH(sdram) -1 ;
}

SECTIONS
{
    _itcm_lma = _end;
    .code_TCM :
    AT ( _itcm_lma )
    {
        _sitcm = .; *(.code_TCM); _eitcm = .;
    } > itcm

    .data_TCM :
    {
        _sdtcm = .; *(.data_TCM); _edtcm = .;
    } > dtcm

    .DTCM_stack :
    {
        . = ALIGN(8);
        _sdtcm_stack = .;
        . += STACK_SIZE;
        _edtcm_stack = .;
    } > dtcm
}

location of variables:

 

__attribute__((__section__(".data_TCM")))  static float  Ia_buf[Sampls];
__attribute__((__section__(".data_TCM")))  static float  Ib_buf[Sampls];
__attribute__((__section__(".data_TCM")))  static float  Ic_buf[Sampls];
__attribute__((__section__(".data_TCM")))  static float  I0_buf[Sampls];
__attribute__((__section__(".data_TCM")))  static float  Ua_buf[Sampls];
__attribute__((__section__(".data_TCM")))  static float  Ub_buf[Sampls];
__attribute__((__section__(".data_TCM")))  static float  Uc_buf[Sampls];
__attribute__((__section__(".data_TCM")))  static float  U0_buf[Sampls];

What did I do wrong?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Should the section that copies the vector table to ITCM from SRAM

// Copy Vector Table to beginning of ITCM (Address 0)
pSrc  = (uint32_t*)&exception_table;
pDest  = (uint32_t*)0;
pDestEnd = (uint32_t*)sizeof(DeviceVectors);

for(; pDest < pDestEnd;)
{
    *pDest++ = *pSrc++;
}

actually be

// Copy Vector Table to beginning of ITCM (Address 0)
pSrc  = (uint32_t*)&exception_table;
pDest  = (uint32_t*)0;
pDestEnd = (uint32_t*)(sizeof(exception_table)/sizeof(DeviceVectors));

for(; pDest < pDestEnd;)
{
    *pDest++ = *pSrc++;
}

 

Is it better to store the vector table in instruction TCM (ITCM) than data TCM (DTCM)?

 

 

Last Edited: Fri. Dec 8, 2017 - 12:29 PM