Foreword
As you know, the Arduino (AVR) environment does not contain in-circuit debugging functions, which creates great inconvenience when searching for complex errors and supporting projects. I want to show two ways with which you can debug your sketches of different levels of complexity. For the first method, you only need programs, and for the second, you need an inexpensive (compared to the original debugger) adapter, which you can either assemble yourself or buy ready.
In general, nothing new for those who use debuggers all the time, but it can be useful for Arduino users (AVR).
Build with Makefile
Before we get to the description of debugging in the gland (in the second part) we need to practice a little. Probably many people know that the Arduino environment calls the avr-gcc compiler with the whole environment, automatically adjusts the parameters for calling it, and starts the build process. So, we need to repeat this process explicitly. We will not do this manually, although some gestures will still be needed. This is needed in order to get a debug object file in ELF format. The Arduino environment cleans up and we do not have access to either the compiler options or the compilation results.
This brings us to the question of using utilities for the automatic assembly of the avr-gcc project, or more precisely, the sketch with the Arduino libraries. It could be sad, because this is not a simple matter, but as they say, everything has already been done before us. It turns out that github already has everything you need for assembling sketches with Arduino libraries. The project is called
Arduino-Makefile . As it is not difficult to guess from the description, this project contains a Makefile for the automatic assembly of projects on the Arduino. Of the features listed in the description, we will pay attention only to a few.
The Arduino-Makefile package is a set of configuration files, examples, and descriptions. There are no utilities in it that all should use. There is also no development environment, i.e. assembly is carried out through the command line. This means that you can fasten any IDE that is convenient for you, which supports assembly via a Makefile. I usually use Visual Studio.
')
If you look closely at the content, you will notice that there is one global universal Makefile (Arduino.mk) that is included in specific local build files. You need to specify only private (minimum) settings for a specific assembly purpose, and the rest will be done automatically (setting variables, dependency searching, etc.). This is very convenient, as will be shown below.
It is important to note that files with different extensions (* .ino, * .pde, * .c and * .cpp) are supported. The fact is that one of the debuggers will be AVR Studio 4. When you load a debug file into it, the sources in the project tree will be located in different folders: cpp files in sources, and the rest in headers. If we leave the extension for the sketch (ino), the file will not get into the sources and syntax highlighting will not affect it. It is impossible to look at it. Therefore, we note that the extension for sketches during assembly for debugging in AVR Studio needs to be changed to standard (.c or .cpp).
Tools
We found out that we can collect sketches. Now let's see how the assembly and debugging process will be organized. I promised to show two ways. Each of them has its pros and cons. We make them a brief overview.
Method 1 . We create a debug file, load it into Proteus, debug it there.

Advantages:
- relative ease of debugging (with the connection of the monitor of the serial port you only need to suffer);
- access to the outside world through the serial port;
- plotting (virtual measuring devices are available);
- the ability to simulate the circuit in real time;
- in separate windows the registers mk, memory areas, global variables and the source code are available, of course, including its assembler version.
Disadvantages:
- paid Proteus;
- limited set of peripherals;
- complex models can not take into account all the features of the original components.
Method 2 We create a debug file, load it into AVR Studio 4, debug it using the special plug-in Proteus VSM Viewer for AVR Studio 4.

The advantages and disadvantages are almost the same as method 1. You can add that AVR Studio shows a detailed tree of all registers of the simulated micron, up to the bits, which is very convenient. Of the minuses, it is worth noting that debugging optimized code has its own characteristics and it is not so easy to understand how to make the debugger stop at the right places.
Method 3 . We create a debug file, load it into AVR Studio 4, debug it using the JTAG ICE mkII software emulator and a special adapter (HappyJTAG2).

Advantages:
- this is a real debugging in real “hardware” using the JTAG ICE mkII debugger (support for microns up to ATmega2560);
- HappyJTAG 2.45 runs on Windows 7 x64, you only need to skip one window, where they are asked to still buy drivers.
Disadvantages:
- unstable work of HappyJTAG2 with source code of small volume was noticed;
- unstable work of AVR Studio when performing debugging actions;
- The author HappyJTAG2 has long abandoned his brainchild (apparently with the advent of AVR Studio 5 and Atmel Studio);
- some connection features (COM4 or one of the first 4 serial ports should be free or absent, because AVR Studio goes through COM1-COM4 in search of a debugger). It is
free or absent , because HappyJTAG2 works, let's say, from the inside.
As you can see, I showed three methods, but at the present time, only two of them have actually worked for me. The first method will be described in this article. The second method, unfortunately, I could not repeat. You need to find a "compatible" combination of Proteus and AVR Studio. The last studio AVR Studio 4.19.730 and Proteus 7.7 SP2 is used in the picture. Once upon a time I used this method, but in the presence of an iron debugger, using it does not make much sense. The third way I left for the second part. There you will need an adapter and a description of its connection to Arduino boards that support JTAG debugging.
And what do we need for this whole kitchen? First you need to forget about the wretched Arduino IDE, it can only be used for control checks when assembling sketches. Next, we need:
-
Arduino-Makefile - a set of configuration files for manually assembling projects on the Arduino;
- any editor with C ++ syntax highlighting and the ability to execute external commands (
Notepad ++ , VS20xx, Far, ...);
- Proteus 7.x - well-known simulator of mixed (analog-digital) circuits;
- terminal program (
PuTTY , ZOC Pro), which will be analogous to the monitor;
- a program that creates null modem virtual serial ports (VSPD, ...);
-
Arduino IDE 1.6.x (we need libraries and avr-gcc compiler);
-
WinAVR (we need binutils from its bundle, this is a set of unix commands for Windows);
-
avr gcc 4.9.2 (the compiler is fresher if you do not want to use the one that comes with the Arduino IDE);
-
AVR Studio 4.19.730 - the latest version of the Atmel development environment before switching to Visual Studio (only needed for the second part);
-
HappyJTAG 2.45 (only needed for the second part).
We assume that you know how to ask Google where to get all this stuff. Just in case, I will provide useful links at the end of the article. Some comments about the toolkit.
As you know, Proteus is paid, but this is not the saddest thing. Unfortunately, its libraries are not as close to the real world as we would like. For example, you cannot model the Ethernet shield W5100 in it (at least in version 7.x). Therefore, dear followers of Arduino, go the true path. Only debugging and only in hardware will save your souls from the wrong questions. We will use Proteus as a training tool, and in the field - only JTAG.
Debugging Arduino Sketches (AVR) with Proteus 7.x
Enough common words, now specifics. There are many options to start the build process, you can’t write them all, so I’ll focus on exactly one of them and try to describe it clearly. After seeing the general scheme, you can apply it to your set of development tools. For convenience, I will break the description of the whole process into steps, some can be skipped. I hope that even the most inexperienced users of the Arduino will understand what they mean.
Step 1 .
Download and install the Arduino development environment. For definiteness, assume that it will be from the 1.6.x series. I will immediately make a few comments here. In general, from Arduino we only need libraries. Apart from everything else, the very idea of ​​a simplified type of program is very good (if you compare C # and C ++ or, God forbid, C ++ / CLI, then this is heaven and earth). The absence of normal debugging tools led, frankly, to illiterate programming. Instead of consciously turning the conceived algorithm into a program code, Arduino users are
forced to make combinations of magic spells, filter out the information through Serial.print () and only a few try to read the source code of the libraries statically. Hard to look at it all.
I was distracted, and you, probably, managed to put Wednesday on standard ways. It is desirable that the folder Arduino was in the root of the section (C: \ Arduino). This is due to the paths in the makefiles that do not like spaces in the “Program Files”. We will later customize the paths and for those who already have a folder in the “Program Files” have to do one complicated thing for Windows users - the
junction point per folder. Perhaps the space can be escaped, but I have not tried it.
For definiteness, suppose that the path to the environment is: C: \ Program Files \ Arduino.
Step 2 .
Download and unpack Arduino-Makefile. The contents of the folder Arduino-Makefile-master unpack in C: \ Arduino-Makefile. I want to immediately note that inside there is a file README.md, which is better to look at github, where a lot of things are described. You should also note the file arduino-mk-vars.md, which contains the description of the variables used in the user (project) Makefile.
To use the make utility, you need the gnu bin utils kit, which was part of
WinAVR at one time. I do not know if there is an official website for building these same utilities under Windows, but you can proceed as follows. You will need to download the good old WinAVR latest version and pull out the utils folder, where the command utilities are located. You can install, copy the folder and uninstall WinAVR (because it includes the old avr-gcc compiler, which we do not need).
Next, for example, create a folder c: \ avr-gcc and copy utils into it. After this, add the path C: \ avr-gcc \ utils \ bin to the PATH variable (via the Computer properties):
set PATH=C:\avr-gcc\utils\bin;%PATH%
The path must be one of the first in the search.
Do not forget about this change, because it may affect the performance of other programs if you use other similar development environments .
Step 3 . You know where you take / buy Proteus [7.2 - 7.8]. Why exactly this series and such interval of versions? Because I tried them and they seem to be quite good on simple projects. Versions greater than 7.8 could not load the object file of one of my projects in IAR, and below I have not tried. The eight is just buggy for now, maybe then someone will write something about her. Here we will take specifically Proteus 7.8 SP2.
Step 4 . Using the
article , create a junction point on the folder with the installed Arduino environment, i.e. C: \ Arduino should link to C: \ Program Files \ Arduino. This is necessary not to split hairs with the support of gaps in makefiles. So, without copying the folder with the Arduino, we got its copy in the right place for us. Who uses Far'om can use the combination Alt + F6 on the folder.
Change the Arduino environment settings. The path to the folder with the sketches: C: \ Arduino-Makefile \ examples. If you use an external editor (Notepd ++, ...), then you can tick the settings. At the same time, the Arduino will automatically update the contents of its editor when the window is activated. Choose the Arduino Mega 2560 board and the ATmega2560 processor (in fact, it’s not so important what to choose, the main thing is to decide on the controller used).
We write an example program to test the build from the Arduino environment, let's call it Example1 and save it in the sketch folder:
void setup()
{
DDRD |= ( 1 << DDD2 );
}
void loop()
{
PIND |= ( 1 << PIND2 );
}
We compile and check that the build passes. In Arduino 1.6.7, the object file linker (ld.exe) crashed with an error, I replaced it with another one (you can, for example, from
this assembly).
Step 5 . Copy the file C: \ Arduino-Makefile \ examples \ WebServer \ Makefile to the folder with our sketch: C: \ Arduino-Makefile \ examples \ Example1. We fix its contents as follows:
Makefile# Arduino Make file. Refer to https://github.com/sudar/Arduino-Makefile
# Suppress printing of Arduino-Makefile configuration.
#ARDUINO_QUIET = 1
# Directory where the Arduino IDE and/or core files are stored. Usually can be auto-detected as `AUTO_ARDUINO_DIR`.
ARDUINO_DIR = ../../../Arduino
# Directory where tools such as `avrdude`, `avr-g++`, `avr-gcc`, etc. are stored in the `bin/` subdirectory.
AVR_TOOLS_DIR = ../../../Arduino/hardware/tools/avr
# Directory where the `*.mk` files are stored.
# Usually can be auto-detected as parent of `Arduino.mk`.
ARDMK_DIR = ../../../Arduino-Makefile
# Device type as listed in `boards.txt` or `make show_boards`.
BOARD_TAG = mega
# Microcontroller model.
# Usually can be auto-detected as `build.mcu` from `boards.txt`
MCU = atmega2560
#CPU speed in Hz
#Usually can be auto-detected as `build.f_cpu` from `boards.txt`, except in
#some 1.5+ cores like attiny where there is a clock submenu.
#F_CPU = 16000000L
# What name you would like for generated target files.
# Defaults to the name of your current working directory, but with underscores (_) instead of spaces.
#TARGET = project
# Baudrate of the serial monitor.
# Defaults to `9600` if it can't find it in the sketch `Serial.begin()`
MONITOR_BAUDRATE = 9600
DEBUG = 1
DEBUG_FLAGS = -O1 -gdwarf-2 -gstrict-dwarf
include ../../Arduino.mk
We first insert a line at the beginning of our source that explicitly connects Arduino.h (this is not necessary if there are dependencies on the libraries specified in the ARDUINO_LIBS variable):
#include "Arduino.h"
void setup()
{
DDRD |= ( 1 << DDD2 );
}
void loop()
{
PIND |= ( 1 << PIND2 );
}
Do not forget to save the source and Makefile. Next, being in the Example1 folder, entering the make command (using the console or in Far, or in another convenient way), there should be a large wrapper, similar to the one displayed in the Arduino IDE when you turn on the output of full information about the build process. That is, if everything was done correctly, if something did not work out, then try first to understand for yourself what is wrong, and then write comments to the article.
Since we commented out the line ARDUINO_QUIET = 1 in the Makefile, before the assembly information there is a header with the values ​​of the Makefile variables themselves. Some of them are given, while others are calculated in the course of execution. This helps to find errors when editing the project Makefile.
Beginning of footcloth-------------------------
Arduino.mk Configuration:
- [AUTODETECTED] CURRENT_OS = WINDOWS
- [USER] ARDUINO_DIR = ../../../Arduino
Usage: egrep [OPTION]... PATTERN [FILE]...
Try `egrep --help' for more information.
- [USER] ARDMK_DIR = ../../../Arduino-Makefile
- [AUTODETECTED] ARDUINO_VERSION = 167
- [DEFAULT] ARCHITECTURE = avr
- [DEFAULT] ARDMK_VENDOR = arduino
- [DEFAULT] ARDUINO_SKETCHBOOK =
- [USER] AVR_TOOLS_DIR = ../../../Arduino/hardware/tools/avr
- [COMPUTED] ARDUINO_LIB_PATH = ../../../Arduino/libraries (from ARDUINO_DIR)
- [COMPUTED] ARDUINO_PLATFORM_LIB_PATH = ../../../Arduino/hardware/arduino/avr/libraries (from ARDUINO_DIR)
- [COMPUTED] ARDUINO_VAR_PATH = ../../../Arduino/hardware/arduino/avr/variants (from ARDUINO_DIR)
- [COMPUTED] BOARDS_TXT = ../../../Arduino/hardware/arduino/avr/boards.txt (from ARDUINO_DIR)
- [DEFAULT] USER_LIB_PATH = /libraries (in user sketchbook)
- [DEFAULT] PRE_BUILD_HOOK = pre-build-hook.sh
- [USER] BOARD_TAG = mega
- [COMPUTED] CORE = arduino (from build.core)
- [COMPUTED] VARIANT = mega (from build.variant)
- [COMPUTED] OBJDIR = build-mega (from BOARD_TAG)
- [COMPUTED] ARDUINO_CORE_PATH = ../../../Arduino/hardware/arduino/avr/cores/arduino (from ARDUINO_DIR, BOARD_TAG and boards.txt)
- [USER] MONITOR_BAUDRATE = 9600
- [DEFAULT] OPTIMIZATION_LEVEL = s
- [DEFAULT] MCU_FLAG_NAME = mmcu
- [DEFAULT] CFLAGS_STD =
- [DEFAULT] CXXFLAGS_STD =
- [AUTODETECTED] DEVICE_PATH =
- [DEFAULT] FORCE_MONITOR_PORT =
- [AUTODETECTED] Size utility: AVR-aware for enhanced output
- [COMPUTED] BOOTLOADER_PARENT = ../../../Arduino/hardware/arduino/avr/bootloaders (from ARDUINO_DIR)
- [COMPUTED] ARDMK_VERSION = 1.5
- [COMPUTED] CC_VERSION = 4.8.1 (avr-gcc)
-------------------------
mkdir -p build-mega
We assume that everything went well, then you should have a build-mega daddy, in which our long-awaited Example1.elf is the very file for which the whole action was started. With this file we will “brainwash” the virtual mic in Proteus and will heal ... with another degree of freedom.
Step 6 . Let's go back to Proteus. Create a new project (dsn-file)
in the folder with the source . We get the component from the depths of the libraries - the ATmega2560 microcontroller and insert it where it fits, it hurts a lot. Fill in the properties of the component in the picture. It is not necessary to install COMPIM yet, you will need it to work with the monitor.

Then we enter Debug \ Start / Restart Debugging. Get a picture like this.

Well, then, it all depends on the flight of your imagination. In the source window, not only Example1.ino will be available, but other dependent sources as well. You can reveal the assembler code, processor registers, memory, and something else there. Read the dock on Proteus.
Step 7 . You need to configure the monitor. I am too lazy to write, I hope to do it myself. Meaning, in short, such. Create two virtual serial ports connected by a null modem (preferably with numbers greater than COM4). You register one in the COMPIM Proteus component, and the second in the terminal program (PuTTY). Do not forget to correct the speed and encoding of the output in the terminal program, in theory it should match the encoding of the source files, if you want to make a conclusion to the monitor in Russian.
Step 8 . If you want to use
avr gcc 4.9.2 , then you need to put the contents of the archive in the root of the disk and fix the path in the variable AVR_TOOLS_DIR. Only there I did not earn avr-size, it seems. You can change it to the one that comes with WinAVR (or Arduino).
By the way, in order for the size to be displayed in normal form, you need to add an option to the avr-size call (Arduino.mk file):
avr_size = $(SIZE) $(SIZEFLAGS) --format=avr $(1)
Useful links :
1.
Arduino IDE 1.6.x.2.
Arduino-Makefile .
3.
WinAVR .
4.
avr gcc 4.9.2 .
5.
Hard links, etc. in Windows .
6.
PuTTY .
7.
Notepad ++ .