2012/04/16

Arduino の sketch はどうビルドされるか

Arduino IDE は、avr-gcc をつかって、Sketch からファームをビルドしてくれますが、どのような過程でビルドするのか理解しておくと、Sketch を書いたり、ライブラリを作成したりする際の参考になるかもしれません。
参考文献にもあげたArduino Build Processの記述は、若干古いようで、1.0以前の内容が書かれています。以下の説明は、1.0のAruduino IDE のソースコードをもとに再構成して行っています。1.0以前とは若干処理が異なっていますが、大筋で同じことをしていると思われます。


まず、Sketch の構成要素ですが、多くの場合1つの  ino ファイルを使うだけで十分ですが、Arduino IDE は、複数のファイルに分割して Sketch を構成することもサポートしています。"mysketch" という名前の Sketch を作った場合、 "mysketch" という名前のディレクトリの中に


  1. mysketch.pde あるいは.ino
  2. 拡張子なしのファイル (あるいは、pde, ino, h, c, cpp 以外の拡張子のファイル)
  3. 拡張子.hのヘッダファイル
  4. 拡張子.c/.cppのソースファイル


を置くことができます。b〜dのファイルのことをArduino IDE では、”Tab" と読んでいます(Tabの作り方などの操作は連載(9)Arduinoで何でも制御 サンプル・スケッチを動かす(3)などをみてください)。
"mysketch"という Sketch の名前にあたる部分を、"main class name"などと呼んだりします。


cのヘッダファイルはa,b,cから
#include "hoge.h"
のようにダブルクォートでインクルードして使用できます。
bの拡張子なしのファイルは、ビルド時にaの Sketch にマージされます。この機能を利用して、大きなプログラムのソースを複数の Sketch として分割することができます。
Sketch 風の構文ではなく、C/C++ で直に書きたい場合も、そのまま、C/C++ のソースを Tab に含めることができます。この機能のおかげで、テスト段階のライブラリを Sketch ディレクトリにおいてテストしながら作ったり、IDE本体にライブラリを追加することなく、Sketch に固有のライブラリを導入したりすることが可能になっています。


以上のファイルをもとにビルドされる訳ですが、ビルドの処理の概要を順を追って説明します。


1) main sketch file の生成
まず、 main sketch file に Sketch のソースを集約します。
main Sketch file は、1.0以前は、拡張子.S のファイルとして 、main 関数を含むターゲットごとの main.cxx ファイルを追加する形態をとっていましたが、1.0以降は、別ファイルとしてmain.cpp(hardware/arduino/cores/arduino/内)を使い、リンク時に統合される形態にかわっているようです。
main sketch file は、以下のように生成されます。
  1. aとbのファイルをマージして一つにまとめる
    (Sketch::preprocess())
  2. #include <[ファイル名]>を探して、インクルード/リンクするライブラリを収集する
    (PdePreprocessor::writePrefix())
  3. 関数定義を収集し,プロトタイプ宣言を作る
    (PdePreprocessor::writePrefix())
  4. #include "Arduino.h" を挿入する
    (PdePreprocessor::writeProgram())
  5. 3を挿入する
    (PdePreprocessor::writeProgram())
  6. main sketch name に拡張子.cpp をつけて保存します。
    (PdePreprocessor::write())


注目すべきは、2 の段階です。インクルードファイルに指定したヘッダファイルに対応するソースファイルが、リンクの行程でライブラリとしてリンクされることになります。
また、sketch 内では、3の段階で関数プロトタイプ宣言が自動で生成されるので、C言語などと違って、宣言を書かなくても良いようになっています。




2) コンパイル
コンパイルは、
  1. Sketch フォルダ
  2. ライブラリフォルダ
  3. コアフォルダ
単位で行われます。
通常作業ディレクトリはシステムのテンポラリフォルダに作られますが、preferences.txtに
build.path=build
を追加しておくと、作業ディレクトリがArduino IDE と同じディレクトリ内のbuildになります。生成されるファイルを確認するのに便利です。


3) リンク
コンパイルされたオブジェクトファイルとアーカイブファイル、および Cライブラリ libc.a, 数学ライブラリ libm.c がリンクされ、最終的に hexファイルにまとめられます。これがArduino に書き込まれるファームとなります。


以上を図にまとめておきます:




  
(参考文献)
#includeWriting a Library for Arduino

0 件のコメント:

コメントを投稿