Arduino代码调试(AVR)。第1部分。虚拟调试

前言


如您所知,Arduino(AVR)环境不包含在线调试功能,这在搜索复杂错误和维护项目时会带来极大的不便。我想展示两种调试不同难度级别的草图的方法。对于第一种方法,您只需要程序,而对于第二种方法,您需要便宜的(与原始调试器相比)适配器,您可以自己组装或购买现成的适配器。
通常,对于经常使用调试器的用户而言,没有什么新鲜的东西,但对于Arduino(AVR)的用户可能有用。

用Makefile编译


在介绍硬件调试(第二部分)之前,我们需要进行一些培训。也许很多人知道Arduino环境会在整个环境中调用avr-gcc编译器,自动配置用于调用它的参数并开始构建过程。因此,我们需要明确地重复此过程。尽管仍然需要一些手势,但我们不会手动执行此操作。为了获得ELF格式的调试对象文件,这是必需的。 Arduino环境会自行清理,我们无法访问编译器选项或编译结果。

这给我们带来了使用实用程序自动构建avr-gcc项目,或更确切地说是带有Arduino库的草图的问题。在这里会很难过,因为这不是一件简单的事情,但是正如他们所说,一切都已经摆在我们面前。事实证明,github已经具备使用Arduino库组装草图所需的一切。该项目称为Arduino-Makefile。从描述中不难猜测,该项目包含一个Makefile,用于在Arduino上自动构建项目。在描述中列出的功能中,我们将仅关注其中一些。

Arduino-Makefile软件包是配置文件,示例和描述的集合。没有实用程序应该使用所有这些。也没有开发环境,即汇编是通过命令行完成的。这意味着您可以固定任何方便的IDE,这些IDE支持通过Makefile进行汇编。我通常使用Visual Studio。

如果仔细查看内容,您会发现有一个全局通用Makefile(Arduino.mk),该文件包含在特定的本地程序集文件中。您只需要为程序集的特定目的指定专用(最小)设置,其余设置将在自动模式下完成(设置变量,搜索依赖项等)。如下所示,这非常方便。

请务必注意,支持具有各种扩展名(* .ino,* .pde,* .c和* .cpp)的文件。事实是,其中一个调试器将是AVR Studio4。将调试文件加载到其中时,项目树中的源文件将位于不同的文件夹中:源文件中的cpp文件,头文件中的其余文件。如果我们保留草图的扩展名(ino),则该文件将不会进入源文件,并且语法高亮将不起作用。看不到它。因此,我们注意到在AVR Studio中调试时在装配过程中草图的扩展名需要更改为标准(.c或.cpp)。

工具包


我们发现我们可以收集草图。现在让我们看一下组装和调试过程的组织方式。我答应展示两种方式。每个人都有其优点和缺点。让我们简要地回顾一下它们。

方法1。我们创建一个调试文件,将其加载到Proteus中,然后在此处进行调试。 优点: -调试相对容易(通过串行端口监视器的连接,您只需要折磨自己); -通过串行端口访问外界; -绘制图表(可使用虚拟测量仪器); -实时仿真电路的能力;








-当然,在单独的窗口中,可以使用寄存器mk,存储器区域,全局变量和源代码,包括其汇编程序版本。

缺点:
-付费Proteus;
-外围设备数量有限;
-复杂的模型不能考虑原始组件的所有功能。

方法2。我们创建一个调试文件,将其加载到AVR Studio 4中,使用用于AVR Studio 4的特殊Proteus VSM Viewer插件对其进行调试。



优点和缺点与方法1的优点和缺点几乎相同。您可以添加AVR Studio显示模拟微米的所有寄存器的详细树,直到位为止,这非常方便。在缺点中,值得注意的是,调试优化的代码具有其自身的特性,而且不容易理解如何使调试器停在正确的位置。

方法3。我们创建一个调试文件,将其加载到AVR Studio 4中,使用JTAG ICE mkII软件仿真器和一个特殊的适配器(HappyJTAG2)对其进行调试。 优点: -这是使用JTAG ICE mkII调试器(支持ATmega2560的麦克风)在真实硬件中进行的真实调试; -HappyJTAG 2.45可在Windows 7 x64上运行,您只需要跳过一个窗口,无论如何他们都会要求您购买驱动程序。

 





缺点:
-发现源代码较小的HappyJTAG2运行不稳定;
-执行调试操作时AVR Studio的工作不稳定;
-HappyJTAG2的作者早就放弃了他的创意(显然是随着AVR Studio 5和Atmel Studio的出现);
-连接的某些功能(COM4或前四个串行端口之一应为空闲或不存在,因为AVR Studio通过COM1-COM4进行迭代以寻找调试器)。它是免费的还是不存在的,因为可以这么说,HappyJTAG2从内部起作用。

如您所见,我展示了三种方式,但目前只有两种方式实际上为我赚了钱。本文将介绍第一种方法。不幸的是,我无法重复第二种方法。您需要找到Proteus和AVR Studio的“兼容”组合。图中使用了最新的Studio AVR Studio 4.19.730和Proteus 7.7 SP2。曾几何时,我使用这种方法,但是在有铁调试器的情况下,使用它没有多大意义。在第二部分中,我离开了第三种方法。在那里,您将需要一个适配器及其对支持JTAG调试的Arduino板的连接的描述。

我们整个厨房需要什么?首先,您需要忘记烦人的Arduino IDE,它仅可在组装草图时用于控件检查。接下来,我们将需要:

-Arduino-Makefile-一组用于在Arduino上手动组装项目的配置文件;
-一些具有C ++语法突出显示功能的编辑器,并具有执行外部命令的能力(Notepad ++,VS20xx,Far等);
-Proteus 7.x-混合(模拟-数字)电路的著名模拟器;
-终端程序(PuTTY,ZOC Pro),它将类似于监视器;
-创建空调制解调器虚拟串行端口(VSPD,...)的程序;
- Arduino的IDE的1.6.x版(我们需要的库和编译器GCC编译);
- WinAVR中(我们需要的binutils从他的包,适用于Windows一套UNIX命令的);
- AVR海合会4.9.2(如果您不想使用Arduino IDE随附的版本,则编译器会更新);
- 在AVR Studio的4.19.730 - Atmel的开发环境才去到Visual Studio(需要只有第二部分)的最新版本;
- HappyJTAG 2.45(仅需要用于第二部分)。

我们将假设您知道如何询问Google在哪里获得所有这些家庭。为了以防万一,我将在文章结尾处提供有用的链接。关于工具箱的一些评论。

如您所知,Proteus是有偿的,但这并不是最可悲的事情。不幸的是,他的图书馆并不像我们想要的那样接近现实世界。例如,您不能在其中建模以太网屏蔽W5100(至少在版本7.x中)。因此,Arduino的亲爱的追随者们走了正确的道路。仅调试,并且仅在硬件中进行调试,才能使您免于提出错误的问题。我们将Proteus用作培训工具,并且在现场-仅JTAG。

在Proteus 7.x中调试Arduino草图(AVR)


足够用于常用词,现在具体说明。开始组装过程有很多选择,您不能全部写下来,所以我将只集中讨论其中一个,并尝试对其进行清楚地描述。看到一般方案,您可以将其应用于您的开发工具集。为了方便起见,我将分步细分整个过程的描述,有些可以跳过。我希望即使是最没有经验的Arduino用户也能理解它的含义。

第1步资料下载并安装Arduino开发环境。为了确定起见,让我们假设它将来自1.6.x系列。在这里,我将立即发表一些意见。通常,我们只需要Arduino的库。除了其他所有内容之外,简化程序形式的想法非常好(如果比较C#和C ++,或者,上帝禁止使用C ++ / CLI,那么这就是天堂。)坦率地说,缺乏常规的调试工具导致了编程失误。 Arduino用户没有自觉地将设想的算法转换为程序代码,而是被迫制作魔术咒语的组合,通过Serial.print()过滤掉信息,只有少数尝试静态读取库源代码。这很难看。

我分心了,您可能设法以标准方式设置环境。建议将Arduino文件夹放在分区的根目录下(C:\ Arduino)。这是由于makefile路径不喜欢Program Files中的空格。稍后,我们将为那些在“程序文件”中已经有文件夹并且必须做Windows使用者难以完成的事情的人配置路径- 文件夹上的连接点。也许可以逃脱空间,但是我还没有尝试过。

为了明确起见,假设环境路径为:C:\ Program Files \ Arduino。

第2步资料下载并解压缩Arduino-Makefile。将Arduino-Makefile-master文件夹的内容解压缩到C:\ Arduino-Makefile中。我要立即注意到,在其中有一个README.md文件,最好查看github,那里描述了很多东西。您还应该注意文件arduino-mk-vars.md,其中包含用户(项目)Makefile中使用的变量的描述。

为了使make实用程序正常工作,您需要使用gnu bin utils工具包,该工具包是WinAVR的一部分在适当的时候。我不知道是否有一个官方站点可以为Windows组装这些相同的实用程序,但是您可以执行以下操作。您将需要下载最新版本的旧版WinAVR,然后从中拉出utils文件夹,该文件夹是命令实用程序所在的位置。您可以安装,复制文件夹并卸载WinAVR(因为它包括旧的avr-gcc编译器,我们不需要它)。

接下来,例如,创建一个文件夹c:\ avr-gcc并将utils复制到该文件夹​​。之后,将路径C:\ avr-gcc \ utils \ bin添加到PATH变量(通过“计算机”属性): 该路径应该是搜索中的第一个路径。不要忘记这一变化,因为如果使用其他类似的开发环境,它可能会影响其他程序第三步

set PATH=C:\avr-gcc\utils\bin;%PATH%



。您自己知道在哪里可以买到Proteus [7.2-7.8]。为什么要确切地讲这个系列以及如此间隔的版本?因为我尝试过它们,而且看似简单的项目,所以它们相当不错。 7.8以上的版本无法在IAR中加载我的项目之一的目标文件,而在下面的版本中我没有尝试。八个目前只是越野车,也许有人会写一些关于她的东西。在这里,我们将特别采用Proteus 7.8 SP2。

第4步。使用本文,在已安装Arduino环境的文件夹上创建一个交点,即C:\ Arduino应参考C:\ Program Files \ Arduino。这是必要的,以免在makefile中支持空格。因此,无需使用Arduino复制该文件夹,我们就可以在正确的位置获得它的副本。谁使用Far可以在文件夹上使用Alt + F6组合键。

我们更改Arduino环境的设置。带有草图的文件夹的路径:C:\ Arduino-Makefile \ examples。如果使用外部编辑器(Notepd ++,...),则可以检查设置。同时,当窗口激活时,Arduino将自动更新其编辑器的内容。我们选择Arduino Mega 2560开发板和ATmega2560处理器(实际上,在这里选择什么并不重要,主要是确定所使用的控制器)。

我们编写了一个示例程序来测试Arduino环境中的程序集,将其命名为Example1并将其保存在sketch文件夹中: 编译并验证程序集是否通过。在Arduino 1.6.7中,目标文件链接器(ld.exe)因错误而崩溃,我将其替换为另一个文件(例如,来自程序集)。第5步

void setup()
{
DDRD |= ( 1 << DDD2 );
}

void loop()
{
PIND |= ( 1 << PIND2 );
}



将文件C:\ Arduino-Makefile \ examples \ WebServer \ Makefile复制到我们的草图文件夹中:C:\ Arduino-Makefile \ examples \ Example1。我们将其内容修复如下:

生成文件
# 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

我们在源代码的开头插入显式连接Arduino.h的行(如果ARDUINO_LIBS变量中指示有库依赖项,则不需要这样做): 不要忘记保存源代码和Makefile。接下来,在Example1文件夹中,我们输入make命令(使用控制台或在Far中,或以另一种便捷的方式),这将出现一个大的脚印,类似于Arduino IDE中显示的有关构建过程的完整信息的输出。这是如果一切都正确完成,但是如果某些事情不起作用,则首先尝试独立地了解问题所在,然后在文章上发表评论。

#include "Arduino.h"

void setup()
{
DDRD |= ( 1 << DDD2 );
}

void loop()
{
PIND |= ( 1 << PIND2 );
}



由于我们注释掉了Makefile中的ARDUINO_QUIET = 1行,因此在有关程序集的信息之前,有一个带有Makefile本身变量值的标头。其中一些已指定,而其他一些则随着进度进行计算。这有助于在编辑项目的Makefile时发现错误。

鞋垫的开始
-------------------------
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


我们假设一切顺利,那么您应该拥有一个超级大型爸爸,在其中,我们期待已久的Example1.elf是开始执行所有操作的文件。有了这个文件,我们将“洗脑” Proteus中的虚拟麦克风并以另一种自由度进行治疗。

第6步。回到Proteus。在源文件夹中创建一个新项目(dsn文件)。我们从库中取出组件-ATmega2560微控制器,然后将其插入合适的位置,这确实很痛苦。在图片中填写组件的属性。还不需要安装COMPIM;您将需要它与显示器一起使用。 然后我们进入调试模式Debug \ Start / Restart Debugging。获取一张看起来像这样的图片。







好吧,这一切都取决于您的想象力。在源代码窗口中不仅可以使用Example1.ino,还可以使用其他从属源。您可以打开汇编代码,处理器寄存器,内存等。阅读Proteus上的基座。

第7步。您需要设置一个监视器。写懒惰,我希望自己做。简而言之,意思是这样。您创建两个通过空调制解调器(最好是数字大于COM4)连接的虚拟串行端口。您在COMPIM Proteus组件中指定了一个,在终端程序(PuTTY)中指定了第二个。不要忘记在终端程序中纠正输出的速度和编码,理论上,如果要用俄语将输出输出到监视器,它应该与源文件的编码一致。

第8步。如果要使用在avr gcc 4.9.2中,您需要将归档文件的内容放在磁盘的根目录中,并在变量AVR_TOOLS_DIR中修复路径。似乎只有avr大小对我不起作用。您可以将其更改为WinAVR(或Arduino)随附的版本。

顺便说一句,在正常形式需要输出的大小的选项添加到通话AVR-大小(文件Arduino.mk):相关链接 1. Arduino的IDE的1.6.x版 2. Arduino-Makefile 3. WinAVR 4. AVR海合会4.9.2 5. Windows中的硬链接等 6. 腻子 7. 记事本++

avr_size = $(SIZE) $(SIZEFLAGS) --format=avr $(1)










Source: https://habr.com/ru/post/zh-CN390427/


All Articles