使用Arduino库获取常规AVR代码

时间:2012-11-06 22:32:59

标签: arduino libraries avr

我有一个Arduino Uno和一个Linux环境。虽然Arduino IDE非常棒,但是如果出现问题,它并没有给我太多的意见。它也变得极其缓慢,有时会停止与芯片通信。

另一种方法是使用AVR-GCC / g ++和AVRDude工具链对我的Arduino Uno进行编码。但是,在使用简单的文本编辑器和命令行工具进行编程时,我非常希望能够访问与Arduino相同的函数(如SerialdigitalWrite等)。

所以我试图找到包含所有函数的头文件,即/usr/share/arduino/hardware/arduino/cores/arduino中的“Arduino.h”。

我用它来编译(使用makefile来执行此操作)

avr-gcc -mmcu=atmega328p -I. -gdwarf-2 -DF_CPU=16000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=testarduino.o -I/usr/share/arduino/hardware/arduino/cores/arduino -I/usr/share/arduino/hardware/arduino/variants/standard -std=gnu99 -MMD -MP -MF .dep/testarduino.elf.d testarduino.o --output testarduino.elf -Wl,-Map=testarduino.map,--cref     -lm

编译此代码:

#include "Arduino.h"

int main(void)
{
    init();
    pinMode(13,OUTPUT);
    while(1){
    digitalWrite(13,HIGH);
    delay(1000);
    digitalWrite(13,LOW);
    delay(1000);
    }
    return 0;
}

但是当我尝试编译时(似乎未定义引用'xxxxxxxxx')似乎没有识别出任何函数。那么需要包含哪些确切的头文件以确保我可以使用相同的功能?或者还有其他我想念的东西?

3 个答案:

答案 0 :(得分:21)

如何获取undefined reference

的定义

消息undefined reference to 'xxxxxxxxx'表示链接器无法找到相关函数的实际定义(而不仅仅是声明)。

当链接器找不到函数的定义时,通常可以在lib文件(例如* .so或* .dll)或源文件(例如* .cpp或*)中找到该定义。 C)。对于你的Arduino,你需要告诉avr-gcc编译和链接Arduino * .cpp文件。您需要Arduino核心的所有源文件。

ARDCOREDIR = <my arduino folder>/hardware/arduino/cores/arduino

Sudar提出了很好的建议,提倡使用AVR的Makefile,它配置为包含Arduino函数 definitions 。 (我将链接到我的并在下面解释。)

在我的makefile中,我按如下方式处理了这个操作:

# CPP_SOURCE_FILES is a previously-defined variable, holding my project's source files
CPP_SOURCE_FILES += $(filter-out $(ARDCOREDIR)/main.cpp, $(wildcard $(ARDCOREDIR)/*.cpp))

注意我省略了main.cpp文件,因为Arduino main.cpp文件定义了main(),我希望自己在我自己的项目文件中定义它。

必要的头文件

当然,您还必须为avdu-gcc传递arduino标头的include标志:

-I$(ARDCOREDIR)

您必须在实际项目代码中包含Ardhuino.h文件:

#include <Arduino.h>

Arduino.h头文件将包含所有其他Arduino头文件,包括引脚文件,其中包含Arduino引脚的定义。不同的Arduinos必须有不同的引脚输出文件,因此请确定您使用的是哪种类型,并告诉avr-gcc包含包含相应引脚文件的目录。如果您使用的是标准Arduino(UNO),请使用以下命令:

-I$(ARDCOREDIR)/../../variants/standard

我的Makefile

您的构建过程不仅需要实现上述几条指令,还需要知道如何制作应在Arduino(或AVR)上编程的.hex文件。因此,使用makefile是个好主意。

我不喜欢为每个项目重建我的makefile,所以我的机器上只有一个基本的makefile,每个项目都有自己的非常短的makefile,它调用include来包含基本的makefile。您可以找到my base makefile here

我机器上单个项目的简短(非基础)Makefile示例:

# This is the name of the file that shall be created. (It is also the name of my primary source file, without the file extension.)
TARGET = temp

# create a variable that only pertains to this project
MY_OWN_LIBRARY_DIR = /usr/home/MJ/Arduino/libraries/mj_midi

# "EXTRAINCDIRS" is a variable used by the base makefile. The base makefile creates a -I compiler flag for every item in the "EXTRAINCDIRS" list.
EXTRAINCDIRS = $(MY_OWN_LIBRARY_DIR)

# specify *.c source files pertaining to my project
SRC =

# specify *.cpp source files pertaining to my project
PSRC = temp.cpp $(MY_OWN_LIBRARY_DIR)/midi-listener.cpp $(MY_OWN_LIBRARY_DIR)/midi-song.cpp

# specify additional (non-core) Arduino libraries to include
ARDLIBS = SoftwareSerial

# include my base makefile
include /d/dev/avr/Makefile.base

注意:如果您要使用我的基本makefile,请确保将变量ARDDIR(显示在文件顶部附近)设置为指向计算机上的Arduino目录。

答案 1 :(得分:5)

我使用makefile for Arduino,它允许我同时使用用户和系统库。您不必使用Arduino IDE,但同时可以使用它提供的库。

答案 2 :(得分:1)

您可能希望将Arduino IDE编译选项设置为详细。然后编译一些内容并观察IDE的输出。它将告诉您它在何处找到.cpp文件以及它使用的编译器选项。一旦你查看.cpp文件,你会立即看到你需要包含的内容。

之后,makefile变得更容易理解。如果您之前没有任何经验,我的建议是避免它,而是选择scons。 Scons是Python编写的。因此,您可以立即从更简单的调试中受益。