Sie sind auf Seite 1von 4

This article has been accepted for publication in a future issue of this journal, but has not been

fully edited. Content may change prior to final publication. Citation information: DOI 10.1109/LES.2016.2619692, IEEE
Embedded Systems Letters

IEEE-ESL-Aug-16-0113 1

Arduino Debugger
Jan Dolinay, Petr Dostálek, and Vladimír Vašek

with Atmel 8-bit MCU ATmega328.


Abstract—This letter describes our source-level debugger for Arguably one of the main limitations of Arduino is its poor
Arduino which can be used to debug the code in Arduino using debugging support. Being able to debug the program is very
GNU debugger (GDB). The presented solution uses Eclipse as the desirable for any larger software project and also learning
visual front-end. It does not require any modification of the
about debugging is an important topic in embedded
Arduino board or additional hardware; debug functionality is
achieved by adding a program library to the user application. programming courses.
Standard functionality expected from a debugger is available, The solution presented in this article makes it possible to
such as setting breakpoints while debugging, stepping through debug programs in Arduino without any extra hardware or
the code and viewing variables. This allows developing projects modification of the board. It only requires adding a program
with Arduino more efficiently and also using the Arduino for library (driver) into the user application. The solution is based
teaching embedded programming at a more advanced level,
on the widely-used GNU debugger GDB.
including debugging the program.

Index Terms—Arduino, Engineering education, BACKGROUND AND RELATED WORK


Microcontrollers, Software debugging. A common way of debugging Arduino programs is sending
text messages to the host computer and using the on-board
LED. These two options are easily available with just a few
INTRODUCTION lines of code, but much better debugging support is available

S INCEits introduction in 2003, the Arduino platform


became a very popular tool for hobby projects with
microcontrollers. But its usage is not limited to the “Maker”
and common in the MCU-based systems nowadays. A typical
MCU, including the ATmega328 used in Arduino Uno, has an
on-chip debug module which allows setting breakpoints,
world. It can be found in research laboratories as an affordable stepping through the code, displaying variables, etc.
and easy-to-use platform for controlling various apparatus or Unfortunately, the Arduino Uno board does not support this.
performing experiments in many areas. For example, [1] If an Arduino user desires more advanced debugging than
describes control of microfluidic devices and the authors of [2] the above mentioned text messages and LED, they can use
used Arduino in psychological and neurophysiological Visual Micro debugger. This software tool allows developing
experiments. The Arduino is also often used in education [4], Arduino projects in Microsoft Visual Studio or Atmel Studio
[5]. It is possible that it will soon become de facto standard [7]. Unlike the Arduino platform, which is an open source, this
platform for teaching embedded systems and similar subjects. tool is not free. Moreover, it does not allow inserting
Arduino is a microcontroller-based prototyping platform breakpoints on the fly or stepping through the code.
which consists of a board with microcontroller (MCU), Another option is connecting to the on-chip debugWire
software framework for this MCU and integrated development interface available in the ATmega328 MCU. However, a
environment (IDE) [3]. There are several boards available special device (debug adapter) is needed. An example of such
ranging from very small, such as Arduino Nano, to powerful a device is AVR Dragon, which is probably the most
boards with 32-bit MCU, such as Arduino Due. In this letter affordable tool for this purpose ($50). The Arduino board
we will be discussing the design of a debugger for probably requires a minor modification to allow using the debugWire
the most used board, Arduino Uno. This board is equipped interface - there is a place on the board which needs to be cut.
Our debugger represents a third option based on the GNU
“This work was supported by the Ministry of Education, Youth and Sports Project debugger (GDB) and the so called GDB stub. The
of the Czech Republic within the National Sustainability Programme project GDB stub (or GDB server) is a piece of code which runs in the
No. LO1303 (MSMT-7778/2014) and also by the European Regional debugged MCU and executes commands from the GDB. We
Development Fund under the project CEBIA-Tech No. CZ.1.05/2.1.00/03”.
J. Dolinay, is with the Department of Automation and Control have decided to use this approach because it requires no
Engineering, Faculty of Applied Informatics, of Tomas Bata University in modification of the hardware, it is free and GDB is accepted
Zlín, nám. T. G. Masaryka 5555, 760 01 Zlín, Czech Republic (e-mail: as a standard for debugging in the industry.
dolinay@fai.utb.cz).
P. Dostálek, is with the Department of Automation and Control
The principle of GDB stub is commonly used on various
Engineering, Faculty of Applied Informatics, of Tomas Bata University in platforms [8], [9], [10]. However, to the best of the authors’
Zlín, nám. T. G. Masaryka 5555, 760 01 Zlín, Czech Republic (e-mail: knowledge, it has not been implemented for the Arduino. We
dostalek@fai.utb.cz).
V. Vašek, is with the Department of Automation and Control Engineering,
have found three projects [11], [12], [13] which implement
Faculty of Applied Informatics, of Tomas Bata University in Zlín, nám. T. G. such a stub code for the Atmel AVR family of
Masaryka 5555, 760 01 Zlín, Czech Republic (e-mail: vasek@fai.utb.cz).

1943-0663 (c) 2016 IEEE. Personal use is permitted, but republication/redistribution requires IEEE permission. See http://www.ieee.org/publications_standards/publications/rights/index.html for more information.
This article has been accepted for publication in a future issue of this journal, but has not been fully edited. Content may change prior to final publication. Citation information: DOI 10.1109/LES.2016.2619692, IEEE
Embedded Systems Letters

IEEE-ESL-Aug-16-0113 2

microcontrollers (the ATmega328 MCU used in the Arduino B. Breakpoint Implementation


Uno board belongs to this family), but none of them usable for Breakpoints are the most important functionality of the
Arduino. Project [11] relies on modifying the flash memory of GDB stub. Breakpoints are used not only to stop the program
the MCU to support breakpoints, which is hard to implement at a user-selected point but are also internally used by GDB
on Arduino as explained in the next section. when the user single-steps through the code.
Project [12] seems to be an unfinished experiment, last In a GDB stub for the ATmega328 MCU a breakpoint can
updated in 2008 and project [13] is not designed to be implemented either by inserting a call to the GDB stub at
communicate with GDB directly. So although each of these the point at which the user requests the program to stop or by
projects provided valuable information for our work, it took comparing current position in the program (the program
combining all three of them to obtain a working solution. counter register PC) with a list of requested breakpoint
addresses. The former method requires erasing and rewriting
IMPLEMENTATION OF THE GDB STUB FOR ARDUINO parts of the flash memory upon any breakpoint insertion. This
Our GDB stub is in principle a program library for the leads to increased wear of the memory and also requires that
ATmega328 MCU used in the Arduino Uno board. This the flash-modification routines of the GDB stub are placed in
library acts as the GDB representative on the target machine. a special section of the MCU memory which is already
It sends and receives any information which GDB needs. The occupied by the Arduino bootloader. Although we believe it is
communication with GDB is carried on via the USB interface possible to somehow combine or link the GDB stub with the
available on the Arduino board, using the same virtual serial Arduino bootloader and implement this method we have
port which is used to upload user programs. However, we decided to use the latter option, which is easier to implement
found the serial connection very unstable with GDB on host and does not affect the life of the program memory. Our GDB
computers with Windows operating systems, probably due to stub keeps an array of breakpoint addresses in RAM memory
non-standard implementation of the virtual serial port driver. and compares these addresses with the current position in the
Therefore we use a proxy server running on the host system program after each machine instruction. If there is a match, the
which communicates with GDB via TCP socket on one side user program is stopped and a message is sent to the debugger
and with the Arduino board via serial port on the other side. on the host system, see Fig. 2. To let the GDB stub do the
For Linux hosts no such proxy is needed. The components and comparison an interrupt must be triggered after the execution
communication interfaces of the debug system are shown in of every instruction of the user program to give control to the
Fig. 1. The dashed line represents the direct connection via stub code. This method is based on the feature of the
serial port which is usable on Linux systems. ATmega328 MCU that one instruction of the main program is
always executed after returning from an interrupt service
routine (ISR) even if another interrupt request is already
pending. We use the external interrupt, configured to trigger
when the associated pin is low, for this purpose. The GDB
stub makes sure that there is continuous request for the
interrupt by configuring the pin as output and driving it low.
The obvious drawback of this method is that it considerably
reduces the execution speed of the program when any
breakpoint is set.

Fig. 1. Configuration of the debug system with our GDB stub.

A. Communication Protocol
Our GDB stub communicates with the debugger using
standard GDB communication protocol called Remote Serial
Fig. 2. Code of the GDB stub for handling breakpoints.
Protocol (RSP). This protocol defines many commands but
only a few are required to make the stub work [9]. The
ANALYSIS AND DISCUSSION
following commands are implemented in our stub:
• Last signal (?) The GDB stub was tested on computers with Windows 7,
• Set thread (H) and is thread alive (T) Windows 10 and Linux Mint 17 operating systems in the
• Read registers (g) and write registers (G) Eclipse IDE versions Luna (4.4.2) and Mars (4.5.0) with build
• Read memory (m) and write memory (M) tools and GDB obtained from Arduino IDE version 1.6.8. It
should be possible to use the stub with any other IDE which
• Detach the debugger (D) and kill request (k)
allows configuring GDB for debugging. It is not possible to
• Continue (c) and step (s)
use the Arduino IDE, because it does not have any support for
• Insert (Z) and remove (z) breakpoint debugging. Testing environment with Windows 7 laptop
• Basic query requests (qSupported, qC, thread info) computer can be seen in Fig. 3.

1943-0663 (c) 2016 IEEE. Personal use is permitted, but republication/redistribution requires IEEE permission. See http://www.ieee.org/publications_standards/publications/rights/index.html for more information.
This article has been accepted for publication in a future issue of this journal, but has not been fully edited. Content may change prior to final publication. Citation information: DOI 10.1109/LES.2016.2619692, IEEE
Embedded Systems Letters

IEEE-ESL-Aug-16-0113 3

A. Usage of the Debugger Fig. 4 shows the call stack which indicates that the program
To explain the usage of the debugger we will describe is stopped in micros function which was called from the delay
simple use case with the traditional Arduino sample program function which was itself called from the loop function (see
which blinks the on-board LED connected to pin 13. also Fig. 5 with the loop function code).

Fig. 3. Testing environment with Windows 7 computer running the Eclipse


IDE with GDB. Arduino Uno is connected via USB cable.

To use the proposed debugger the user first needs to add the
code of the GDB stub into their project. The code is located in
two files, avr8-stub.c and avr8-stub.h.
Then a call to debug_init function must be placed in the
initialization part of the user code. In a typical Arduino Fig. 5. Sample program with two breakpoints inserted. The program is
stopped at the first one.
program this will be in the setup function, which is executed
once upon power up or reset, see Fig. 5.
The user can, for example, insert breakpoints into the loop
Once the program is built and uploaded to the board a
function or step through the code using the Step into or Step
debug session can be configured and started. The Eclipse IDE
over buttons in the IDE. Fig. 5 shows the code with two
acts as a visual front-end to the GDB debugger which
breakpoints inserted and the program stopped at the first one.
connects to the GDB stub code running in the target MCU.
The connection with the debug target can use the Arduino B. Use Cases
virtual serial port directly on Linux hosts, for example, To illustrate the benefits of using the debugger let us take
/dev/ttyS0. On Windows hosts the connection is established the same sample program as earlier but this time with an error
via free TCP-to-serial proxy server hub4com. – a misspelled call to the delay function with the argument
Unless a breakpoint has been pre-set in the code the missing. The code can be seen in Fig. 6.
program in the target MCU is now freely running and the on- The compiler will issue a warning but if the user ignores it,
board LED is blinking. The program can be stopped using the it is possible to upload and run the program. But instead of
Suspend button in the IDE. It will be stopped at arbitrary blinking, the LED will be continuously on. With a debugger at
position, most likely inside the delay function, as can be seen hand the user can connect to the program and suspend it. Then
in Fig. 4. they can step through the program line by line and see that
stepping over the first call to delay function takes a noticeable
amount of time but the second call to delay is skipped
immediately. This indicates that the problem is on this line of
the program and the user is now likely to notice the missing
argument.
As another use case let us consider similar program with
busy loop delay instead of the Arduino delay function. There
is a hard-to-find error in the for loop – the variable “i” used as
the loop counter is too short (16 bits) to ever reach the value
against which it is compared (100,000). As a result the loop
never finishes. The visible result is that the LED is always on
Fig. 4. The call stack of the test program after it has been stopped by the because the program never returns from the first call to the
debugger. delay function.

1943-0663 (c) 2016 IEEE. Personal use is permitted, but republication/redistribution requires IEEE permission. See http://www.ieee.org/publications_standards/publications/rights/index.html for more information.
This article has been accepted for publication in a future issue of this journal, but has not been fully edited. Content may change prior to final publication. Citation information: DOI 10.1109/LES.2016.2619692, IEEE
Embedded Systems Letters

IEEE-ESL-Aug-16-0113 4

modify the delay function for debugging purposes. In our


experience it is possible to cope with this limitation, for
example, by inserting and removing breakpoints as needed
(this is fast operation with no side effects such as rewriting the
program memory in our solution). There is also a breakpoint
function available in our stub which can be used to insert
Fig. 6. Sample program with the argument missing in the second call to delay
breakpoints at compile time which do not affect the execution
function.
speed of the program. The source code of our stub and
detailed instructions for use can be found at
(http://www.codeproject.com/Articles/1037057/Debugger-for-
Arduino).

CONCLUSION
Fig. 7. Delay function with busy loop. The for loop will never end because In this letter we presented a source-level debugger for
the 16-bit variable i can never reach value 100,000. Arduino. It offers a unique option for debugging Arduino
programs with the standard GNU debugger GDB. Together
If the user connects to the program with the debugger and with Eclipse IDE this allows building a complete development
suspends it, the program will be stopped inside the mydelay environment for micro-controller applications based on free
function. The user can hoover the mouse over the “i” variable software and hardware. Having a debugger allows developing
to see its value. This may be some arbitrary number, e.g. 8466, programs for Arduino more efficiently and also using the
as shown in Fig. 8. Resuming the program for a while and Arduino for teaching embedded programming on a more
suspending it again it is possible to observe the changes of the advanced level, including debugging the program.
value. Yet a better approach will be to place a breakpoint at Our solution is implemented as the so called GBD stub,
the last line of the mydelay function, i.e. at the closing brace. which is a code running on the debugged micro-controller. It
The program should stop at this breakpoint after the loop provides common functionality expected from a debugger,
finishes. Since it never stops, it is clear that the loop never such as setting and removing breakpoints while debugging,
finishes. Finding the reason why it never finishes may take stepping through the code and inspecting variables.
some time still, but at least the location and reason of the
incorrect program behavior were quickly identified. REFERENCES
[1] E. T. da Costa, M. F. Mora, P. A.Willis, C. L. do Lago, H. Jiao, and C. D.
Garcia, “Getting started with openhardware: Development and control of
microfluidic devices,” Electrophorensis, vol. 35, pp. 2370–2377, Aug.
2014.
[2] A. D’Ausillio, “Arduino: A low-cost multipurpose lab equipment,”
Behavior Research Methods, vol. 44, no. 2, pp. 305-313, Jun. 2012.
[3] Anon. (2015, May). Arduino Home Page. [online]. Available:
http://arduino.cc
[4] P. Bender, K. Kussmann, “Arduino based projects in the computer
science capstone course,” Journal of Computing Sciences in Colleges,
vol. 27, no. 5, pp. 152-157, May 2012.
Fig. 8. Inspecting the value of the variable i. [5] P. Jamieson. (2012, April). Arduino for Teaching Embedded Systems.
Are Computer Scientists and Engineering Educators Missing the Boat?
C. Memory Utilization and Performance [online]. Available
Our debugger stub requires approximately 5 kB of program www.users.muohio.edu/jamiespa/html_papers/fecs_11.pdf
[6] Anon. (2015, February). Why Arduino is not the right educational tool.
memory (flash) out of the 32 kB available in the MCU, and [online]. Available: http://www.hackvandedam.nl/blog/?p=762
255 Bytes of RAM (out of 2 kB available). We consider this to [7] Anon.(2015, February). Arduino IDE for Microsoft Visual Studio and
be acceptable for most Arduino projects. Someone developing Atmel Studio. [online]. Available: http://www.visualmicro.com
[8] H. Li, Y. Xu, F. Wu, C. Yin, "Research of “Stub” remote debugging
a cutting-edge application will probably use a hardware technique," Proceedings of 2009 4th International Conference on
debugger rather than our software solution. Computer Science & Education, Nanning, China, 2009, pp. 990-993.
As already mentioned, when breakpoints are set, the [9] J. Bennett. (2015, February). Howto: GDB Remote Serial Protocol,
Writing a RSP Server. [online]. Available:
debugged program runs at a significantly reduced speed. The http://www.embecosm.com/appnotes/ean4/embecosm-howto-rsp-server-
overall effect depends on the design of the debugged program. ean4-issue-2.html
For example, the Arduino delay function, which is internally [10] M. Tan (2015, February) A minimal GDB stub for embedded remote
debugging. [online]. Available:
implemented by polling hardware timer, is slowed down by a http://www.cs.columbia.edu/~sedwards/classes/2002/w4995-02/tan-
factor of 4 - a one second delay takes four seconds to execute. final.pdf
If a simple busy loop is used to generate a delay, the delay will [11] R. Pen. (2015, May). AVR-GDB Server. [online]. Available:
be stretched approximately by a factor of 350 - a busy loop https://github.com/rouming/AVR-GDBServer
[12] I. Doornekamp (2015, May). AVR gdbstub. [online]. Available:
which normally takes 100 milliseconds will take about 35 http://zevv.nl/play/code/avr-gdbstub.
seconds to execute. In such a case it will be necessary to [13] S. Vakulenko. (2013, June). uOS - embedded operating system. [online].
Available: https://code.google.com/p/uos-embedded.

1943-0663 (c) 2016 IEEE. Personal use is permitted, but republication/redistribution requires IEEE permission. See http://www.ieee.org/publications_standards/publications/rights/index.html for more information.