Debugging
CCS comes with an inbuilt debugger that assists in the detection and correction of logical errors in the microcontroller code. The debugger can be used only if the code is free of syntax errors and the program builds successfully using the build option (hammer symbol in the toolbar). To use the debugger, you should see the below message on the Console window after building the project.
Once you have a project that builds successfully, you can enter into the debug mode by clicking on the DEBUG button (Green color BUG symbol in the toolbar) or by clicking Run -> Debug button from the toolbar.
When the debug button is pressed, CCS loads the program (***.out) on the microcontroller and prepares for the execution of the function main(). After the debug mode is enabled, you should see a display like this :
By default, the Debug window and the Variables window must appear on the screen when you enter the debug mode. If they are not automatically shown, to display the debug window, go to View -> Debug; to display the variables, go to View -> Variables.
To execute the code without any interruption, you press the Resume button (Green play symbol) and to exit the debug mode, you press the Terminate button (Red stop symbol).
When a microcontroller executes a code normally, it executes several hundreds of thousands of instructions every second. It is humanly impossible to trace the execution at this speed. Thus, in order to debug a functional error, it is essential to slow down the execution of the code on the microcontroller. This is the main utility provided by the debugger. The debugger allows you to visualize the execution of code line by line.
The execution of code can be halted at any line by setting a Breakpoint on that line. When a breakpoint is set on a line, the microcontroller executes all the lines of code up to this line and halts before executing this line. To set a breakpoint on a line of code, double-click on the line number. This should insert a small green diamond on the left of the line number. In the below figure, a breakpoint is set on line number 53.
Breakpoints can be used as a powerful tool to check the control flow of the code. Setting breakpoint on a line within a conditional statement can help in quickly identifying if the condition gets satisfied. For example, when a breakpoint is set on line 56 of the above code snippet, and if the code execution hits the breakpoint and halts, it means all the if() conditions in the lines 51, 53, 54 have evaluated to TRUE.
When the execution of code halts, we could choose to execute the code one line after the other using step operation. The CCS debugger has 3 variants of the step operation namely
step into
step over
step return
If there is a function call on any line, the step into operation takes the debugger inside the function and executes all the lines in the function one after the other. This is helpful when the function is newly written and has not been completely verified.
Sometimes when the code invokes a well-tested function or library functions made available by the manufacturer, we could skip debugging inside these functions. To execute a function call without having the debugger to get into the function, use the step over operation.
The step return operation executes all the subsequent lines of code in the current function and halts the execution at the line where this function was invoked from.
All through the stepping process, the CCS debugger lets you view the values of variables available in the current scope. Variables in the current scope are displayed in the Variables window. Each row of this window is a variable and the window displays the name of the variable, type of the variable, the current value stored in the variable and the physical address of the variable. Whenever the value of any variable changes, the variable window highlights it. Using the variables window along with step operations makes the debugging process a lot easier.
The next tool available in the CCS debugger is the Expressions window. The expressions window is similar to the variables window but it can also evaluate arithmetic and logical operations on variables and constants. To enable the expressions window, go to View -> Expressions.
To add an expression, click on the ‘+’ symbol and enter the expression. The result of the expression is displayed in the value column.
Sometimes it is necessary to understand the hierarchy of function calls to debug the code. The debug window displays the hierarchy of functions that were invoked, and the current function is at the top of the hierarchy. For example, in the below image the debugger is currently executing the function makeString() which is invoked inside main().