# Introduction
This page describes how to setup and use Hardware Breakpoints, Watchpoints, Count Events and Data Access Counts in CCS for C2000 devices.
Hardware breakpoints - halt execution of the processor at a pre-defined place in the code.
Hardware watchpoints - allow execution to halt when a read or write access is made to a data variable address.
Count Event - can be used to measure clock cycles between two points in the code.
Data Access Count - can be used to determine the number of times a data variable address has been accessed.
Since these are all implemented internally by the hardware and require on-chip analysis resources, there is usually a limit to the maximum number of events that can be enabled at one time.
# Configure a Hardware Breakpoint
The steps below describe how to configure a hardware breakpoint in CCS.
1. Configure CCS for a C28x target and launch a debug session.
2. In the Debug Perspective, open the breakpoint dialog from menu **View → Breakpoints**.
3. Use the pull-down menu to select **Hardware Breakpoint**.
![](./images/C28x_hw_breakpoint.png)
4. In the Location field, specify the address where the breakpoint should be set.
Alternately, if the code is programmed to Flash, double-clicking on a line of code in the editor will automatically set a hardware breakpoint.
**Note:** C28x devices have two analysis resources available at a time. One resource can be used as a hardware breakpoint, watchpoint, or counter. The other one can be used as a hardware breakpoint or watchpoint. So when working with hardware breakpoints, there is a limit of 2 hardware breakpoints. If you try to set more than the allowed limit, the following message will appear:
![](./images/C28x_no_aet_resource.png)
In addition, the debugger may use a breakpoint by default to halt at CIO functions, allowing only one breakpoint to be available to the user. This breakpoint can be disabled by going into menu **Run → Debug Configurations → Target** tab, and unchecking the box for **Enable CIO function use**. Also ensure that the box for **Halt at program termination** is also unchecked if you want access to both available breakpoints.
![](./images/C28x_cio_endprogram_bp.png)
# Configure a Hardware Watchpoint
1. Configure CCS for a C28x target and launch a debug session.
2. In the Debug Perspective, open the breakpoint dialog from menu **View → Breakpoints**.
3. Use the pull-down menu to select **Hardware Watchpoint**.
![](./images/C28x_hw_watchpoint.png)
4. In the Location field, specify the address that you want to watch and if the execution should stop on a Read or Write access.
For example, if you want to watch when a global variable named **interruptCount** is written to, for the **Location** field specify **interruptCount**, and for the **Memory** field select **Write**.
![](./images/C28x_hw_watchpoint1.png)
5. The watchpoint can be further customized, if needed, by right-clicking on the watchpoint in the Breakpoints view and selecting **Breakpoint Properties**. Among other things, this dialog allows you to:
- Configure a data read/write of a particular value
- Configure the size of the data
- Configure a mask value (bits that will be ignored)
![](./images/C28x_hw_watchpoint2.png)
# Configure a Count Event
Count Event can be used to count different events, one of them being clock cycles. Using Count Event for measuring clock cycles could be one method of profiling code.
1. Configure CCS for a C28x target and launch a debug session.
2. In the Debug Perspective, open the breakpoint dialog from menu **View → Breakpoints**.
3. Use the pulldown to select **Count Event**.
![](./images/C28x_count_event.png)
4. Select the Event to Count as Clock Cycles.
![](./images/C28x_clock_cycles.png)
5. Enable a breakpoint in your code by double-clicking on the line in the source file.
6. Select the **Resume** icon. When the breakpoint is reached the Count Event will display the number of Clock Cycles.
![](./images/C28x_count_event1.png)
By using two breakpoints this can be used to determine cycle count between two places in the code (useful to profile functions).
1. Enable the Count Event as shown above, then right-click on its entry in the Breakpoints view, select Properties and check the box marked **Reset Count on Run**. This will make the Event counter reset every time the processor is put to run, thus resetting count events within breakpoint boundaries.
![](./images/C28x_count_event2.png)
2. Set two breakpoints in the code.
3. Run to the first breakpoint. The Event counter will count the number of cycles up to this point in your code. You can disregard this number.
4. Run to the second breakpoint. This time the Event count will show the number of cycles between the first and the second breakpoint.
**Note:** If you are setting software breakpoints (ie code is in RAM) then you can set any number of breakpoints. If they are hardware breakpoints or code is in Flash, then you will only be able to set 1 breakpoint if Count Event is enabled. So you would need to run to the first breakpoint, then disable the first breakpoint and enable the second, and run to the second breakpoint.
Also note that the number of CPU cycles can vary greatly depending on the type of memory the code is running from (Flash, RAM, external).
# Configure Data Access Count
Data Access Count can be used to count the number of times a data variable has been accessed.
1. Configure CCS for a C28x target and launch a debug session.
2. In the Debug Perspective, open the breakpoint dialog from menu **View → Breakpoints**.
3. Use the pulldown to select **Data Access Count**.
![](./images/C28x_data_access.png)
4. In the **Location** field, specify the data variable that you want to count accesses for. In the **Memory** field, choose if you want to count Read or Write access.
![](./images/C28x_data_access1.png)
5. Click the **Resume** icon. Halt the code when desired.
6. The **Count** column will display the number of times that variable was accessed up to that point in the code.
![](./images/C28x_data_access2.png)
7. To reset the count between runs, right-click on its entry in the Breakpoints view, select Breakpoint Properties and check the box marked **Reset Count on Run**. This will make the counter reset every time the processor is put to run.
![](./images/C28x_data_access3.png)
# Profiler
The Count Event method described above can be used to profile code. The page [Profiling on C28x Targets](https://processors.wiki.ti.com/index.php/Profiling_on_C28x_Targets) has additional methods and information on profiling code.
# Checking for stack overflow
A common issue causing software instability is stack overflow. When building a project the stack size is typically specified in the project linker options (or in the configuration file for BIOS projects). That corresponding size will be allocated for the stack by the linker. The linker will generate a symbol called __STACK_END (two preceding underscores) that corresponds to the end of stack.
A hardware watchpoint can be set to monitor when the location __STACK_END - 2 is written to which will indicate that a stack overflow has occurred.
1. Configure CCS for a C28x target and launch a debug session.
2. In the Debug Perspective, open the breakpoint dialog from menu **View → Breakpoints**.
3. Use the pull-down menu to select **Hardware Watchpoint**.
4. For **Location**, enter the symbol **__STACK_END - 2**. For **Memory**, select **Write**. This will cause execution to halt every time the processor writes to that address.
![](./images/C28x_stack_overflow.png)