AM6548: R5F Application Development

Part Number: AM6548

Tool/software:

Hi,

I am trying to develop baremetal applications on the R5F cores of the AM6548 so that I can take advantage of the safety features. I have seen posts on E2E on people asking questions, but I haven't seen clear details on how to do this.

I have CCS installed with a processor development kit and the MCU+ SDK. I am able to compile R5F C programs using different compilers. My goal is to use rproc in U-Boot to load the firmware on to the R5F cores, and run the baremetal application that way. Whenever I try to load the .elf/.out executables, my U-Boot freezes. I have tried compiling for 3 different compilers, TI, CLANG, and GNU. In the properties of my R5F CCS project, I try to add the linker command file of the AM65x but get errors, such as "HEAPSIZE" undefined. 

I was able to get the C program to run via the XDS110 Debugger on my AM65 IDK system's R core, but I need the program to run from U-Boot.

I am unsure on what else to try, and why the executables freeze U-Boot. 

  • Hello Akm,

    Setting support expectations

    First off, please note that we have limited software support for AM65x R5F cores. Please refer to this thread for more details:
    https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1402124/am6548-how-to-develop-applications-for-the-mcu-r5f-cores/5368606#5368606

    You can see the supported software drivers in AM65x MCU+ SDK in the release notes:
    https://software-dl.ti.com/mcu-plus-sdk/esd/AM65X/09_01_00_04/docs/api_guide_am65x/RELEASE_NOTES_09_01_00_PAGE.html

    If you want software support from TI with additional drivers or features, I would encourage you to evaluate another device to see if it might work for your usecase, like AM64x. We can assist with processor selection if needed.

    Talking about your actual question 

    What version of Linux SDK / U-Boot are you using?

    Regards,

    Nick

  • Thank you for the support reminder.

    I am using both 7.03.* and 9.01.*

    Do you know how to properly build R5F applications?

  • Hello Akm,

    Build steps

    I usually build R5F applications with makefiles (just because I am often programming Linux, so I'm usually in the terminal anyway). But for building in both CCS or with Makefiles, I would recommend following the steps in the MCU+ SDK Getting Started documents.

    Start here, and make sure you have the correct versions of all the tools installed:
    https://software-dl.ti.com/mcu-plus-sdk/esd/AM65X/09_01_00_04/docs/api_guide_am65x/GETTING_STARTED.html

    This page has instructions to build projects from both CCS and Makefile. There are also links to pages that have more details (Using SDK with CCS Projects / Makefiles): https://software-dl.ti.com/mcu-plus-sdk/esd/AM65X/09_01_00_04/docs/api_guide_am65x/GETTING_STARTED_BUILD.html

    Start from a known good example 

    Are you starting with a "known good" example that you can get to compile, load, and run? That makes it a lot easier to change one thing at a time and test, and then work backwards if something breaks.

    Regards,

    Nick

  • Hi Nick,

    I was able to get a project to compile. I was also able to load the executable on to the R cores. However, I am not sure if it is running correctly. I am using a linker script that may not necessarily be correct. Can you help verify?

    Here is the lds file I am using, the lines with "akm" are added by me. I am compiling with the GNU compiler and producing .elf files. 

    /****************************************************************************/
    /*  AM65x.lds                                                               */
    /*  Copyright (c) 2018  Texas Instruments Incorporated                      */
    /*  Author: Rafael de Souza                                                 */
    /*                                                                          */
    /*    Description: This file is a sample linker command file that can be    */
    /*                 used for linking programs built with the GCC compiler    */
    /*                 and running the resulting .out file on a AM65x device.   */
    /*                 Use it as a guideline.  You will want to                 */
    /*                 change the memory layout to match your specific          */
    /*                 target system.  You may want to change the allocation    */
    /*                 scheme according to the size of your program.            */
    /*                                                                          */
    /****************************************************************************/
    
    STACKSIZE = 0x2000; /* akm */
    HEAPSIZE = 0x1000; /* akm */
    Entry = 0x90000000; /* akm */
    
    MEMORY
    {
    
        MSMC_SRAM1 :  o = 0x70000000,  l = 0x00100000  /* 1MB L3 MSMC with ECC SRAM1 */
        MSMC_SRAM2 :  o = 0x70100000,  l = 0x00100000  /* 1MB L3 MSMC with ECC SRAM2 */
        /*DDR0 :        o = 0x80000000,  l = 0x40000000  /* 1GB external DDR Bank 0 */
        /*DDR1 :        o = 0xC0000000,  l = 0x40000000  /* 1GB external DDR Bank 1 */
        DDR0 :        o = 0x80000000,  l = 0x80000000  /* akm 2GB external DDR Bank 0 */
        DDR1 :        o = 0x880000000,  l = 0x80000000  /* akm 2GB external DDR Bank 1 */
    }
    
    /* Linker script to place sections and symbol values. Should be used together
     * with other linker script that defines memory region DDR0.
     * It references following symbols, which must be defined in code:
     *   Entry : Entry of reset handler
     * 
     * It defines following symbols, which 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
     *   __HeapBase     - To be compatible with Linaro's semihosting support 
     *   __StackLimit
     *   __StackTop
     *   __StackBase    - To be compatible with Linaro's semihosting support 
     *   __stack
     */
    ENTRY(Entry)
    
    SECTIONS
    {
        .rsthand :
        {
            . = ALIGN(0x10000);
            KEEP(*(.isr_vector))
            *startup_ARMCA53.o (.text)
        } > MSMC_SRAM1
        
        . = ALIGN(4);
        .text :
        {
            *(.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*))
        } > MSMC_SRAM1
    
        .ARM.extab : 
        {
            *(.ARM.extab* .gnu.linkonce.armextab.*)
        } > MSMC_SRAM1
    
        __exidx_start = .;
        .ARM.exidx :
        {
            *(.ARM.exidx* .gnu.linkonce.armexidx.*)
        } > MSMC_SRAM1
        __exidx_end = .;
    
            
        .data :
        {
            . = ALIGN(4);
            __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);
            /* All data end */
            __data_end__ = .;
    
        } > MSMC_SRAM1
    
        .bss :
        {
            . = ALIGN(4);
            __bss_start__ = .;
            *(.bss*)
            *(COMMON)
            __bss_end__ = .;
        } > MSMC_SRAM1
        
        .heap (NOLOAD):
        {
            /* The line below can be used to FILL the memory with a known value and
             * debug any stack overruns. For this to work, the specifier (NOLOAD) above 
             * must be removed at the expense of an increase in the output binary size */
            FILL(0xDEADBEEF)
            . = ALIGN(16);
            __end__ = .;
            end = __end__;
            /* The line below created to be compatible with Linaro's semihosting support */
            __HeapBase = __end__; 
            *(.heap*)
            . = . + HEAPSIZE;
            __HeapLimit = .; 
        } > MSMC_SRAM1
    
        /* .stack section doesn't contain any symbols. It is only
         * used for linker to calculate size of stack sections, and assign
         * values to stack symbols later */
        .stack (NOLOAD):
        {
            /* The line below can be used to FILL the memory with a known value and
             * debug any stack overruns. For this to work, the specifier (NOLOAD) above 
             * must be removed at the expense of an increase in the output binary size */
            FILL(0xBAD0BAD0)
            . = ALIGN(16);
            __StackLimit = . ;
            *(.stack*)
            . = . + STACKSIZE;
            __StackTop = . ;
            /* The line below created to be compatible with Linaro's semihosting support */
            __StackBase = . ;
        } > MSMC_SRAM1
        PROVIDE(__stack = __StackTop);
    
    }
    /**************************************************************************/
    

    Here is my C program to run on the R core. I am trying to toggle a GPIO to blink an LED. I know the pin works because I can toggle it in U-Boot, and am using the same addresses. Can the R core access these regions?

    //#include <stdio.h>
    #include <stdio.h>
    //#include <kernel/dpl/DebugP.h>
    //#include "ti_drivers_config.h"
    //#include "ti_drivers_open_close.h"
    //#include "ti_board_open_close.h"
    
    /**
     * hello.c
     */
    
    
    #define CTRLMMR_PADCONFIG114    (0x0011C1C8)
    #define GPIO1_DIR01             (0x00601010)
    #define GPIO1_OUT_DATA01        (0x00601014)
    
    #define BIT_POS                 (18)
    #define BIT_MASK                (1 << BIT_POS)
    
    void delay(uint32_t count);
    void InitializeGPIOs(void);
    
    int main(void)
    {
        volatile uint32_t *gpioPinOutdata= (uint32_t*) (GPIO1_OUT_DATA01);
    
        volatile uint32_t *gpioPinConfig = (uint32_t*) (CTRLMMR_PADCONFIG114);
        volatile uint32_t *gpioPinDir = (uint32_t*) (GPIO1_DIR01);
    
        *gpioPinConfig = 0x00010007;    // Configure pin for GPIO mapping.
        *gpioPinDir &= ~(BIT_MASK);     // Set GPIO1_18 to be output direction.
    
    	while(1)
    	{
    	    *gpioPinOutdata ^= (BIT_MASK);
    	    delay(1000);
    	}
    
    	return 0;
    }
    
    void delay(uint32_t count)
    {
        while(count--)
        {
            __asm__("nop");
        }
    }
    
    void InitializeGPIOs(void)
    {
        volatile uint32_t *gpioPinConfig = (uint32_t*) (CTRLMMR_PADCONFIG114);
        volatile uint32_t *gpioPinDir = (uint32_t*) (GPIO1_DIR01);
    
        *gpioPinConfig = 0x00010007;    // Configure pin for GPIO mapping.
        *gpioPinDir &= ~(BIT_MASK);     // Set GPIO1_18 to be output direction.
    }

  • Hello Akm,

    You can find the documentation for the MCU+ SDK GPIO examples here:
    https://software-dl.ti.com/mcu-plus-sdk/esd/AM65X/09_01_00_04/docs/api_guide_am65x/EXAMPLES_DRIVERS_GPIO_LED_BLINK.html

    and the driver documentation here:
    https://software-dl.ti.com/mcu-plus-sdk/esd/AM65X/09_01_00_04/docs/api_guide_am65x/DRIVERS_GPIO_PAGE.html

    I would start by trying to get that unmodified MCU+ GPIO example working. Once it is working, you can start modifying from there.

    It does not look like the code you posted is based on MCU+ SDK code, so we will not be able to comment.

    Regards,

    Nick

  • Hi Nick,

    I cannot get the example projects from mcu plus sdk to import into CCS. I have reinstalled the specific versions called out in the SDK documentation. When I import the "Hello World" project, I get an error that reads "Import failed for project 'hello_world' because its meta-data cannot be interpreted. Please contact support." I do not know where to go from there.

    Even if I were to get the MCU+SDK working, can I directly take the executables produced and run them on the R5 cores using rproc in U-Boot? Please confirm this as this is key.

    As for the code I am using, I just want to test that basic C code works on my R5 core by toggling the GPIO. It is a simple code that I ran on my IDK through the CCS debugger. However, I want to be able to run this in U-Boot via rproc, but it does not seem to be doing anything when compiled with GNU, and does not load when using the TI LTS compiler.  

  • Hello Akm,

    If you are using the version of u-boot that is available in AM65x Linux SDK 9.1, then yes, you should be able to take an ELF file and load it onto an R5F core, as discussed in the Linux SDK docs here:
    https://software-dl.ti.com/processor-sdk-linux/esd/AM65X/09_01_00_01/exports/docs/linux/Foundational_Components/U-Boot/UG-RemoteProc.html

    I am reassigning your thread to another team member to comment about the CCS import question. Today is a holiday in India, so it might be a couple of days before you get a response. Feel free to ping the thread if you do not get a reply within a few business days.

    Regards,

    Nick

  • Hi Akm,

    When I import the "Hello World" project, I get an error that reads "Import failed for project 'hello_world' because its meta-data cannot be interpreted.

    Can you please provide a screenshot of complete error message?

    Also please tell which version of MCU+SDK and CCS are you using?

    Regards,

    Tushar

  • Hi,

    The issue was because there was some cached file in the project directory. After deleting the .project files, I was able to import the project successfully and compile the program. Thanks.