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.

CCS/AWR1843

Other Parts Discussed in Thread: AWR1843, AWR1642, AWR2944

Hello KI, I am using AWR1843, XSD110 debugger and ccs software to build a debugging environment, and when I call the API to write a script to implement automated testing, I find that if I call the run() API, the target board can run successfully, the indicator light will flash, but the control will not be returned to the host application/script, and any operations following the run() command will not be executed, making the program unable to perform other operations. If the runAsynch() API is called, the control can be returned to the host application/script, and the operations after runAsynch() will be executed, but the AWR1843 target board will not be able to run successfully, the indicator light will not flash, if the timeout setting is added, it will display the target board fails to run, why is this? Is there any API that would allow the target board to run successfully, blink the lights and return control to the host application/script? The following are the execution results and script documentation, can you help? thank you very much!

1682.perl_clientOne.txt
BEGIN {
	# Add the @INC path the directory where the DSSClient module is found.
	push (@INC, "dss");
}
use strict;
use warnings;
use DSSClient;

if (scalar(@ARGV) != 2) {
    die "Usage: perl perl_client <local host> <port number>\n";
}

my $host = $ARGV[0];
my $port = $ARGV[1];
#my $portTwo = $ARGV[2];

my $client = new DSSClient($host, $port);
my $cmd = undef;
my $result = undef;

# Connect to the CCS json server.
$client->open();

#Send commands to DSS Test Server
#----------------
# This command does not exist and should FAIL.
$cmd = {
	"name" => "buggyrun",
};
execute_command($cmd);

# Connect to the target.
$cmd = {
	"name" => "connect",
};
execute_command($cmd);

# Demonstrate the use of custom commands (report current timeout value)
$cmd = {
	"name" => "custom_cmd",
};
execute_command($cmd);

# Demonstrate the use of custom commands (report current timeout value)
$cmd = {
	"name" => "custom_cmd",
};
execute_command($cmd);

# Disconnect from the target.
$cmd = {
	"name" => "disconnect",
};
execute_command($cmd);

# Connect to the target.
$cmd = {
	"name" => "connect",
};
execute_command($cmd);

# Connect to the target.
$cmd = {
	"name" => "connect",
};
execute_command($cmd);

# Load program.
$cmd = {
	"name" => "loadProgram",
	"program" => "C:/Tool/JPython/bin/target-config/xwr18xx_mrr_ti_design_mss.xer4f",
};
execute_command($cmd);

# Load program.
# $cmd = {
# 	"name" => "load",
# 	"program" => "C:/Tool/JPython/bin/target-config/xwr18xx_mrr_ti_design_dss.xe674",
# };
# execute_command($cmd);

# Load program.
$cmd = {
	"name" => "loadBinaryProgram",
	"program" => "C:/Tool/JPython/bin/target-config/ROC_LCP_FLASH_debug.bin",
	"address" => "0x510e0000",
};
execute_command($cmd);

# Execute program.
$cmd = {
	"name" => "runAsynch",
};
execute_command($cmd);

# We are done now.

$client->close();

#------------------

# execute command
sub execute_command
{
    $result = $client->execute($_[0]);
    
    if (defined $result) {
        print "$_[0]{name}: ". $result->{"status"} . "\n";  
        # If there is a message, print it
        if (exists $result->{"message"} ) {           
        	print "  message: " . $result->{"message"} . "\n";
        }
        # If a value was returned, print it
        if (exists $result->{"value"} ) {           
        	print "  value: " . $result->{"value"} . "\n";
        }
    } else {
        print "$_[0]{name} execution failed\n";
    }
}

  • , I find that if I call the run() API, the target board can run successfully, the indicator light will flash, but the control will not be returned to the host application/script, and any operations following the run() command will not be executed, making the program unable to perform other operations.

    Yes this is true... unless you set a timeout. Try setting a timeout of several seconds. That will force the run() API to timeout and return (note that the timeout will not impact the running target in any way). Does the program still run successfully?

  • KI, according to what you said, we set a timeout of a few seconds for the clients corresponding to the two cores (the timeout period set by the kernel that runs first is longer than that of the kernel that runs later), the AWR1843 target board can run successfully(if set the same time, the target board may not run), and the control right after the timeout expires will be returned, but the AWR1843 target board will stop running after the timeout throws an exception. I remember that you let us set up two cores as a group, call the run() API and set a timeout, in this case after the timeout returns control, the AWR1843 target board can still continue to run, and the flash will keep blinking. Why is this? Why the two cores are executed separately, and the target board stops flashing after the timeout? We want the AWR1843 target board to run, and the control can also be returned, but the board will not stop running, so that we can continue to run the next script and execute other command operations. Is there any way to solve it? Can you give a solution? Because this is related to our recent project, it is more urgent, I hope you can help us. There is a time difference between our two countries, is there any more effective way to communicate? For example, hold a meeting to discuss when we are all online, I think it may be more effective to communicate this way, what do you think, haha

    Thanks!

  • I have been investigating this further and I believe I can see the issue you are reporting. I have a simple program that blinks the LED. When I run it with runAsynch, the LED does blink. Also, when I run it with the "run" command, the LED will blink until the timeout. Then it will stop blinking. This is the behavior you witnessed also. This should not be the case. I then had similar actions in a standard dss javascript. runAsynch() works as expected (blinking the LED). Same with a run() call with a timeout.

    Hence there appears to be some issue with the TestServer environment. At first glance, I don't see what the issue could be. Even more curious is that I added a custom TestServer command that queries the target status to see if is is halted or not (using the isHalted() API). When I call the command, it returns that the target is NOT halted (even though the LED is not blinking). Hence is the target running incorrectly like you mentioned that you are seeing? Again I don't yet know.

    Support for the TestServer script is somewhat limited so it may take a bit of time to get to the bottom of this. My apologies for the issues.

    ki

  • Ok, thank you for your help, looking forward to your reply.

    After setting the timeout yesterday, we called the run() API, and executed the breakpoint command after that. The console execution prints the result as follows. Does this mean that if the script is used to implement automated testing, when the AWR1843 board is running, it can't be interrupted, right? (To be precise, you can hit a hardware breakpoint, or stop the target board first and then hit a software breakpoint). But if the CCS software is used for manual operation, when the target board is running, both software breakpoints and hardware breakpoints can be hit. This is different from script testing. Why? If we automate the test with scripts, is there a limit to the types of breakpoints?

  • Does this mean that if the script is used to implement automated testing, when the AWR1843 board is running, it can't be interrupted, right?

    Most devices/cpus require the target be halted before a software breakpoint can be set. A software brekapoint is an intrusive step that writes a halt opcode to the memory location. A hardware breakpoint does not require a write to memory.

    Note that this is regarding setting a software brekapoint. Once the software breakpoint is set, a running target will get halted when a breakpoint (hw or sw) is hit.

    ut if the CCS software is used for manual operation, when the target board is running, both software breakpoints and hardware breakpoints can be hit. This is different from script testing. Why? If we automate the test with scripts, is there a limit to the types of breakpoints?

    In regards to breakpoint limitation, that is determined by the device and debugger. Both are the same between scripting and CCS IDE.

    The error in your screenshot is regarding setting a software breakpoint. If you are saying that you are able to set breakpoints in the IDE while target is running but not in the script, then you may be setting hardware breakpoints in the IDE. 

  • Support for the TestServer script is somewhat limited so it may take a bit of time to get to the bottom of this. My apologies for the issues.

    I filed a bug for this. Tracking ID: https://sir.ext.ti.com/jira/browse/EXT_EP-10926

  • Well, I know. However, the location of the software breakpoint (when the target board is running) on the IDE is the same as the position we add on the script. When the target board runs to the breakpoint, it will stop.

  • 我看到你提交的错误。我想解释一下这个错误。我们的双核使用DSS JavaScript编写脚本调用runasynch() API,目标板无法运行;如果我们使用run()和timeout() API,目标板可以成功运行并返回控制,但不能满足逐个运行脚本执行操作的要求,所以你以后给我们提供一个TestServer解决方案,对吧?TestServer解决方案的问题是我们使用run()和timeout() API,控件会返回,但是超时后,目标板会停止,flash会停止闪烁。如果调用 runasynch() API,则返回控制,目标板既不运行也不闪烁。

    In addition, I also want to ask, if we need to read/write the value of a global variable or read/write the value of a local variable at a breakpoint, should we call the read/writeData() API? We are not very understanding of the use of this API and the parameters that need to be passed in. Is there an example? Is there a way to read/write the value of a global variable with its name as a parameter? The API manual on the official website does not explain how to use some of the methods of these classes (just like the runBenchmark() API I asked you about the clock before, there is no explanation for how to use  it), which makes it a little difficult for us to use. I hope that each API can be given a use case.

    谢谢!

  • Yes I do agree that the API document is a bit light on details and can use more examples. 

    As for the read/writeData() API, yes you can use it to read/write a global variable. 

    Details on the parameters:

    public long readData(int nPage,
                         long nAddress,
                         int nTypeSize)
                  throws ScriptingException
    Read a single integer value from the target and return the result as an unsigned integer. Specify the bit length of the type to read in nTypeSize.
    Parameters:
    nPage - memory page
    nAddress - start address to read from
    nTypeSize - bit length

    -memory page value in most cases is '0' unless you have an older C2000 device)

    -you would pass in the address of the global variable you wish to read

    -the bit length would be dependant on the variable type. For example you would pass in '32' for a 'long' or 'word' type.

    To find the address of the global variable, you can use symbol.getAddress("gVariable") where "gVariable" is your global variable. That API will retun the address.

  • I have an AWR1642 which has a Cortex-R4 and a C674x. Looks like the DSP (C674x) supports the ability to set a software breakpoint while the CPU is running. The R4 must be halted to set a software breakpoint. Is this the beahvior you see?

  • Yes, that's right, I just tried it with the IDE.

  • 好的,非常感谢!
    I want to ask is there a solution to our problem? Besides you, is there anyone who can support us to solve CCS problems?

  • Yes, that's right, I just tried it with the IDE.

    This also works as expected with TestServer. I set up one for my AWR1642.Port 4444 is for the R4 and 4445 for the DSP.

    In the screenshots below you can see that for the R4, I could not set a breakpoint while the target is running. For the DSP, I was able to.

  • I want to ask is there a solution to our problem? Besides you, is there anyone who can support us to solve CCS problems?

    Regarding the bug I filed, it seems specific to TestServer. Since TestServer has limited support, there isn't much engineering resources available to investigate. I hope to have some more details later this week. 

  • Yes, the information printed in our black window is the same as you. After calling the runAsynch() API, it returns OK, but the target board light does not flash.

  • ok, thank you very much, we are looking forward to your early reply.

  • After calling the runAsynch() API, it returns OK, but the target board light does not flash.

    Yes this is the mystery I need to investigate...

  • Yes this is the mystery I need to investigate...

    During my investigations, I can see that when a runAsynch is executed, the target runs for a short moment but then halts immediately after. It is similar to when a timeout occurs for the run command. I'm not sure what is triggering the halt, I'm investigating this now.

  • However, our target board will not run at all. When will this question be answered at the latest? Our project is advancing step by step, and integration testing is about to start, but the environment has not been set up yet.
    Thanks

  • I found the root cause of the issue.

    The TestServer script will halt the CPU before closing the connection with the client script. Hence why when you call runAsynch and then the client script finishes execution, the TestServer script will then halt the target before closing connection.

    It is not exactly a bug per se since it is explicitly mentioned in the script that this action is taking place. However I am wondering what the overall purpose of this is. Clearly it is an undesired behavior in cases where you want to leave the target running.

    In any case, you can work around the issue by commenting out line 207 in "TestServer.js":

    Thanks for yoru patience.

    ki

  • Hello,Ki, We tested it according to the method you said. After the first core connection calls the runAsynch() API, the control returns to the target board successfully and the light turns green. After the second core connection calls the runAsynch() API, the control is also returned, but the indicator light of the target board does not flash, why is this? 

  • We try to add two breakpoints with one of the cores, and then call the runBenchmark() API to read the execution time between the two breakpoints, and get a return value of type long. What is the unit of this value? milliseconds or seconds? Is it just the execution time of the code or does it need to be calculated and converted to be the final time value? Our two perl script commands are as follows, please help to see if it is right, thank you!

    perl script.txt
    perl script one:
    $client->open();
    $cmd = {
    	"name" => "connect",
    };
    execute_command($cmd);
    $cmd = {
    	"name" => "setBreakpointByLineNo",
    	"fileName" => "SCHM.c",
    	"lineNo" => "292",
    };
    execute_command($cmd);
    
    # Execute program.
    $cmd = {
    	"name" => "run",
    };
    execute_command($cmd);
    
    # We are done now.
    $client->close();
    
    
    
    perl script two:
    $client->open();
    $cmd = {
    	"name" => "setBreakpointByLineNo",
    	"fileName" => "SCHM.c",
    	"lineNo" => "309",
    };
    execute_command($cmd);
    
    # Execute program.
    $cmd = {
    	"name" => "run",
    };
    execute_command($cmd);
    
    # Read clock.
    $cmd = {
    	"name" => "readClock",
    };
    execute_command($cmd);
    
    # We are done now.
    $client->close();

  • Ki is out today.  He will see your post tomorrow.

    Thanks and regards,

    -George

  • We tested it according to the method you said. After the first core connection calls the runAsynch() API, the control returns to the target board successfully and the light turns green.

    Great!

    After the second core connection calls the runAsynch() API, the control is also returned, but the indicator light of the target board does not flash, why is this? 

    I don't know the reason for this issue. But if you just do a regular run call for the second core, does it blink as expected?

  • What is the unit of this value? milliseconds or seconds? Is it just the execution time of the code or does it need to be calculated and converted to be the final time value?

    It is CPU cycles.

    See the section in the article below called: "Convert Cycles to actual time"

    https://dev.ti.com/tirex/explore/node?node=A__ACh7aaTRwDWC-8ORL0EHMg__ccs_devtools__FUz-xrs__LATEST

  • No, I guess the indicator light on the target board will flash only when the two cores are running together and control is not returned. So we later tried to let both cores call the run() API directly, and then let one of the cores keep runing , another core add two breakpoints and read the clock value. During the whole process, the target board only has a green light, but the clock will return a value, we are not sure whether this value is the execution time between two breakpoints (because we don't know whether the target board has successfully run), so I want you to help us to see if our script is written correctly,is the command sequence like this (add a breakpoint before run, read the clock value after run)?

  • Thank you very much for the information, we have seen how to calculate the clock value. Another question is, how do we know the operating frequency of the target, that is, how do we know the value of CLK? Is this related to the target board? Or is it that most fixed values are 300MHZ?

  • Another question is, how do we know the operating frequency of the target, that is, how do we know the value of CLK? Is this related to the target board? Or is it that most fixed values are 300MHZ?

    The CPU frequency would be specific to the device. This information will be in the documentation for the device itself. Any further questions regarding this should be directed to the device experts.

  • I see you created a command called "readClock". Can you describe what this command does? And where do you enable the clock?

  • The Read clock command is used to read the execution time of the code between two breakpoints. It calls the runBenchmark() API. Our execution sequence is: add breakpoint -> run target -> read clock, the script screenshot is as follows. The final execution result is that after adding the first breakpoint, the return clock cycle count is 1064; after adding the second breakpoint, the return clock cycle count is 1. This is not what we expected. We think that the clock cycle count value after the second breakpoint is added should be greater than the first return value, The value obtained by subtracting the two numbers is converted to the execution time of the code between the two breakpoints. Does the runBenchmark() API automatically clear the previous count before each count?

  • The Read clock command is used to read the execution time of the code between two breakpoints. It calls the runBenchmark() API

    Note that runBenchmark does the following:

    -enable and reset the profile clock 

    -run the target

    -returns the cycle count when halted.

    Note that your perl script is sending a "run" command, followed by a "readClock" command. Esentially you are doing 2 consecutive runs, with only the cycle count of the secound run being returned. 

    Is this what you want?

    Does the runBenchmark() API automatically clear the previous count before each count?

    yes it does. If you wish to not have the clock reset, then you should manually enable the clock, do a standard run, and then do a standard read the clock.

  • Thank you for the git bundle. I'll take a look at let you know as soon as I have anything to report.

  • Thank you for the git bundle. I'll take a look at let you know as soon as I have anything to report.

    Ignore this last post. I meant to reply to different thread and got mixed up.

  • Hello Ki, thanks for your help, we will try the scripting method later. Today we manually debug the code to calculate the execution time between two breakpoints on ccsIDE and turn on the clock. When the R5_0 core of awr2943 stops at the first hardware breakpoint , the clock cycle count is 0, then when it stops at the second hardware breakpoint, the clock cycle count is also 0 (according to the official operation document, after running to the first hardware breakpoint, cancel the breakpoint, then add a second hardware breakpoint , continue execution of the target), why is this? Moreover, we found that the target board did not output any signal. Is it necessary to make the target board run first, and then add breakpoints? But the R5_0 core cannot add breakpoints during operation. Change the hardware breakpoint to software breakpoint, the clock cycle count is still 0. Can you help to answer this question? Thanks! The running screenshot is as follows:

  • Hello Ki,we manually debug the code on ccsIDE,there is an error here. This problem occurs when I start running Coretex_R5_0 after I add clock events and breakpoints. I didn't find any relevant solutions online,plesae help me solve this question, thank you!

  • Hello, Ki, I would like to ask if there is any other method in CCS to read the execution of the code between two breakpoints? besides count event and enable clock. I heard there is also a Cycleprofiler_getTimeStamp() function that calculates the timestamp? How is it used?

  • After testing, we found that in the file under the cortex_R5_0 core, the clock cycle count has no value after the breakpoint is stopped. However, if the file under the C66xx_DSP core, after the execution stops at the breakpoint, the clock cycle count has a value. Why is this? Is it the internal mechanism of the nucleus itself?

  • When the R5_0 core of awr2943 stops at the first hardware breakpoint , the clock cycle count is 0, then when it stops at the second hardware breakpoint, the clock cycle count is also 0 (according to the official operation document, after running to the first hardware breakpoint, cancel the breakpoint, then add a second hardware breakpoint , continue execution of the target), why is this? Moreover, we found that the target board did not output any signal. Is it necessary to make the target board run first, and then add breakpoints? But the R5_0 core cannot add breakpoints during operation. Change the hardware breakpoint to software breakpoint, the clock cycle count is still 0. Can you help to answer this question?

    I'm not sure why the counter value is 0. Can you try using the CCS profile clock under 'Run -> Clock'? See the below article for more details on the Profile Clock:

    https://dev.ti.com/tirex/explore/node?node=A__ACh7aaTRwDWC-8ORL0EHMg__ccs_devtools__FUz-xrs__LATEST

    The value of the Profile Clock should match the Event Counter since I believe they use the same clock. I am able to see valid cycle counts for the R4 of my AWR1642. I don't have an AWR2943 to test with.

    Also see if you can see the clock value increment as you single step.

  • there is an error here. This problem occurs when I start running Coretex_R5_0 after I add clock events and breakpoints. I didn't find any relevant solutions online,plesae help me solve this question, thank you!

    I've never seen this error before. I will need to follow up with engineering

  • Hello, Ki, I would like to ask if there is any other method in CCS to read the execution of the code between two breakpoints? besides count event and enable clock.

    If you are using SYS/BIOS, there are some intrumentation calls that can be used for profiling. My knowledge of SYS/BIOS is limited so this is a question best split out to another thread and answered by the device experts (who support SYS/BIOS)

    There is also 

    I heard there is also a Cycleprofiler_getTimeStamp() function that calculates the timestamp? How is it used?

    See: https://e2e.ti.com/support/sensors-group/sensors/f/sensors-forum/889677/iwr6843isk-ods-cycleprofiler_gettimestamp

  • After testing, we found that in the file under the cortex_R5_0 core, the clock cycle count has no value after the breakpoint is stopped. However, if the file under the C66xx_DSP core, after the execution stops at the breakpoint, the clock cycle count has a value. Why is this? Is it the internal mechanism of the nucleus itself?

    It's quite possible that the R5 of an AWR2943 does not have a profile clock. I've seen this be the case for other devices. 

  • It's quite possible that the R5 of an AWR2943 does not have a profile clock. I've seen this be the case for other devices. 

    I was able to test on an AWR2944 EVM and can confirm that both the profile clock and event counter is available on the R5 and seem to work as expected.

  • Oh,sorry,we found the reason, because we turned on the clock and the clock event in the configuration at the same time, resulting in insufficient clock resources. Today, we tested the execution time of the code between the two breakpoints with the clock event in the configuration, but the final calculated result does not seem to be normal, and the deviation from the estimated value is a bit large. We tested in several places, and the time calculated in the end was a bit off. Is the clock value read by this clock event accurate?

  • Oh,sorry,we found the reason, because we turned on the clock and the clock event in the configuration at the same time, resulting in insufficient clock resources.

    ah, good. 

    Today, we tested the execution time of the code between the two breakpoints with the clock event in the configuration, but the final calculated result does not seem to be normal, and the deviation from the estimated value is a bit large. We tested in several places, and the time calculated in the end was a bit off. Is the clock value read by this clock event accurate?

    The reported cycle count should be pretty accurate. There are some considerations for devices with deep piplines and caching but if you are getting the cycle count between two points, it should be fairly close.

  • Hello Ki, long time no see, we recently re-try the function of clock reading code execution time between two breakpoints with a script, the value of clock cycle read by the script is very different from the clock cycle count we read manually on CCSIDE , our script execution result and script content are as follows, can you help us to check whether the script is correct? Is there any way to verify the correctness of the results obtained by executing the script?Thanks!

  • our script execution result and script content are as follows, can you help us to check whether the script is correct?

    I believe readClock is your custom command and it basically calls the DSS API "runBenchmark". Is that correct? If so, then your client script looks fine. I can't commend on your inmplementation of readClock command since you did not prove the source to that.

    Is there any way to verify the correctness of the results obtained by executing the script?Thanks!

    Turn on IDE visibility while the server script is running. That way you can visually see what is happening while the scripts run:

    https://software-dl.ti.com/ccs/esd/documents/dss_launching_ccs_from_dss.html

    This is very useful for debugging scripts and I actually did this to find the cause of your original issue of why the target was halting after running runAsych

    You can add the line to launch the IDE in the "TestServer.js" script, in the TestServer function after the scritping instance is created.

    Thanks

    ki

  • Yeah,readClock is my custom command that basically calls the DSS API "runBenchmark". Are breakpoints added by add.breakpoint() API on script hardware breakpoints? So I need to remove the first breakpoint before adding the second one when starting the clock event. Later I retried removing the first breakpoint before adding the second one, and the value of the clock cycle looked much more normal. I'll try again tomorrow, as you said, thank you for your help.

  • Are breakpoints added by add.breakpoint() API on script hardware breakpoints?

    It will, assuming the debugging memory map is configured properly. You would get a failure message if it was not.

    Remember that runBenchmark will simply run to the next breakpoint and return the cycte count. Modify your script so that you read the PC before you call readClock and then after so that you know you counted the cycles from the correct addresses. I don't think there is a test server command to the read a register, you'll need to implement it using DSS.

  • What is PC? computer? I remember the official documentation saying that hardware breakpoint can only be added one at a time when the clock event is turned on. We manually debug on CCSIDE when the clock event is turned on,after the target stops at the breakpoint, we will remove the breakpoint, re-add the second breakpoint, and then run the target board again, when the target board stops at the second breakpoint, the clock cycle count read is the clock cycle between the two breakpoints, is that so? If that's the case, as I understand it, when I add a breakpoint on the script and call the runBenchmark API, the target board runs and stops at the breakpoint I added, right? Or does the target board stops at the breakpoint before I call the runBenchmark API?

  • What is PC?

    The Program Counter. It is a register that has the addess of the current location of the program counter. You can see it in the Register view

    I remember the official documentation saying that hardware breakpoint can only be added one at a time when the clock event is turned on.

    This depends on the device since the profile clock will use a hardware breakpoint resource. Some devices (like older C2000 devices) only have two resources. Other devices/CPUs may have more. There should be more than two on C6000 and ARM.

    We manually debug on CCSIDE when the clock event is turned on,after the target stops at the breakpoint, we will remove the breakpoint, re-add the second breakpoint, and then run the target board again, when the target board stops at the second breakpoint, the clock cycle count read is the clock cycle between the two breakpoints, is that so?

    Note that the inside the CCSIDE, the profile clock will keep a cumulative count by default. It does not reset between runs. So if the clock is enabled and then run to a breakpoint, the profile clock will store the cycle count from when it was enabled to when it hit that first breakpoint. So then if you set your second breakpoint and run to it, it will ADD the value of the cycle count between breakpoints AND the original value from when the clock was enabled to the first breakpoint. The clock can be reset by double-clicking on it. You can also adjust the clock properties to auto-reset before each run. The the default behavior is to keep a cumulative count.