The 'eye2see' Probe Is an Easy Way to Symbolically Debug a Microcontroller

This external probe works over I2C to enable symbolic debugging on small microcontrollers with minimal pin usage.

Evan Rust
9 months agoCommunication / Productivity / Debugging

The importance of Debuggers

When working with embedded devices, debuggers quickly become an indispensable tool as they allow engineers to peer into the device as it is running for a real-time look at outputs, memory locations, function calls, and errors. However, these capabilities come at both a performance and monetary cost, owing to the additional hardware required to interface a host system with the embedded target. Mark Henderson's eye2see project is different, as it uses the almost universally present I2C protocol to send and receive symbolic debugging information, meaning that no additional pins are required.

A system overview

Although not quite as robust as something like using a J-Link or Atmel-ICE debugger over SWD/JTAG, eye2see still provides a relatively straightforward way to view information. By placing e2clog() and e2clogbrk() statements within the code, specialized C/C++ preprocessor macros are able to replace these lines with I2C commands to either output data or wait for a resume input, respectively. By going with this approach in combination with the TinyI2C library, powerful logging statements and breakpoints can be added with minimal overhead pin costs.

Setting up on a target

Once the macros have been included on the debugee (target device), the programmer must set the peripheral I2C address of the eye2see Probe and signal if the TinyI2C library should be used over the built-in Wire library. Even though the ATtiny85 has a mere 8KB of flash and 512 bytes of RAM, the extra code is still small enough to enable breakpoint debugging on a microcontroller with only 8 pins.

The external device

Most of the magic occurs in the eye2see Probe which acts as the go-between for the target microcontroller and the host computer. Configured in I2C peripheral mode, this versatile device formats incoming information from the debugee into data that can be outputted over USB serial. And it's not limited to a specific microcontroller either, as anything that supports being an I2C peripheral, outputting via USB serial, and the Arduino framework can function as an eye2see Probe. Since Henderson wanted a general device, he developed his version from a Seeed XIAO RP2040, attached a small graphical LCD, and provided a Qwiic connector in addition to software-configurable I2C pullups.

Viewing results

In order to see the data being logged and set/remove/resume breakpoints, Henderson created the py2see application that was built using a Python GUI and runs on a host PC. The top row has areas to select the desired COM port, which I2C address the Probe should use, if pullups should be enabled, and controls for breakpoints. Each line in the debug information table has a timestamp, line number, log value along with the variable name if present, the actual value, and radio buttons to select how the value should be displayed. If the checkbox for a particular breakpoint is set, the program will pause execution the next time it is reached and subsequently resume when the "Resume" button is clicked.

Limitations

The eye2see system is a clever way to gain symbolic debugging capabilities in microcontrollers that ordinarily lack it. However, one large drawback is that execution times are a lot slower due to all of the communication that occurs between the Probe and target device, but Henderson also mentions that some values could be saved from within an interrupt service routine and later logged to prevent time-critical code from failing. More details on the project can be found in Henderson's write-up here.

Evan Rust
IoT, web, and embedded systems enthusiast. Contact me for product reviews or custom project requests.
Latest articles
Sponsored articles
Related articles
Latest articles
Read more
Related articles