SPRAD28 October 2022 AM2431 , AM2432 , AM2434 , AM2631 , AM2631-Q1 , AM2632 , AM2632-Q1 , AM2634 , AM2634-Q1 , AM263P4 , AM263P4-Q1 , AM26C31 , AM26C31-EP , AM26C31M , AM26C32 , AM26C32-EP , AM26C32C , AM26C32M , AM26LS31 , AM26LS31M , AM26LS32A , AM26LS32AC , AM26LS32AM , AM26LS33A , AM26LS33A-SP , AM26LS33AM , AM26LV31 , AM26LV31E , AM26LV31E-EP , AM26LV32 , AM26LV32E , AM26LV32E-EP , AM26S10 , AM2732 , AM2732-Q1
This application note covers the various debugging tools and techniques available to users developing applications with Sitara™ AM2x microcontrollers (MCUs).
Sitara™ and Code Composer Studio™ are trademarks of Texas Instruments.
Arm® is a registered trademark of tm.
Cortex® is a registered trademark of Arm Limited (or its subsidiaries) in the US and/or elsewhere.
All trademarks are the property of their respective owners.
This section covers how to build your application for optimal debugging.
Before debugging your code, disable any compiler optimization. When compiler optimization is enabled, stepping through code can become unpredictable, and breakpoints sometimes cannot be set to the exact line in the C source code. This is because the optimizer can condense code and impact the correlation between the assembly instruction and the C source. Due to this, the recommendation is to turn off compiler optimization when stepping through code.
To disable compiler optimization, go to your project's properties > Build > Arm Compiler > Optimization, and set the optimization level to none or 0. If building with makefiles, this can be done by modifying the makefiles directly. For MCU+ SDK, this is typically done within the submodule's makefile (not the top-level makefile).
The SDK provides two versions of libs: "Debug" and "Release". The "Debug" version is built with optimization disabled, while the "Release" version is built with optimization enabled. The recommendation is to use the "Debug" version of an SDK lib when debugging.
The SDK libs follow the naming convention: "{library name}.{device}.{core}.{compiler}.{version}.lib"
For example, "drivers.am243x.m4f.ti-arm-clang.release.lib" implies the following:
The libraries that are linked to your project can be configured in the project properties under Build > Arm Linker > File Search Path.
This section covers the key debug features offered by Code Composer Studio™ (CCS) for stop-mode debugging. Stop-mode debugging refers to debugging where stopping or halting the core is involved, as opposed to real-time debugging, which involves debugging without stopping the core (real-time debug is discussed in this application note in a later section).
The chip can be debugged using CCS via the JTAG port. If using a Sitara AM2x MCU evaluation board, you can use the on-board JTAG debug probe. There is also typically support for using your own JTAG debug probe via an external header.
To setup your board and debugger for CCS debug, see the EVM Setup section of the MCU+ SDK Getting Started guide for your device to setup your board and debugger for CCS debug.
This section covers breakpoints and watchpoints and how to use them.
Breakpoints are program locations where the processor must halt so that debugging can occur. Both hardware and software break points allow the core to halt at a given PC location.
Watchpoints are breakpoints that can be triggered to halt program execution when a particular memory read or write occurs. Watchpoints are extremely useful to catch exceptions, invalid memory boundary accesses, overrun buffers, and so forth and can be set to access any memory region, including Memory Mapped Registers (MMRs).
A Software breakpoint is implemented as an opcode replacement. The debugger modifies the opcode by inserting an estop_0 instruction where the previous instruction was. The program counter stops immediately before it executes the software breakpoint instruction. In general, this instruction is hidden from the main interface, but in certain instances this instruction is displayed in the Disassembly View. Software breakpoints can only be set in memory regions with write access (RAM), therefore, there is no theoretical limit to the number of software breakpoints that can be used.
To toggle a breakpoint, either double-click on the left side of either the line number in the source code view or the address in the disassembly view, or right-click → Toggle Breakpoint.
CCS allows you to single-step through the code in your program. With the breakpoint set, select Run > Step Into to step into a given function.
You can also select Run > Step Over that executes the function in a single step. This is useful when you do not want to enter a certain function when single-stepping through code.
A Hardware breakpoint is implemented internally by the target hardware. The method used to do this is heavily dependent on the device or core, but typically the debugger writes the address to a register on the device and sets a flag to enable breakpoints. These registers are not exposed to the IDE. A hardware breakpoint can be set in any memory type (RAM, Flash or ROM), but it is limited by the number of registers on the device. This is mandatory for the types of console I/O devices. Hardware breakpoints can also have a count, which determines the number of times a location is encountered before a breakpoint is generated. For example, if the count is 2, a breakpoint is generated every second time. Hardware breakpoints make use of dedicated registers and hence are limited in number. The AM243x supports 8 hardware breakpoints and 8 watchpoints. To see how many hardware breakpoints and watchpoints are supported per device family, see the device-specific technical reference manual.
Watchpoints are a special category of hardware breakpoints that can be triggered for a particular memory read or write. Watchpoints are extremely useful to catch exceptions, invalid memory boundary accesses, overrun buffers, and so forth and can be set to access any memory region, including Memory Mapped Registers (MMRs).
To set a Watchpoint, highlight a variable in the source code editor, right click and select Breakpoint → Hardware Watchpoint. For example, right click on the variable gGpioIntrDone and add a watchpoint. Whenever you press the general-purpose input/output (GPIO) push button, a breakpoint will trigger when gGpioIntrDone increments at the line gGpioIntrDone++; in GPIO_bankIsrFxn().
A common issue causing software instability is stack overflow. When building a project, the stack size is typically specified in the project linker, that corresponding size is allocated for the stack by the linker. A hardware watchpoint can be set to monitor when the location __STACK_END - 2 is written to, which indicates that a stack overflow has occurred.
To open the Registers view: View → Registers.
The Registers view allows for viewing and editing the contents of core and peripheral registers of the device, including bitfields and individual bits.
Type Ctrl+F or right click → Find to search for any register in the register window.