4.4.11 Advanced Debugging (AVR JTAG/debugWIRE devices)

I/O Peripherals

Most I/O peripherals will continue to run even though the program execution is stopped by a breakpoint. Example: If a breakpoint is reached during a UART transmission, the transmission will be completed and corresponding bits set. The TXC (transmit complete) flag will be set and be available on the next single step of the code even though it normally would happen later in an actual device.

All I/O modules will continue to run in Stopped mode with the following two exceptions:

  • Timer/Counters (configurable using the software front-end)
  • Watchdog Timer (always stopped to prevent Resets during debugging)

Single Stepping I/O Access

Since the I/O continues to run in Stopped mode, care should be taken to avoid certain timing issues. For example, the code:

OUT PORTB, 0xAA
IN TEMP, PINB

When running this code normally, the TEMP register would not read back 0xAA because the data would not yet have been latched physically to the pin by the time it is sampled by the IN operation. A NOP instruction must be placed between the OUT and the IN instruction to ensure that the correct value is present in the PIN register.

However, when single-stepping this function through the OCD, this code will always give 0xAA in the PIN register since the I/O is running at full speed even when the core is stopped during the single-stepping.

Single Stepping and Timing

Certain registers need to be read or written within a given number of cycles after enabling a control signal. Since the I/O clock and peripherals continue to run at full speed in Stopped mode, single stepping through such code will not meet the timing requirements. Between two single steps, the I/O clock may have run millions of cycles. To successfully read or write registers with such timing requirements, the whole read or write sequence should be performed as an atomic operation running the device at full speed. This can be done by using a macro or a function call to execute the code, or use the run-to-cursor function in the debugging environment.

Accessing 16-Bit Registers

The Microchip AVR peripherals typically contain several 16-bit registers that can be accessed via the 8-bit data bus (e.g., TCNTn of a 16-bit timer). The 16-bit register must be byte accessed using two read or write operations. Breaking in the middle of a 16-bit access or single-stepping through this situation may result in erroneous values.

Restricted I/O Register Access

Certain registers cannot be read without affecting their contents. Such registers include those which contain flags which are cleared by reading, or buffered data registers (e.g., UDR). The software front-end will prevent reading these registers when in Stopped mode to preserve the intended non-intrusive nature of OCD debugging. In addition, some registers cannot safely be written without side-effects occurring - these registers are read-only. For example:

  • Flag registers, where a flag is cleared by writing ‘1’ to any bit. These registers are read-only.
  • UDR and SPDR registers cannot be read without affecting the state of the module. These registers are not accessible.