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.

AM6422: Loading load_dmsc and application with Lauterbach to R5

Part Number: AM6422

Hi,

I'm trying to debug a simple hello world project with Lauterbach. 

My goal is to program the application on the RAM and debug it with Lauterbach. 

I have tried the following two methods to do that, but each of them has a limitation that I have noted below. 

1. Putting the board on UART mode and loading the boot and application both on RAM using the provided Python script "uart_bootloader.py"

reference: https://software-dl.ti.com/mcu-plus-sdk/esd/AM64X/latest/exports/docs/api_guide_am64x/TOOLS_BOOT.html

Then I plugged the Lauterbach probe into J25 and defined the R5-0 as CPU and attach it. After,  by loading the .out file, I was able to see the source code as well. However, in this way, each time that I want to reprogram the board using UART, it asks me to do a power cycle. Which is not possible as the board is connected to a remote pc.

2. I put the board on DEV BOOT mode (my device is HS-FS). In this mode, if I'm programming inside the CCS I have to load the load_dmsc.hs_fs.js through the scripting console.

But I'm not using CCS (because my ultimate goal was to make a batch file to include the execution of this script as well as the Lauterbach script)

where my  load_dmsc.hs_fs.js is modified to first reset the board at the beginning to be able to reprogram it and also, load the application after loading the ccs_init_elf_file (containing SYSFW and boardcfg).

 reference: https://software-dl.ti.com/mcu-plus-sdk/esd/AM64X/latest/exports/docs/api_guide_am64x/HSFS_MIGRATION_GUIDE.html 

By doing so, I'm able to see the Hello World printing on my console, and it seems it's successfully programmed. 

However, the memory package for your debugger script doesn't mention how the loading program is calculated and it is loaded where. 

At this step, if I attach my Lauterbach probe to J25, the debugger is automatically transferred from J28 to J25 (external debugger which is Lauterbach here), meaning that I can not use TI's debugger script anymore to reprogram it. and each time I need to disconnect the Lauterbach probe (so it is switched to the internal debugger), program it, reconnect the probe, define my CPU as R5-0, and attach it. However, this is not pleasant because each time I have to disconnect Lauterbach to load the program with the internal debugger into RAM and then connect the debugger to attach Lauterbach for debugging. 

So I tried to implement an equivalent of the load_dmsc.hs_fs.js  in Lauterbach which is setting some values for the defined addresses and loading ccs_init_elf_file and then my application files. 

I think it's maybe because it's not loaded at the right address. In your Javascript, I can not see where the ccs_init_elf_file is loaded, however, for a non-HS-FS, the loading address is visible. Based on the linker file, I could see the address of the SRAM that is used which is E:0x70080000. But should I put both of these two files (ccs_init_elf_file, and my application back to back? I tried to put only the first one, but the debug port fails). 

Can you help me with how should I modify it to be able to either do everything with Lauterbach(programming and debugging) or to be able to do it with a batch file without changing the connection or do the power cycle manually?

Thanks, 

Boshra

  • Hello Boshra,

    I am routing this query to script experts and will get a reply in one or two days.

    Regards,

    S.Anil.

  • Hi Boshra,

    The starting two images are not visible to me. Can you please send it again ?

    So I tried to implement an equivalent of the load_dmsc.hs_fs.js  in Lauterbach which is setting some values for the defined addresses and loading ccs_init_elf_file and then my application files. 

    Can you please send the equivalent load_dmsc_hsfs.js file created by you? 

    For the automation of code execution without using CCS we have an existing FAQ. Please refer Automate code execution.

    Thanks & Regards,

    Tushar

  • I attached it here. But I have also highlighted the differences I made in the picture earlier. 
    I tried to do the same as this script with Lauterbach, But  I don't know exactly at what address into RAM I should load the executable ccs_init_elf_file.out and at what address should I load my application_r5.out. I loaded them one after the other or only the first one at E:0x70080000, which seemed its the address used by the linker script. But it doesn't work. 

    Note: I could not create the elf file when I choose the compiler to be GNU V7.2.1 in  CCS, it only generates the images and executable, that's why I'm loading the executable instead of the elf.

     

    /*
     * Copyright (c) 2021, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  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.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * 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 OWNER 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.
     */
    
    /*
    Description:
       Load the DMSC firmware and initialize DMSC with a default board configuration from R5F.
    
    Usage:
    
    1. Modify "sdkPath" (search for EDIT THIS) to point to the absolute path of the SDK.
        - On windows make sure to use '/' or '\\' as path separator
    
    2. Launch AM64x target connection in CCS, however DO NOT connect to any CPUs.
    
    3. From CCS Scripting console do (CCS Tool Bar > View > Scripting Console)
        js:> loadJSFile "<path/to/sdk>/tools/ccs_load/am64x/load_dmsc_hsfs.js"
    
    4. After successful execution you should see a log like below
    
      On the CCS scripting console in CCS,
    
        js:> loadJSFile "C:/ti/mcu_plus_sdk/tools/ccs_load/am64x/load_dmsc_hsfs.js"
        Connecting to DMSC_Cortex_M3_0!
        Fill R5F ATCM memory...
        Writing While(1) for R5F
        Loading DMSC Firmware ... C:/ti/mcu_plus_sdk/source/drivers/sciclient/soc/am64x_am243x/sysfw.bin
        DMSC Firmware Load Done...
        DMSC Firmware run starting now...
        Connecting to MCU Cortex_R5_0!
        Running the board configuration initialization from R5!
        Happy Debugging!!
    
        js:>
    
      On the AM64x.ccxml:CIO console in CCS, i.e the R5F console,
    
        [MAIN_Cortex_R5_0_0]
        DMSC Firmware Version AA.B.C-vDDDD.EEE-FF-gggggg (HHH
        DMSC Firmware revision 0xNN
        DMSC ABI revision x.y
    
        [SCICLIENT] ABI check PASSED
        [SCICLIENT] Board Configuration with Debug enabled ...
        [SCICLIENT] Common Board Configuration PASSED
        [SCICLIENT] PM Board Configuration PASSED
        [SCICLIENT] RM Board Configuration PASSED
        [SCICLIENT] Security Board Configuration PASSED
    
        DMSC Firmware Version AA.B.C-vDDDD.EEE-FF-gggggg (HHH
        DMSC Firmware revision 0xNN
        DMSC ABI revision x.y
    
        All tests have passed!!
    
      On the AM64x.ccxml console in CCS, i.e the GEL output console,
    
        DMSC_Cortex_M3_0: GEL Output: This GEL is currently only supported for use from the Cortex-M3 inside the DMSC.
        DMSC_Cortex_M3_0: GEL Output: Do not run this GEL from any other CPU on the SoC.
        DMSC_Cortex_M3_0: GEL Output: This script sets the first address translation region to [0x8000_0000, 0x0000_0000].
        DMSC_Cortex_M3_0: GEL Output: It also sets the second address translation region to    [0x6000_0000, 0x4000_0000].
        DMSC_Cortex_M3_0: GEL Output: This is consistent with the SoC DV assumptions.
        DMSC_Cortex_M3_0: GEL Output: Configuring ATCM for the R5Fs
        DMSC_Cortex_M3_0: GEL Output: ATCM Configured.
        ...
        DMSC_Cortex_M3_0: GEL Output: Powering up all PSC power domains in progress...
        DMSC_Cortex_M3_0: GEL Output: Powering up MAIN domain peripherals...
        ...
        DMSC_Cortex_M3_0: GEL Output: Powering up LPSC_A53_CLUSTER_0
        DMSC_Cortex_M3_0: GEL Output: Power domain and module state changed successfully.
        ...
        DMSC_Cortex_M3_0: GEL Output:
        DMSC_Cortex_M3_0: GEL Output: *****DDR is configured using R5 or A53 GELs
        DMSC_Cortex_M3_0: GEL Output: M4F WFI Vector set into IRAM.
        MAIN_Cortex_R5_0_0: GEL Output: Running from R5
        MAIN_Cortex_R5_0_0: GEL Output:
    
        DDR not initialized with R5 connect.
    
        Go to menu Scripts --> AM64 DDR Initialization -> AM64_DDR_Initialization_ECC_Disabled to initialize DDR.
    
        ====
    
    5. If any of the logs in step 4 show "fail" or "error" messages then
       check your EVM, CCS, SDK setup and try again.
    */
    
    function updateScriptVars()
    {
    	
        //Open a debug session
        dsMCU1_0 = debugServer.openSession( ".*MAIN_Cortex_R5_0_0" );
    
    }
    
    function connectTargets()
    {
        /* Set timeout of 20 seconds */
        script.setScriptTimeout(200000);
        updateScriptVars();
    
        //Init_M4()
        print("Connecting to MCU Cortex_R5_0!");
    
    	    // Query the number of supported resets
        var numResets = dsMCU1_0.target.getNumResetTypes();
        
    	var my_reset
    	for (i=0;i<numResets;i++)
        {
           // Access one of the resetType objects
           my_reset = dsMCU1_0.target.getResetType(i);
           
           // determine if the reset is allowed, and issue a reset
           if ( my_reset.isAllowed() ) { my_reset.issueReset();}
    	}
    
        // Connect the MCU R5F
        dsMCU1_0.target.connect();
    	
    
    
        dsMCU1_0.memory.fill(0x78000000, 0, 0x2000, 0);
        print("Writing While(1) for R5F")
        dsMCU1_0.memory.writeWord(0, 0x78000000, 0xE59FF004); /* ldr        pc, [pc, #4] */
        dsMCU1_0.memory.writeWord(0, 0x78000004, 0x38);       /* Address 0x38 */
        dsMCU1_0.memory.writeWord(0, 0x78000038, 0xEAFFFFFE) /* b          #0x38 */
    
        // Halt the R5F and re-run.
        dsMCU1_0.target.halt();
    
        // Reset the R5F and run.
        dsMCU1_0.target.reset();
    
        print("Running the board configuration initialization from R5!");
        // Load the board configuration init file.
        dsMCU1_0.memory.loadProgram(ccs_init_elf_file);
    	
        // Halt the R5F and re-run.
        dsMCU1_0.target.halt();
    	
        // Run Synchronously for the executable to finish
        dsMCU1_0.target.run();
    	
    
        return 0;
    }
    
    function disconnectTargets()
    {
        updateScriptVars();
        // Reset the R5F to be in clean state.
        dsMCU1_0.target.reset();
    }
    
    function doEverything()
    {
        var run = true;
    
        if(!File(ccs_init_elf_file).isFile())
        {
            print("[ERROR] File "+ccs_init_elf_file+" not found !!!");
            run = false;
        }
    
        if(run == true)
        {
            updateScriptVars();
            var connectSuccess = connectTargets();
            if(connectSuccess == 0)
            {
    			
    	        print("Ready to pogram application");
    	        dsMCU1_0.memory.loadProgram(appfile);
    		    //var main = dsMCU1_0.symbol.getAddress("main");
    			//var bp1 = dsMCU1_0.breakpoint.add(main)
                //var bp2 = dsMCU1_0.breakpoint.add("main.c", 40);
    			//var bp3 = dsMCU1_0.breakpoint.add("main.c", 49);
    
              	//dsMCU1_0.target.halt();
    	        dsMCU1_0.target.run();
    			
    
    			print("Happy Debugging!!");
                disconnectTargets();
                
    		
            }
        }
        else
        {
            print("Please read the instructions at top of this file to make sure the paths to the SDK are set correctly !!!")
        }
    }
    
    // Import the DSS packages into our namespace to save on typing
    importPackage(Packages.com.ti.debug.engine.scripting)
    importPackage(Packages.com.ti.ccstudio.scripting.environment)
    importPackage(Packages.java.lang)
    importPackage(Packages.com.ti.ccstudio.ResetType)
    importPackage(Packages.com.ti.ccstudio.Breakpoint)
    importPackage(java.io);
    importPackage(java.lang);
    
    var ds;
    var debugServer;
    var script;
    
    // Check to see if running from within CCSv4 Scripting Console
    var withinCCS = (ds !== undefined);
    
    var sdkPath = null;
    
    if (!withinCCS)
    {
        // !!! EDIT THIS !!! Add absolute path to SDK in your environment variables
        // OR set this variable to the absolute path of the SDK
        sdkPath = "C:/ti/mcu_plus_sdk_am64x_08_06_00_43";
    }
    else
    {
        sdkPath = System.getenv("MCU_PLUS_SDK_AM64X_PATH");
        if(sdkPath == null)
        {
            // !!! EDIT THIS !!! Add absolute path to SDK in your environment variables
            // OR set this variable to the absolute path of the SDK
            sdkPath = "C:/ti/mcu_plus_sdk_am64x_08_06_00_43";
        }
    }
    
    // path to board config elf
    ccs_init_elf_file = sdkPath+"/tools/ccs_load/am64x/sciclient_ccs_init.release.out";
    
    appfile= "C:/Users/barghava/workspace_v12/hello_world_am64x-evm_r5fss0-0_nortos_gcc-armv7/Release/hello_world_am64x-evm_r5fss0-0_nortos_gcc-armv7.out";
    
    // !!! EDIT THIS !!! Add absolute path to the CCXML file here.
    fileCcxml = "C:/Users/barghava/workspace_v12/hello_world_am64x-evm_r5fss0-0_nortos_gcc-armv7/targetConfigs/AM64x.ccxml"
    
    // Create scripting environment and get debug server if running standalone
    if (!withinCCS)
    {
        // Import the DSS packages into our namespace to save on typing
        importPackage(Packages.com.ti.debug.engine.scripting);
        importPackage(Packages.com.ti.ccstudio.scripting.environment);
        importPackage(Packages.java.lang);
    
        // Create our scripting environment object - which is the main entry point into any script and
        // the factory for creating other Scriptable ervers and Sessions
        script = ScriptingEnvironment.instance();
    
        // Get the Debug Server and start a Debug Session
        debugServer = script.getServer("DebugServer.1");
    	
        // Check if the CCXML file exists.
        if(!File(fileCcxml).isFile())
        {
            print("[ERROR] File "+fileCcxml+" not found !!!");
            print("Seems like the script is not run from within CCS. Please edit the load_dmsc_hsfs.js script to add a path to your CCXML configuration file in this case.")
        }
        else
        {
            debugServer.setConfig(fileCcxml);
            doEverything();
        }
    }
    else // otherwise leverage existing scripting environment and debug server
    {
        debugServer = ds;
        script = env;
        doEverything();
    }
    
    

  • Hi Boshra,

    From the changes done in load_dmsc_hsfs.js file, it seems like you are trying to do the following:

    • Reset the EVM.
    • Initializing the EVM.
    • Loading the Appimage.

    Instead of loading the appimage from load_dmsc_hsfs.js file you can use the `loadti` tool provided by TI to load/run the executables(.out) on TI targets. 

    And you can also reset the EVM from the application itself by writing 0x200F6 value to CTRLMMR_RST_CTRL (0x43018170) register. 

    Write the following command in a batch file

    <path to CCS installation>\ccs\ccs_base\scripting\bin\dss.bat <installation path to MCU+SDK>\tools\ccs_load\am64x\load_dmsc_hsfs.js
    <CCS installation path>\ccs1210\ccs\ccs_base\scripting\examples\loadti\loadti.bat -t=<timeout in milisec> -c <path to .ccxml (target configuration) file> -cpu=<CPU Name> <path to .out binary>
    

    Save the batch file and execute it. This will automate the above task.

    Note : Please change the path appropriately in the given commands and load_dmsc_hsfs.js file.

    Thanks & Regards,

    Tushar

  • Hi thanks for your reply, the modification I did for load_dmsc seems working (I don't know if it was the right way to do it or not though), and it was not the reason for my ticket, But I will apply your suggestions to make it cleaner.

    My problem is that I want to debug and reprogram it with Lauterbach and as soon as the Luaterbach debugger is connected, the debugger switches from the internal debugger to the external which is Lauterbach. So if the Lauterbach probe is connected to J25 JTAG, the debugger (hw side) switches to J25, and it's not J28 JTAG anymore. Therefore, if Lauterbach is connected, I can not program it the way I explained. 

    In the image that I also sent you earlier, I was trying to write a script that is following the same steps as load_dmsc_hsfs.js. Can you explain to me what is it missing and how I should make it work?

    thanks, 

    Boshra

  • Hello Boshra,

    Please note for HS-FS Javascript, we are loading the ELF files identified by .out extension. The loading address information is not available in the script since the loading addresses are embedded in the metadata of the ELF files. The program loading the ELF file would know how to parse the ELF file and so respectively loads the sections in the ELF file at their loading addresses.

    If we talk about CCS, it knows how to parse the ELF file. I believe Lauterbach also knows how to parse the ELF files. In that case, you only need to give the right command in Lauterbach script to load the ELF file, the Lauterbach will itself parse and load the sections in the program at the right addresses.

    Regards,

    Prashant

  • I modified the Lauterbach script. The loading address was as it was in the linker script at address 0x70080000 of SRAM for R5. Both the SYSFW and application are loaded at this address. However, there should be a wait between loading the SYSFW and then the application. Probably the ROM code copies that to another address and we should wait for it to complete before loading our application. Also, I added a warm reset at the beginning to be able to reprogram it.  So it was resolved by adding a wait between the two loadings. 

  • Hi Boshra,

    Thanks for the adding the details. It would be helpful for the future readers.

    If the above issue is resolved , Can you please close the thread?

    Thanks & Regards,

    Tushar