This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

LP-AM263: AM263 linker and startup file examples for external application

Part Number: LP-AM263

Hello!

I'd like to know how to properly configure startup sequence, link and boot the application, that is getting loaded into the RAM trough the communication interface (UART, ETH, etc...)

For my usecase I want to implement my custom bootloader so that allows me to load an application directly to the ram and jump into application entry point.

I changed the linker and moved my app's entry point to 0x701B0000 so I can load the hello world app from that address. The "hello world" application boots and works, but it crashes once it triggers an interrupt.

For my understanding something goes wrong with vector tables and I can't find the information how to properly configure them. Please guide me how to configure startup sequence and setup vector tables for my case.

Looking forward for reply

/* This is the stack that is used by code running within main()
 * In case of NORTOS,
 * - This means all the code outside of ISR uses this stack
 * In case of FreeRTOS
 * - This means all the code until vTaskStartScheduler() is called in main()
 *   uses this stack.
 * - After vTaskStartScheduler() each task created in FreeRTOS has its own stack
 */
--stack_size=16384
/* This is the heap size for malloc() API in NORTOS and FreeRTOS
 * This is also the heap used by pvPortMalloc in FreeRTOS
 */
--heap_size=32768
-e_vectors  /* This is the entry of the application, _vector MUST be plabed starting address 0x0 */

/* This is the size of stack when R5 is in IRQ mode
 * In NORTOS,
 * - Here interrupt nesting is enabled
 * - This is the stack used by ISRs registered as type IRQ
 * In FreeRTOS,
 * - Here interrupt nesting is enabled
 * - This is stack that is used initally when a IRQ is received
 * - But then the mode is switched to SVC mode and SVC stack is used for all user ISR callbacks
 * - Hence in FreeRTOS, IRQ stack size is less and SVC stack size is more
 */
__IRQ_STACK_SIZE = 256;
/* This is the size of stack when R5 is in IRQ mode
 * - In both NORTOS and FreeRTOS nesting is disabled for FIQ
 */
__FIQ_STACK_SIZE = 256;
__SVC_STACK_SIZE = 4096; /* This is the size of stack when R5 is in SVC mode */
__ABORT_STACK_SIZE = 256;  /* This is the size of stack when R5 is in ABORT mode */
__UNDEFINED_STACK_SIZE = 256;  /* This is the size of stack when R5 is in UNDEF mode */

SECTIONS
{
    /* This has the R5F boot code until MPU is enabled,  this MUST be at a address < 0x80000000
     * i.e this cannot be placed in DDR
     */
    GROUP {
    	.vectors:{} palign(8)
        .text.hwi: palign(8)
        .text.cache: palign(8)
        .text.mpu: palign(8)
        .text.boot: palign(8)
        .text:abort: palign(8) /* this helps in loading symbols when using XIP mode */
        .text:   {} palign(8)   /* This is where code resides */
        .rodata: {} palign(8)   /* This is where const's go */

        .data:   {} palign(8)   /* This is where initialized globals and static go */
        .bss:    {} palign(8)   /* This is where uninitialized globals go */
        RUN_START(__BSS_START)
        RUN_END(__BSS_END)
        .sysmem: {} palign(8)   /* This is where the malloc heap goes */
        .stack:  {} palign(8)   /* This is where the main() stack goes */
        .irqstack: {. = . + __IRQ_STACK_SIZE;} align(8)
        RUN_START(__IRQ_STACK_START)
        RUN_END(__IRQ_STACK_END)
        .fiqstack: {. = . + __FIQ_STACK_SIZE;} align(8)
        RUN_START(__FIQ_STACK_START)
        RUN_END(__FIQ_STACK_END)
        .svcstack: {. = . + __SVC_STACK_SIZE;} align(8)
        RUN_START(__SVC_STACK_START)
        RUN_END(__SVC_STACK_END)
        .abortstack: {. = . + __ABORT_STACK_SIZE;} align(8)
        RUN_START(__ABORT_STACK_START)
        RUN_END(__ABORT_STACK_END)
        .undefinedstack: {. = . + __UNDEFINED_STACK_SIZE;} align(8)
        RUN_START(__UNDEFINED_STACK_START)
        RUN_END(__UNDEFINED_STACK_END)
        .ARM.exidx:  {} palign(8)   /* Needed for C++ exception handling */
        .init_array: {} palign(8)   /* Contains function pointers called before main */
        .fini_array: {} palign(8)   /* Contains function pointers called after main */
    } > OCRAM

}

MEMORY
{
    /*R5F_VECS  : ORIGIN = 0x701B0000 , LENGTH = 0x00000040*/
    /*R5F_TCMA  : ORIGIN = 0x00000040 , LENGTH = 0x00007FC0*/
    /*R5F_TCMB  : ORIGIN = 0x00080000 , LENGTH = 0x00008000*/

    /* when using multi-core application's i.e more than one R5F/M4F active, make sure
     * this memory does not overlap with other R5F's
     */

    OCRAM     : ORIGIN = 0x701B0000 , LENGTH = 0x40000

    /* This section can be used to put XIP section of the application in flash, make sure this does not overlap with
     * other CPUs. Also make sure to add a MPU entry for this section and mark it as cached and code executable
     */
    FLASH     : ORIGIN = 0x60100000 , LENGTH = 0x80000


    }

  • Hi Artem,

    The AM263x bootloading is a two step process: The ROM bootloading (RBL), Secondary bootloading (SBL), then the application program (appImage). Please refer to the following URL for details: 

    AM263x MCU+ SDK: Understanding the bootflow and bootloaders (ti.com)

    The SBL_QSPI is the main one to focus on.

    If you are more concern about the linker command file for the appImage, the any of the example (like hello_world, empty etc.) in the MCU+ SDK can be a good reference.

    Best regards,

    Ming

  • Hello, 

    I need to skip ROM and SBL sequence since it's not possible to change the QSPI flash content or trigger a warm reset. 

    For my case I need to load temporary application into the RAM section and jump into entry point. 

    Please let me know if it's possible on AM263x

    Regards, 

    Artem

  • Hi Artem,

    If you just want to load and run an application program (*.out file), then set the AM263x CC or LP to NOBOOT MODE. Use CCS target configuration file to connect to a R5F core, then load and run the application program.

    Refer to the URL: AM263x MCU+ SDK: Download, Install and Setup CCS (ti.com) for the details on how to create a CCS target configuration file.

    Best regards,

    Ming

  • Hello,
    I'm not sure if you understood my problem.

    I want to upload a binary file of my application in the RAM region via Ethernet interface, then perform a jump into the entry point without performing reset or boot flow.

    The problem that I faced for now, the exception interrupt (PendSV) crashes my application. The problem is related to the startup sequence of my application that I'm trying to upload from Ethernet, the vector table wasn't loaded correctly as far as I understood.

    Please give me information how to relocate vector table from address 0x00000000 to my custom address and how to properly configure linker script for my RAM application

  • Hi Artem,

    According to the ARM Cortex R5F TRM:

    The vector table resides at either 0x0 or 0xffff0000, defined by a pin at reset, and reflected in the V bit of the SCTLR:
    https://developer.arm.com/documentation/den0042/a/ARM-Processor-modes-and-Registers/Registers/System-Control-Register--SCTLR-

    If TCM is at 0x0 and V bit is 0, then yes, you can place the vector table there (and this is a very common scenario). You may have reset behavior that starts from 0xffff0000, then enable and initialize TCM, then clear V bit to enable subsequent exceptions to be handled in TCM.

    I believe that for AM263x the interrupt vector table has to be located at ATCM 0x00000000.

    See the following URL for details:

    R5: Does the exception vector table reside in TCM if at 0x0000 0000 - Architectures and Processors forum - Support forums - Arm Community

    May I know the reason in which you have to change the interrupt vector table location to 0x701B0000?

    Best regards,

    Ming

  • Hello! I want to explain my use case.

    I have main application that resides inside external flash and boots as any regular application via RBL.
    The main application is able to download the external application binary into 0x701B0000 memory region and execute it jumping to the entry point. The vector table of external application resides at the very beginning of 0x701B0000 memory (see the linker file attached above). I need to have a solution how to properly configure the vector table and startup flow for the external application.

    Please note, that I'm not able to modify external flash content during the boot flow of any of apps

  • Hi Artem,

    You can put the interrupt vector table for the external application to the 0x00000000 (TCMA), because when your main application jump to the entrypoint of your external application, the interrupt vector table of the main application is useless. The control has been passed to the external application from main application from then on.

    The example in the MCU+ SDK is the SBL_QSPI (your main application) and the hello_world (your external application). They both put the interrupt vector table at the same 0x00000000, because the SBL_QSPI will load the hello_world into the RAM and pass the control to hello_world.

    Best regards,

    Ming