Использование библиотек Arduino для обычного кода AVR

у меня есть Arduino Uno и среда Linux. Хотя Arduino IDE велик и все, однако он не дает мне много входов, если что-то пойдет не так. И он также становится мучительно медленным и иногда перестает общаться с чипом.

альтернативой является кодирование моего Arduino Uno с помощью avr-GCC/g++ и avrdude toolchain. Тем не менее, я очень хотел бы иметь доступ к тем же функциям, что и в Arduino (например,серийный, digitalWrite, etc.) при программировании с помощью простого текстового редактора и командной строки.

поэтому я попытался найти файл заголовка со всеми функциями, определенными ie " Arduino.h " in /usr/share/arduino/hardware/arduino/cores/arduino.

я использовал это для компиляции (используя 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 ответов


как получить определения для undefined reference

означает, что компоновщик не может найти фактический определение (не только объявление) для рассматриваемой функции.

когда компоновщик не может найти определение для функции, это определение обычно можно найти в файле lib (e.g *.так или *.dll) или в исходном файле (например,*.cpp или *.с.) Для вашего Arduino вам нужно сказать avr-gcc, чтобы скомпилировать и связать Arduino *.cpp-файлы. Вам нужны все исходные файлы из ядра Arduino.

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

Судар дал хороший совет, выступая за использование файла Makefile для AVRs, который настроен на включение функции Arduino определения. (Я свяжусь со своим и объясню это ниже.)

в моем 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 основной.файл cpp определяет main(), и я хочу определить его я сам в своих файлах проекта.

необходимые заголовочные файлы

конечно, вы также должны передать avr-gcc флаг включения для заголовков arduino:

-I$(ARDCOREDIR)

и вы должны включить Ardhuino.H-файл в ваш фактический код проекта:

#include <Arduino.h>

Arduino.файл заголовка h будет включать все другие файлы заголовков Arduino, включая файл pinout, который содержит определения для контактов Arduino. Разные Arduinos должны иметь разные pinout файлы, поэтому определите, какой тип вы используете, и скажите avr-gcc включить каталог, содержащий соответствующий файл pinout. Если вы используете стандартный Arduino (UNO), используйте следующее:

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

Мой Makefile

мало того, что ваш процесс сборки должен реализовать несколько инструкций, описанных выше, он должен знать, как это сделать .шестнадцатеричный файл, который должен быть запрограммирован на ваш Arduino (или AVR). Поэтому, хорошая идея использовать a файл Makefile.

мне не нравится перестраивать мой makefile для каждого проекта, поэтому у меня есть только один базовый makefile на моей машине, и каждый проект имеет свой собственный, очень короткий makefile, который вызывает include включить базовый makefile. Вы можете найти моя база makefile здесь.

пример короткого (не базового) файла 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

NB: если вы собираетесь использовать мой базовый makefile, убедитесь, что вы установили переменная ARDDIR (который появляется в верхней части файла), чтобы указать на каталог Arduino на вашем компьютере.


Я использую makefile для Arduino, что позволяет мне как пользователю, так и системным библиотекам. Вы не должны использовать Arduino IDE, но в то же время, можете использовать библиотеки, которые предоставляются им.


вы можете установить параметры компиляции Arduino IDE для подробного. Затем скомпилируйте что-нибудь и посмотрите вывод IDE. Он скажет вам, где он находится .cpp-файл и какие параметры компилятора он использует. Как только вы посмотрите в него .cpp файл вы сразу видите, что вам нужно включить.

после этого makefiles становится намного легче понять. Если у вас нет опыта работы с make, мой совет-избегать этого и вместо этого идти на булочки. Scons пишется Python. Таким образом, вы сразу же извлеките выгоду из гораздо более простой отладки.