#Introduction
For a C28x target, profiling data collection is not enabled in Code Composer Studio
by default.
This article describes how to enable profiling data collection if desired, and
suggests solutions for profiling without using the Code Composer's data collection.
#Other Resources
To discuss technical questions, the E2E Community is a great resource.
Visit [e2e.ti.com](https://.e2e.ti.com).
Forums on the E2E site include:
* [C2000 Forums](https://e2e.ti.com/support/microcontrollers/c2000/f/)
* [Development Tools (CCS, Compiler, DSP/BIOS) Forums](https://e2e.ti.com/support/tools/)
and [many more](https://e2e.ti.com/support/)...
#Profiling Data Collection
This resource is not enabled for the C28x based MCUs by default. This is because
most profiling activities on C28x devices are for code in flash. The hardware function
profiling is breakpoint based, so it is not very useful for code within flash due to
limited hardware breakpoint resources.
If code is based in RAM, then the profiling data collection can be enabled and tried
(see "Enabling Profile Data Collection" towards the end of this article). It should be noted that this is not tested on C28x targets
and is a use at your own risk feature.
#Profiling Solutions for C28x Targets
Here is a list of other solutions that can be used to profile functions within
Code Composer Studio:
**1. Option1 - Profile Clock**
The profile clock uses silicon resources to count cycles between two breakpoints.
When using the profile clock in flash, it is important to free-up as many hardware
breakpoints as possible. On C28x you have two analysis resources available at one
time. One resource can be used as a hardware breakpoint, watchpoint, or counter.
The other one can only be used as a hardware breakpoint or watchpoint. In order to
profile, you need to use the analysis counter which uses up one of your resources
so now you only can set one hardware breakpoint. Code Composer Studio will by default
set a breakpoint for C I/O (printf etc) and the end of program marker. When profiling,
make sure the following options are unselected so the breakpoints will not be used
up by these options:
1. Program load options:
> * **CCS v5 and higher:** Open tools->Debugger options -> Program/Memory Load options
> * **CCS v4:** Open tools->Debugger options -> Generic Options
![](./images/debug-options.jpg)
2. Under Program/Memory Load: Uncheck "Halt at program termination"
3. Under Program/Memory Load: Uncheck "Enable C I/O function use"
![](./images/disable-default-bps.jpg)
4. Optional: Select "Remember my settings" at the bottom of the configuration screen.
To setup the profile clock:
1. In the debug perspective go to
> * **CCS v5 and higher:** Run -> Clock -> Enable.
> * **CCS v4:** Target -> Clock -> Enable.
![](./images/enable-profile-clock.jpg)
This will add a clock icon and count to the status bar.
![](./images/profile-clock.jpg)
2. Run to a breakpoint at the start of the function.
3. Double click on the clock - this will clear its value.
4. Run to a breakpoint at the end of the function
5. The clock will display the delta.
**2. Option 2 - CPU Timer**
Another option customers like to use is to start a CPU timer counting at the SYSCLKOUT frequency.
1. Read the clock before the call
2. Read the clock after the call
3. Subtract the two to get a delta
**3. Option 3 - GPIO Pin**
Another option is to use a GPIO pin:
1. Pull the pin low/high before the function
2. Pull it high/low after the function
3. Read the delta on a scope
#Accessing the Profile Clock via Scripting
The following script may aid in accessing the profile clock through scripts in CCS 5.x.
1. Modify the following script for the location of your project and the addresses where breakpoints should be set.
2. Load the script through the [Scripting Console](https://processors.wiki.ti.com/index.php/Scripting_Console).
> * [Run_benchmark_test.zip](https://processors.wiki.ti.com/images/d/d6/Run_benchmark_test.zip)
3. Loading the script will create a new item in the 'Scripts' menu
Please see the script comments for a description of what it is doing. It should be modified for the project specific symbols.
More information on DSS scripting can be found here:
* [Debug Server Scripting](https://processors.wiki.ti.com/index.php/Debug_Server_Scripting)
* [Java Scripting with DSS](https://processors.wiki.ti.com/index.php/Java_Scripting_with_DSS)
* [Perl Scripting with DSS](https://processors.wiki.ti.com/index.php/Perl_Scripting_with_DSS)
#Profiling in Sys/BIOS
SYS/BIOS provides a 'Timestamp_get32()' API that can be used to benchmark code.
To use this API, you will need to modify your target code to include these APIs.
This is similar to the CPU timer method mentioned above.
In your app.cfg:
```c
Timestamp = xdc.useModule('xdc.runtime.Timestamp');
```
In the app.c file:
```c
#include
UInt32 t0, t1;
t0 = Timestamp_get32();
algo();
t1 = Timestamp_get32();
time = t1 - t0;
```
The API function Timestamp_getFreq() can be used to get the frequency of the Timestamp counter.
#Frequently Asked Questions
**Q: Cycle counts for 'step-by-step' and 'run to line' do not match?**
When single stepping, each instruction goes through the whole pipeline. And then
on the next step, the next instruction will go through the whole pipeline, etc.
There is no potential for a resource conflict between two instructions since each
instruction goes all the way through the pipeline by itself.
If you run or run to line, however, there is the potential for pipeline stalls.
Consider the case where your code is in the same block as data. If you try to read
data you can not fetch an opcode at the same time and there will be a stall. Same
thing for trying to read and write on the same pipeline cycle.
There are other things that can stall the pipe like CPU register conflicts but
these are less obvious to spot.
Refer to this wiki article for more information [C28x Pipeline Conflicts](https://processors.wiki.ti.com/index.php/C28x_Pipeline_Conflicts).
#Enabling Profile Data Collection
As mentioned previously, this functionality is disabled in Code Composer for the
C28x by default. This is because the C28x has limited hardware breakpoints which
are required when using this feature in flash. If you are executing from RAM, you
may find it useful.
[[y Note:
Function profiling for C28x is not officially supported (untested).
]]
To enable HW function profiling with CCSv4 for C28x:
1. Browse to \ccsv4\DebugServer\bin\win32\SerializedProfileActivities
2. Open 'ProfileFunctionsHW.prof_ini' in a text editor
3. Under the list of ISA, add 'TMS320C28' to the list
4. Save file and restart CCSv4
The 'ProfileFunctionsHW.prof_ini' should now look something like:
```c
[Name]
Profile all Functions for CPU Cycles
[Events]
dataclass.pcdt.events.Cycles
dataclass.pcdt.events.CPU Cycles
dataclass.pcdt.events.cycle.Total
[EventClasses]
pcdt
[ISA]
TMS320C28
TMS320C56
TMS320C55
TMS320C621x
TMS320C641x
TMS320C671x
TMS470R1
TMS470R2
TMS470R3
TMS470Rd
TMS470Re
.....
```