web-dev-qa-db-ja.com

通常のAVRコードにArduinoライブラリを使用する

Arduino UnoとLinux環境があります。 Arduino IDEは素晴らしいですが、何かがうまくいかない場合は入力が多くありません。また、非常に遅くなり、チップとの通信が停止することがあります。

別の方法は、AVR-GCC/g ++とAVRDudeツールチェーンを使用してArduino Unoをコーディングすることです。ただし、単純なテキストエディターとコマンドラインを使用してプログラミングしながら、Arduinoと同じ機能( SerialdigitalWrite など)にアクセスしたいツール。

そこで、/usr/share/arduino/hardware/arduino/cores/arduinoに定義されているすべての関数、つまり「Arduino.h」を含むヘッダーファイルを見つけようとしました。

これをコンパイルに使用しました(メイクファイルを使用してこれを行います)

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'への未定義の参照)。それで、同じ関数を使用できるようにするために含める必要がある正確なヘッダーファイルは何ですか?または私が逃した他に何かありますか?

20
Adwait Dongare

_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は、Arduino関数definitionsを含むように構成されたAVRの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))
_

Arduinoのmain.cppファイルがmain()を定義しているので、main.cppファイルを省略していることを確認します。自分のプロジェクトファイルで自分で定義したいと考えています。

必要なヘッダーファイル

もちろん、arduinoヘッダーのincludeフラグもavr-gccに渡す必要があります。

_-I$(ARDCOREDIR)
_

また、実際のプロジェクトコードにArdhuino.hファイルを含める必要があります。

_#include <Arduino.h>
_

Arduino.hヘッダーファイルには、Arduinoピンの定義を保持するピン配置ファイルを含む、他のすべてのArduinoヘッダーファイルが含まれます。 Arduinoごとに異なるピン配置ファイルを使用する必要があるため、使用しているタイプを特定し、適切なピン配置ファイルを含むディレクトリを含めるようにavr-gccに指示します。標準のArduino(UNO)を使用している場合は、以下を使用します。

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

私のメイクファイル

ビルドプロセスは、上記のいくつかの指示を実装する必要があるだけでなく、Arduino(またはAVR)にプログラムされる.hexファイルを作成する方法を知る必要があります。したがって、makefileを使用することをお勧めします。

プロジェクトごとにメイクファイルを再構築したくないので、マシンにベースメイクファイルを1つだけ持っています。各プロジェクトには、includeを呼び出してベースメイクファイルを含める独自の非常に短いメイクファイルがあります。 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ディレクトリを指すように設定してください。

21
JellicleCat

私は Arduinoのmakefile を使用します。これにより、ユーザーライブラリとシステムライブラリの両方を使用できます。 Arduino IDEを使用する必要はありませんが、同時に、提供されているライブラリを使用できます。

5
Sudar

Arduino IDEコンパイルオプションを詳細に設定することをお勧めします。次に、コンパイルしてIDEの出力を確認します。これにより、.cppファイルの場所と使用するコンパイラオプションがわかります。 .cppファイルを調べると、何を含める必要があるかがすぐにわかります。

その後、メイクファイルがはるかに理解しやすくなります。 makeの経験がない場合は、回避してsconsを使用することをお勧めします。 SconsはPythonで書かれています。したがって、はるかに単純なデバッグからすぐにメリットが得られます。

1
Udo Klein