An address breakpoint instructs the debugger to pause execution when the program counter hits a specific address in program memory.
For this exercise, we are going to use an address breakpoint to halt the program on a line of code that writes to a register used for displaying characters on the LCD of the Explorer 16 Evaluation Board.
We will also observe the address breakpoint's behavior in a disassembly window as a:
- hardware breakpoint
- software breakpoint
- breakpoint in the simulator
Hardware Tools (Optional)
|Tool|| About|| Purchase|
If using hardware, either the REAL ICE™ or MPLAB ICD 3 can be used with the Explorer 16 board.
| Windows|| Linux|| Mac OSX|
Integrated Development Environment
Visual, Interactive Simulator Demo
This lab was tested using MPLAB X v3.00
| Windows|| Linux|| Mac OSX|
Project and Source Files
Open the project Breakpoints.XIf you haven't already done so, click on the Open Project button 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.
Build the project for debugging without running it
During the debug process, we have to take special steps to determine a line of code’s physical address in memory. A project needs to be built first, so that the linker assigns addresses to everything. However, while debugging we must account for the memory space used by the debug kernel. So ideally we would like to perform a debug build, without launching the debugger and running the program. For this, we can use the discrete debugger operations.
From the menu, select:
Debug > Discrete Debugger Operation > Build for Debugging (Project Breakpoints)
This will build our project exactly as if we had clicked on the Debug Project button, but now it will not download the program to the debugger or run it on the target.
Open the Disassembly Listing File
From the menu, select:
Window > Debugging > Output > Disassembly Listing File (Project Breakpoints)
This will open the disassembly listing produced by the linker in the previous step. From here we can determine the address of any line in our program.
Search for a file/function in the Disassembly window
For this exercise, we’re interested in a line of code inside the lcdPutChar() function (in the libLCD24/lcdPutChar.c file).
void lcdPutChar(char ch)
PMADDR = 0x0001;
PMDIN1 = ch;
To find where it is in the disassembly listing file, select Edit > Find from the Main Menu (make sure the Disassembly tab is selected in the editor). A text box will appear at the bottom of the editor. Enter the following text into it: void lcdPutChar. This will find the section of the disassembly file that applies to this function.
Get address of instruction that sends characters to LCD
Look down to the line that starts with 15: - this is the C source we are interested in. Two instructions below that is the line where a character is written to the LCD. Its address is the first six digits at the beginning of the line. This address will likely be different on your machine. Make a note of it…
Open the Breakpoints window
From the menu select:
Window > Debugging > Breakpoints
Debug the project
Even if the debugger you have connected is the ICD3, selecting REAL_ICE as the configuration will work.
When the program hits the breakpoint and halts, the file lcdPutChar.c should open in the editor. You will see the program counter pointing to line 16 - one line below the C statement that contains the address breakpoint.
Open the Disassembly window
From the menu, select: Window > Debugging > Disassembly.
Here we can see that address breakpoints exhibit skid just like line breakpoints. Note that the program counter is two addresses ahead of the breakpoint.
Like their line breakpoint counterparts, address breakpoints exhibit no skid effect when software breakpoints are enabled or when debugging in the simulator. The only exception to this is when a line breakpoint or address breakpoint is part of a complex breakpoint. Even if software breakpoints are enabled, any breakpoint that is part of a sequence or tuple will be implemented as a hardware breakpoint. We’ll discuss complex breakpoints in the next pages.
Feel free to experiment with address breakpoints in the simulator or with software breakpoints enabled as you did with line breakpoints lab. You will see that they behave in exactly the same way.
Clean up for the next exercise
DO NOT remove the address breakpoint at this time. We will be using it in a subsequent exercise on Tuples. For now we’ll simply disable it.
Go to the Breakpoints window. If it isn’t open, from the menu select: Window > Debugging > Breakpoints. Then uncheck the box next to the address breakpoint.
With the address breakpoint disabled, it will not cause the code to halt, but its location is remembered by the IDE so that we can easily re-enable it when needed later. Also, while this breakpoint is disabled, we are freeing up an additional hardware breakpoint resource.
This lab helped us to see the differences and similarities between line and address breakpoints. An address breakpoint, unlike a line breakpoint, doesn’t “move around” as source code is changed. Also, it is not restricted to being set on the first assembly instruction representing a line of C code.