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.

66AK2G12: How to synchronize firmware with GEL script.

Part Number: 66AK2G12
Other Parts Discussed in Thread: MSP430F5529

I am using CCS 10.4. Firmware is written in C, on the K2G ARM core, and compiled with GCC v7.3.1 (Linaro).

I have set a software breakpoint in a C function in the firmware, as follows:


/* main.c */

int gGelCommand __attribute__ ((section ("data"))) = 0;
int gGelParam __attribute__ ((section ("data"))) = 0;
int gGelReturnValue __attribute__ ((section ("data"))) = 0;

void GelCommand_Service(void)
{
    // At this breakpoint, the GEL script can populate the values of
    // global vars gGelCommand and gGelParam for the next iteration, 
    // and read the value of global var gGelReturnValue from the
    // previous iteration.
    __asm__(" bkpt;"); 
    
    int command = gGelCommand;
    gGelCommand = 0;
    
    switch (command)
    {
        case 0:
        default:
            break;
            
        case 1:
            gGelReturnValue = (int) myFunc1(gGelParam);
            break;
            
        case 2:
            gGelReturnValue = (int) myFunc2(gGelParam);
            break;
    }
}


int main()
{
    while (1)
    {
        GelCommand_Service();
    }
    
    return 0;
}

Here is an excerpt of a GEL script I have written. The firmware is supposed to be halted at the breakpoint before calling one of the GEL script functions.

/* GEL script */

hotmenu Call_MyFunc1()
{
    int retval;
    retval = GelCommand(1, 10);
    Gel_TextOut("MyFunc1(10) returned with value %u\n",,,,, retval);
}

hotmenu Call_MyFunc2()
{
    int retval;
    retval = GelCommand(2, 20);
    Gel_TextOut("MyFunc2(20) returned with value %u\n",,,,, retval);
}


GelCommand (gelCommand, gelParam)
{
    int retval = 0;
    
    GEL_TextOut("1\n");         // This prints.
    
    // Firmware should be already halted at the BKPT instruction in function
    // GelCommand_Service().
    if (GEL_IsHalted())
    {
        GEL_TextOut("2\n");     // This prints.
        
        // Copy the command and parameter into the global vars that are visible
        // to the firmware.
        gGelCommand = gelCommand;
        gGelParam = gelParam;
        
        // Execute one iteration of GelCommand_Service() in the firmware.
        // Execution should halt at the BKPT instruction.
        GEL_Run();
        
        GEL_TextOut("3\n");     // This prints.
        
        // Try this...
        GEL_SrcStepOver();
        
        GEL_TextOut("4\n");     // This prints.
        
        // Wait for the BKPT instruction to be reached.
        while (!GEL_IsHalted()) // GEL execution hangs here, while the firmware
            ;                   // is waiting at the BKPT.
        
        GEL_TextOut("5\n");     // This does not print.
        
        // Retrieve return value from the firmware.
        retval = gGelReturnValue;
    }
    else
    {
        GEL_TextOut("ERROR: Firmware is not halted.\nBefore executing a GEL command, the firmware must be halted at the BKPT instruction in function GelCommand_Service()");
    }

    GEL_TextOut("6\n");         // This does not print.

    return retval;
}

Summary of how this is supposed to work: When a user selects from the CCS Scripts menu either of the options Call_MyFunc1 or Call_MyFunc2, the GelCommand() function is supposed to populate two global variables in the target, then run the firmware. The firmware is supposed to call the selected firmware function (MyFunc1() or MyFunc2()), and then after returning from the function, halt again at the software breakpoint. The GEL script is then able to retrieve the return value from the function.

But the GEL script hangs on the line of code that waits for the firmware to be halted. Meanwhile, the firmware is in fact halted at the software breakpoint.

Please tell me how to accomplish what I am trying to do here.

Thank you.

  • Hello,

    I can reproduce the behavior you see. I suspect there are multiple issues at play. One is the issue of GEL being (mostly) asynchronous in behavior. The other is the debugger not reporting the correct state of the target. Third is the interaction between GEL and the target state. I'll need to investigate further.

    I would recommend moving away from GEL and instead use DSS. It is better suited for the automation you are trying to so. You can have DSS scripts that can be loaded via Scripting Console. These DSS scripts can also use hotmenus so that you can run a DSS function via a menu item under 'Scripts' like you are trying with GEL:

    https://software-dl.ti.com/ccs/esd/documents/ccs_scripting_console_view.html#the-scripts-menu

    thanks

    ki

  • One is the issue of GEL being (mostly) asynchronous in behavior.

    As I experiment more with this, my common above seems to be the biggest factor. GEL is not ideal for automation beyond simple target initialization. Anything beyond that we recommend DSS. Unless there is some specific reason that GEL is needed, I would try the above steps with a DSS script.

  • Thank you, Ki.

    I'm looking into the DSS materials now. I'd like to keep this thread open a few more days, to confirm that DSS will do what I need, before marking this issue resolved.

    Kind regards,

    Andy

  • Sounds good. DSS will absolutely be the better option here. GEL has many limitations thatDSS resolves with regards to automation beyond a few simple tasks.

  • Hi Ki,

    I've started to create a DSS script. I'm modifying the C:\ti\ccs1040\ccs\ccs_base\scripting\examples\DebugServerExamples\msp430f5529_breakpoints.js example script. Here is what I have so far:

    // Import the DSS packages into our namespace.
    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 servers and Sessions.
    //
    var script = ScriptingEnvironment.instance()
    
    // Create a log file to log script execution (for debug).
    //
    script.traceBegin("FlashUtil_TestLog.xml",  // Output log file name. Path appears to be relative to Current Working Directory.
                      "DefaultStylesheet.xsl")  // XSLT file containing style info to allow the log file to be viewed in a web browser.
                                                // Path of XSLT file appears to be relative to the directory containing this .js script.
    
    // Set TimeOut to 30 seconds.
    //
    script.setScriptTimeout(15000)
    
    // Log everything.
    //
    script.traceSetConsoleLevel(TraceLevel.ALL)
    script.traceSetFileLevel(TraceLevel.ALL)
    
    // Get the Debug Server and start a Debug Session.`
    //
    debugServer = script.getServer("DebugServer.1")
    
    // Path appears to be relative to the folder containing this .js script.
    // 
    debugServer.setConfig("../targetConfigs/66AK2G12.ccxml");
    debugSession = debugServer.openSession(".*")
    
    

    When I run this script, I can single-step through all of the statements successfully until the last one:

    debugSession = debugServer.openSession(".*")

    When I try to step over openSession(), after 6 seconds the Rhino window simply closes.

    When I open the .xml log file, I see the last record in the file reports a ScriptingException, with the associated message reading:

    Could not open session. Found 10 devices matching: .*
    Blackhawk XDS560v2-USB System Trace Emulator/CortexA15
    Blackhawk XDS560v2-USB System Trace Emulator/ICSS_0_PRU_0
    Blackhawk XDS560v2-USB System Trace Emulator/ICSS_0_PRU_1
    Blackhawk XDS560v2-USB System Trace Emulator/ICSS_1_PRU_0
    Blackhawk XDS560v2-USB System Trace Emulator/ICSS_1_PRU_1
    Blackhawk XDS560v2-USB System Trace Emulator/IcePick_D
    Blackhawk XDS560v2-USB System Trace Emulator/CS_DAP_DebugSS
    Blackhawk XDS560v2-USB System Trace Emulator/CSSTM_0
    Blackhawk XDS560v2-USB System Trace Emulator/CTETB_0
    Blackhawk XDS560v2-USB System Trace Emulator/CSETB_PTM

    Here is the full text of the record:

    <record>
      <date>2021-11-15T18:03:04</date>
      <millis>1637017384195</millis>
      <sequence>133</sequence>
      <logger>com.ti.ccstudio.scripting.environment.ScriptingException</logger>
      <level>SEVERE</level>
      <class>com.ti.ccstudio.scripting.environment.ScriptingException</class>
      <method>logException</method>
      <thread>36</thread>
      <message>Could not open session. Found 10 devices matching: .*
    Blackhawk XDS560v2-USB System Trace Emulator/CortexA15
    Blackhawk XDS560v2-USB System Trace Emulator/ICSS_0_PRU_0
    Blackhawk XDS560v2-USB System Trace Emulator/ICSS_0_PRU_1
    Blackhawk XDS560v2-USB System Trace Emulator/ICSS_1_PRU_0
    Blackhawk XDS560v2-USB System Trace Emulator/ICSS_1_PRU_1
    Blackhawk XDS560v2-USB System Trace Emulator/IcePick_D
    Blackhawk XDS560v2-USB System Trace Emulator/CS_DAP_DebugSS
    Blackhawk XDS560v2-USB System Trace Emulator/CSSTM_0
    Blackhawk XDS560v2-USB System Trace Emulator/CTETB_0
    Blackhawk XDS560v2-USB System Trace Emulator/CSETB_PTM</message>
      <exception>
        <message>com.ti.ccstudio.scripting.environment.ScriptingException: Could not open session. Found 10 devices matching: .*
    Blackhawk XDS560v2-USB System Trace Emulator/CortexA15
    Blackhawk XDS560v2-USB System Trace Emulator/ICSS_0_PRU_0
    Blackhawk XDS560v2-USB System Trace Emulator/ICSS_0_PRU_1
    Blackhawk XDS560v2-USB System Trace Emulator/ICSS_1_PRU_0
    Blackhawk XDS560v2-USB System Trace Emulator/ICSS_1_PRU_1
    Blackhawk XDS560v2-USB System Trace Emulator/IcePick_D
    Blackhawk XDS560v2-USB System Trace Emulator/CS_DAP_DebugSS
    Blackhawk XDS560v2-USB System Trace Emulator/CSSTM_0
    Blackhawk XDS560v2-USB System Trace Emulator/CTETB_0
    Blackhawk XDS560v2-USB System Trace Emulator/CSETB_PTM</message>
        <frame>
          <class>com.ti.debug.engine.scripting.DebugServer$SessionFactory</class>
          <method>processMatches</method>
          <line>195</line>
        </frame>
        <frame>
          <class>com.ti.debug.engine.scripting.DebugServer$SessionFactory</class>
          <method>matchByRegularExpression</method>
          <line>252</line>
        </frame>
        <frame>
          <class>com.ti.debug.engine.scripting.DebugServer</class>
          <method>openSession</method>
          <line>1074</line>
        </frame>
        <frame>
          <class>com.ti.debug.engine.scripting.DebugServer</class>
          <method>openSession</method>
          <line>65</line>
        </frame>
        <frame>
          <class>sun.reflect.NativeMethodAccessorImpl</class>
          <method>invoke0</method>
        </frame>
        <frame>
          <class>sun.reflect.NativeMethodAccessorImpl</class>
          <method>invoke</method>
        </frame>
        <frame>
          <class>sun.reflect.DelegatingMethodAccessorImpl</class>
          <method>invoke</method>
        </frame>
        <frame>
          <class>java.lang.reflect.Method</class>
          <method>invoke</method>
        </frame>
        <frame>
          <class>org.mozilla.javascript.MemberBox</class>
          <method>invoke</method>
          <line>145</line>
        </frame>
        <frame>
          <class>org.mozilla.javascript.NativeJavaMethod</class>
          <method>call</method>
          <line>204</line>
        </frame>
        <frame>
          <class>org.mozilla.javascript.Interpreter</class>
          <method>interpretLoop</method>
          <line>3085</line>
        </frame>
        <frame>
          <class>org.mozilla.javascript.Interpreter</class>
          <method>interpret</method>
          <line>2251</line>
        </frame>
        <frame>
          <class>org.mozilla.javascript.InterpretedFunction</class>
          <method>call</method>
          <line>161</line>
        </frame>
        <frame>
          <class>org.mozilla.javascript.ContextFactory</class>
          <method>doTopCall</method>
          <line>340</line>
        </frame>
        <frame>
          <class>org.mozilla.javascript.ScriptRuntime</class>
          <method>doTopCall</method>
          <line>2758</line>
        </frame>
        <frame>
          <class>org.mozilla.javascript.InterpretedFunction</class>
          <method>exec</method>
          <line>172</line>
        </frame>
        <frame>
          <class>org.mozilla.javascript.tools.shell.Main</class>
          <method>evaluateScript</method>
          <line>503</line>
        </frame>
        <frame>
          <class>org.mozilla.javascript.tools.shell.Main</class>
          <method>processFileSecure</method>
          <line>425</line>
        </frame>
        <frame>
          <class>org.mozilla.javascript.tools.shell.Main</class>
          <method>processFile</method>
          <line>391</line>
        </frame>
        <frame>
          <class>org.mozilla.javascript.tools.shell.Main</class>
          <method>processSource</method>
          <line>382</line>
        </frame>
        <frame>
          <class>org.mozilla.javascript.tools.shell.Main</class>
          <method>processFiles</method>
          <line>179</line>
        </frame>
        <frame>
          <class>org.mozilla.javascript.tools.shell.Main$IProxy</class>
          <method>run</method>
          <line>100</line>
        </frame>
        <frame>
          <class>org.mozilla.javascript.Context</class>
          <method>call</method>
          <line>528</line>
        </frame>
        <frame>
          <class>org.mozilla.javascript.ContextFactory</class>
          <method>call</method>
          <line>450</line>
        </frame>
        <frame>
          <class>org.mozilla.javascript.tools.shell.Main</class>
          <method>exec</method>
          <line>162</line>
        </frame>
        <frame>
          <class>org.mozilla.javascript.tools.debugger.Main</class>
          <method>main</method>
          <line>255</line>
        </frame>
        <frame>
          <class>com.ti.ccstudio.apps.internal.scripting.RunScript$1</class>
          <method>run</method>
          <line>87</line>
        </frame>
      </exception>
    </record>
    

    How to fix this?

    A note of somewhat lesser importance: I can't seem to get either Google Chrome or Microsoft Edge to display anything at all for the .xml file. I have placed a copy of DefaultStylesheet.xsl in the same folder as the .xml file. But I only get a blank window in either browser.

  • debugSession = debugServer.openSession(".*")

    This is only recommended for a debug session of a device with only one debuggable CPU. For multicore devices, I'd recommend explicitly specifying the CPU at minimum:

    https://software-dl.ti.com/ccs/esd/documents/users_guide/sdto_dss_handbook.html#multiple-debug-sessions-for-multi-core-debug

    Is your end goal to run your script all from the command line or from within an active debug session like you would do with GEL?

  • Hi Ki,

    Thank you, I got openSession() to work by providing the correct parameter:

        debugSession = debugServer.openSession("Blackhawk XDS560v2-USB System Trace Emulator/CortexA15");
    

    Is your end goal to run your script all from the command line or from within an active debug session like you would do with GEL?

    I am creating a flash programmer utility. Firmware will provide functions to program NOR SPI flash devices on our custom board with bootable images, including a secondary bootloader and the application firmware for both cores. I have imagined that a submenu under the Scripts menu would provide the user interface, though I am open to suggestions for other approaches.

    I am still figuring out how to make this work.

    GEL scripts are able to open dialog and slider pop-up windows to allow the user to provide input parameters. I don't see any similar facilities in DSS. So my "Select Target Device" option in the above screenshot will need a way for the user to specify which flash device on the board to program. What do you recommend for this?

    Likewise, I would like to be able to show an animated "progress bar" that updates as each of these operations proceeds (i.e. blank check, erase device, program device, verify device). It's not obvious how to get the JavaScript/DSS tools to do this. Can you suggest a way to do this?

    Thank you.

    Andy

  • GEL scripts are able to open dialog and slider pop-up windows to allow the user to provide input parameters. I don't see any similar facilities in DSS. So my "Select Target Device" option in the above screenshot will need a way for the user to specify which flash device on the board to program. What do you recommend for this?

    Ahhh... yes, you are correct. Those nice little GEL GUI items are not supported.via DSS. Hmmm... in that case, it may be necessary to run the custom command from the Scripting Console so that you can call the function with parameters.

    DSS is designed for command-line automation and lacks most GUI items like sliders, progress bars, etc. Any kind of "progress" feedback is usually done the old fashioned way by printing text to a console.

    Going back to the original issue, does using DSS resolve the previous asychronous issues that was occuring with GEL?

    Also note that if you are going to use the scripts only from inside a CCS debug session, then you can shorten your script by using the existing 'activeDS' object to refer to the current debug session in context. That way you can skip the steps of specifying a target config, creating a scripting instance, opening a debug session, etc. 

    https://software-dl.ti.com/ccs/esd/documents/ccs_scripting_console_view.html#services

    Again, activeDS is only useful when running scripts inside an active CCS debug session (it is created when a debug session is launched)