Data Breakpoints Lab

 Objective

A data breakpoint instructs the debugger to pause execution when a data memory location is “touched” by either reading from it or writing to it.

A data breakpoint may be configured to break when a specific value is read or written. In this exercise, we will be looking for a specific value to be written to the LCD. In particular, we will look for the less-than (<) character, which is the first of the string “<Hello>“ that has been written to the display in previous labs. We’ll accomplish this by setting a data breakpoint on the PMDIN1 register, which is used for each command and character sent to the LCD module. There are two places in the program where this register is written: the lcdInit() and lcdPutChar() functions.

 Materials

Hardware Tools (Optional)

Tool About Purchase
Explorer16-50px.png
Explorer 16
Development Board
REALICE-50px.png
MPLAB® REAL ICE™
In-Circuit Emulator
ICD3-50px.png
MPLAB® ICD 3
In-Circuit Debugger

Software Tools

Tool About Installers
Installation
Instructions
Windows Linux Mac OSX
MPLAB® X
Integrated Development Environment
MPLAB® XC16
C Compiler
Proteus VSM
Visual, Interactive Simulator Demo

Exercise Files

File Download
Installation
Instructions
Windows Linux Mac OSX
Project and Source Files

 Procedure

1

Open the project Breakpoints.X

If you haven't already done so, click on the Open Project button Main_Open_Project.png and open the Breakpoints.X project. If you have not downloaded the Breakpoints Project yet, you can find it in the Exercise Files section of this page.

2

Set a Data Breakpoint

If the breakpoint tab isn’t already open, select from the menu:
Window > Debugging > Breakpoints.

In the window’s sidebar, click on the Create new breakpoint button:

NewBreakpoint.png

3

Configure Data Breakpoint

In the window that opens:

  • Set Breakpoint Type to Data
  • For the Symbol, click on the Symbols button
  • Select the SFR's radio button, and select PMDIN1 from the list, then click the OK button.
DataBreakpoint.png

The Address field should automatically populate after performing the step above.

  • For Breaks on, select Write Specific Word.
  • For the Value, enter 0x003C (the ASCII value for ‘<‘ = 0x3C = 6010)
  • For the Pass Count Condition, leave it set to Always Break.
  • Click OK.

4

Debug the Project

Click on the Debug Project button: Main_Debug_Project.png

5

Open the Disassembly window

Open the Disassembly window. You should see something like the following:

OpenDisassemblyWindow.png

If you look two instructions above the program counter’s position (green arrow in glyph margin, green highlight in editor) you will see a line that writes to the PMDIN1 register. So it looks like we caught our event. However, if you scroll to the top of the disassembly window you will see that the first line is, !void lcdInit(void).

So we are in the LCD initialization routine, not lcdPutChar(), which writes text to the display. Look at the Watches tab that you should have opened at the very beginning of the lab:

Watches.png

The value in PMDIN1 is indeed the value we were looking for. The problem is that this is a command to the LCD module that happens to have the same data that we were looking for. This value is not a character being written to the display, so it isn’t what we want.

6

Continue to run the program

Since we are still in the lcdInit() routine, we haven’t even begun to write text to the display. We need to continue the program to get to the point we are interested in.

Click on the Continue button: Debug_Continue.png

The program should run again until the next breakpoint event.

7

Observe the second event

When the program halts a second time, the Disassembly window should automatically pop up. You should see something like the following:

SecondDisassemblyWindow.png

Now we can clearly see from the top line that we are in the lcdPutChar function, which means that data is being written to the LCD instead of initialization commands. This is more promising. Look at the Watches tab again to verify that PMDIN1 contains the data we are looking for:

SecondWatchesTab.png

OK, this is much better. This is what we were looking for. Notice also that there was skid involved, just like with address and line breakpoints. The Program Counter is two instructions past the event where the program wrote to PMDIN1. As a result, there was enough time for the character to be displayed on the LCD before the program stopped. The LCD should be showing:

LCDScreen.png

Also, you may have noticed the gray highlight and gray box in the glyph margin on line 10, where the write to PMDIN1 takes place. This is the disabled address breakpoint we set in the previous exercise. It had no effect at this time.

8

Clean up for the next exercise

Do not remove or disable the data breakpoint at this time. We will be using it in the next exercise on Tuples.

a

Click on the Finish Debugger Session button: Debug_Finish_Debugger_Session.png

b

Change the Configuration box on the toolbar (Main_Combo_Box.png) to show REAL_ICE.

 Conclusions

In this exercise, you set a data breakpoint and observed its behavior in a disassembly window and with a Watches window when used with a hardware debugger and in the simulator.

Now, the question we need to ask after this experience is, can we set up a breakpoint so that we only catch the write in lcdPutChar() and don’t stop in the lcdInit() function? The answer is ‘yes’, and we will explore this in the next exercise.

© 2020 Microchip Technology, Inc.
Notice: ARM and Cortex are the registered trademarks of ARM Limited in the EU and other countries.
Information contained on this site regarding device applications and the like is provided only for your convenience and may be superseded by updates. It is your responsibility to ensure that your application meets with your specifications. MICROCHIP MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND WHETHER EXPRESS OR IMPLIED, WRITTEN OR ORAL, STATUTORY OR OTHERWISE, RELATED TO THE INFORMATION, INCLUDING BUT NOT LIMITED TO ITS CONDITION, QUALITY, PERFORMANCE, MERCHANTABILITY OR FITNESS FOR PURPOSE. Microchip disclaims all liability arising from this information and its use. Use of Microchip devices in life support and/or safety applications is entirely at the buyer's risk, and the buyer agrees to defend, indemnify and hold harmless Microchip from any and all damages, claims, suits, or expenses resulting from such use. No licenses are conveyed, implicitly or otherwise, under any Microchip intellectual property rights.