Arduino IDE | Intel Galileo Arduino IDEで作成した実行プログラムをLinuxから実行する時の引数
以前のエントリで書いたように、Linux Arduino互換ライブラリのmain()関数は引数チェックを行っており、
引数が2個未満だった場合は何もせずに実行プログラムを終了させてしまいます。そこで、これも以前の別の
エントリで書いたように、やっつけ作業でmain()関数の殆どを#if 0~#endifで括って除外しました。とは
いえ、あまりに酷いやっつけ作業でしたので、これに関してLinux Arduino互換ライブラリのソースコードを
追っかけてみました。分かったことは、以下の通りです。
(1) 実行プログラムのコマンドラインシンタックスは以下の通り(第3引数<tty2>は指定しないことも可能)
<実行プログラムファイル名> <tty0> <tty1> [<tty2>]
(2) 引数<tty0>,<tty1>,<tty2>で指定したシリアルポートがスケッチのSerial,Serial1,Serial2で使われる
(3) main()関数内で標準出力を強制的に/tmp/log.txtへリダイレクトさせている
(従って、その処理をコメントアウトしないと、標準出力はLinuxのウィンドウには表示されない)
(4) main()関数内で標準エラー出力を強制的に/tmp/log_er.txtへリダイレクトさせている
(従って、その処理をコメントアウトしないと、標準エラー出力はLinuxのウィンドウには表示されない)
main()関数は、以下の通りでした。
ファイル: arduino-1.5.3\hardware\arduino\x86\cores\arduino\main.cpp
int main(int argc, char * argv[])
{
// TODO: disjoin platform ID defined in /sys/firmware/boad_data/plat_id with define PLATFORM_ID
// and refuse to run if identifiers don't match
// Install a signal handler
// make ttyprintk at some point
stdout = freopen("/tmp/log.txt", "w", stdout);
if (stdout == NULL){
fprintf(stderr, "unable to remap stdout !\n");
exit(-1);
}
fflush(stdout);
stderr = freopen("/tmp/log_er.txt", "w", stderr);
if (stderr == NULL){
printf("Unable to remap stderr !\n");
exit(-1);
}
fflush(stderr);
// debug for the user
if (argc < 3){
fprintf(stderr, "./sketch tty0 tty1\n");
return -1;
}
printf("started with binary=%s Serial=%s Serail1=%s\n", argv[0], argv[1], argv[2]);
fflush(stdout);
// TODO: derive trace level and optional IP from command line
trace_init(VARIANT_TRACE_LEVEL, 0);
trace_target_enable(TRACE_TARGET_UART);
// Init IRQ layer
interrupt_init();
// Call Arduino init
init(argc, argv);
#if defined(USBCON)
USBDevice.attach();
#endif
setup();
for (;;) {
loop();
//if (serialEventRun) serialEventRun();
}
return 0;
}
trace_init()関数とtrace_target_enable()関数は、以下のソースにありました。
ファイル: arduino-1.5.3\hardware\arduino\x86\cores\arduino\trace.c
interrupt_init()関数は、以下のソースにありました。
ファイル: arduino-1.5.3\hardware\arduino\x86\cores\arduino\interrupt.c
init()関数は、以下のソースにありました。
ファイル: arduino-1.5.3\hardware\arduino\x86\variants\galileo_fab_d\variant.cpp
追記 : メモ
このぐらいであれば、VMware Player上のUbuntuでも検証出来るだろうと思い、試してみました。しかし、
残念ながら、Linux Arduino互換ライブラリのソースコードそのままではコアダンプしてしまいましたので、
Linux Arduino互換ライブラリのソースコードを変更したところ、以下のように確認することが出来ました。
(なお、以前のエントリで書いたように、VMware Player上のUbuntuでIntel Galileo x86 Linux Arduino
スケッチを実行出来るようにするため、VMware Player上のUbuntuに共有ライブラリを追加しています。)



Linux Arduino互換ライブラリのソースコードを変更した箇所は、以下の通りです。
ファイル: arduino-1.5.3\hardware\arduino\x86\variants\galileo_fab_d\variant.cpp
書き換えた箇所(赤字の箇所)
void init( int argc, char * argv[] )
{
if(argc > 1)
if(Serial.init_tty(argv[1]) != 0)
return;
if(argc > 2)
if(Serial1.init_tty(argv[2]) != 0)
return;
if(argc > 3)
if(Serial2.init_tty(argv[3]) != 0)
return;
sizeof_g_APinDescription = sizeof(g_APinDescription)/sizeof(struct _PinDescription);
// pinInit();
sizeof_g_APwmDescription = sizeof(g_APwmDescription)/sizeof(struct _PwmDescription);
// pwmInit();
sizeof_g_APinState = sizeof(g_APinState)/sizeof(struct _PinState);
}
試したスケッチは、以下の通りです。
void setup() {
Serial.begin(9600);
}
int i = 0;
void loop() {
Serial.print("Hello app!!\r\n");
delay(1000);
if(i++ == 10){ // しまった。++iと書こうとしてi++と書いてしまった。
Serial.print("Done.\r\n");
Serial.end();
exit(0);
}
}
追記 : メモ
またちょっと好奇心から、第1引数のシリアルクラスSerialの入出力先指定を/dev/ttyS1→/dev/ttyと変更
(つまり、ハードウェア仮想化されたCOMポートから通常のLinuxコマンドプロンプトウィンドウへ変更)
してみました。それらしく動いたのですが、残念ながら、その後、Linuxコマンドプロンプトウィンドウで
キーボード入力がエコーバックされなくなってしまいました。(端末設定がシリアル入出力用になったまま
実行プログラムが終了してしまっているのが原因のような気がします。端末設定を元に戻せば直るのかな?)

ちなみに、残念なことに、パイプは期待したようには動作してくれませんでした。(とはいえ想定していた
可能性の範囲内ですが。) それでも、よくよく考えてみればみるほど、今の仕組みでは出来ないことなの
だろうとは思うものの、せっかくのLinuxなのですから何か手はないものだろうか、とも思ってしまいます。

追記 : メモ
もっとずっとIntel GalileoにもLinuxにも詳しい人のブログ
Intel Galileoでprintfを使う
http://jtakao.blog.fc2.com/blog-entry-4.html
Intel Galileoで複数のスケッチを動かしてみる
http://jtakao.blog.fc2.com/blog-entry-5.html
Intel Galileo : トレース出力を活用してみる
http://jtakao.blog.fc2.com/blog-entry-11.html
追記 : メモ
Intel Galileoドキュメントページ
https://communities.intel.com/community/makers/documentation/galileodocuments/content/
Intel Galileoフォーラムページ
https://communities.intel.com/community/makers/content/
追記 : メモ
Intel GalileoダウンロードページからIntel Galileo Linux Examplesというファイルがダウンロード出来る
ようになっていました。スケッチからfgets()関数でボード上のセンサの値を読み出したり、スケッチから
system()関数でLinuxのコマンドを実行したり、といったサンプルプログラムが8個ほど含まれていました。
https://downloadcenter.intel.com/Detail_Desc.aspx?agr=Y&ProdId=3777&DwnldID=23552&DownloadType=%E3%83%A6%E3%83%BC%E3%83%86%E3%82%A3%E3%83%AA%E3%83%86%E3%82%A3%E3%80%81%E3%83%84%E3%83%BC%E3%83%AB%E3%80%81%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB&lang=jpn
引数が2個未満だった場合は何もせずに実行プログラムを終了させてしまいます。そこで、これも以前の別の
エントリで書いたように、やっつけ作業でmain()関数の殆どを#if 0~#endifで括って除外しました。とは
いえ、あまりに酷いやっつけ作業でしたので、これに関してLinux Arduino互換ライブラリのソースコードを
追っかけてみました。分かったことは、以下の通りです。
(1) 実行プログラムのコマンドラインシンタックスは以下の通り(第3引数<tty2>は指定しないことも可能)
<実行プログラムファイル名> <tty0> <tty1> [<tty2>]
(2) 引数<tty0>,<tty1>,<tty2>で指定したシリアルポートがスケッチのSerial,Serial1,Serial2で使われる
(3) main()関数内で標準出力を強制的に/tmp/log.txtへリダイレクトさせている
(従って、その処理をコメントアウトしないと、標準出力はLinuxのウィンドウには表示されない)
(4) main()関数内で標準エラー出力を強制的に/tmp/log_er.txtへリダイレクトさせている
(従って、その処理をコメントアウトしないと、標準エラー出力はLinuxのウィンドウには表示されない)
main()関数は、以下の通りでした。
ファイル: arduino-1.5.3\hardware\arduino\x86\cores\arduino\main.cpp
int main(int argc, char * argv[])
{
// TODO: disjoin platform ID defined in /sys/firmware/boad_data/plat_id with define PLATFORM_ID
// and refuse to run if identifiers don't match
// Install a signal handler
// make ttyprintk at some point
stdout = freopen("/tmp/log.txt", "w", stdout);
if (stdout == NULL){
fprintf(stderr, "unable to remap stdout !\n");
exit(-1);
}
fflush(stdout);
stderr = freopen("/tmp/log_er.txt", "w", stderr);
if (stderr == NULL){
printf("Unable to remap stderr !\n");
exit(-1);
}
fflush(stderr);
// debug for the user
if (argc < 3){
fprintf(stderr, "./sketch tty0 tty1\n");
return -1;
}
printf("started with binary=%s Serial=%s Serail1=%s\n", argv[0], argv[1], argv[2]);
fflush(stdout);
// TODO: derive trace level and optional IP from command line
trace_init(VARIANT_TRACE_LEVEL, 0);
trace_target_enable(TRACE_TARGET_UART);
// Init IRQ layer
interrupt_init();
// Call Arduino init
init(argc, argv);
#if defined(USBCON)
USBDevice.attach();
#endif
setup();
for (;;) {
loop();
//if (serialEventRun) serialEventRun();
}
return 0;
}
trace_init()関数とtrace_target_enable()関数は、以下のソースにありました。
ファイル: arduino-1.5.3\hardware\arduino\x86\cores\arduino\trace.c
interrupt_init()関数は、以下のソースにありました。
ファイル: arduino-1.5.3\hardware\arduino\x86\cores\arduino\interrupt.c
init()関数は、以下のソースにありました。
ファイル: arduino-1.5.3\hardware\arduino\x86\variants\galileo_fab_d\variant.cpp
追記 : メモ
このぐらいであれば、VMware Player上のUbuntuでも検証出来るだろうと思い、試してみました。しかし、
残念ながら、Linux Arduino互換ライブラリのソースコードそのままではコアダンプしてしまいましたので、
Linux Arduino互換ライブラリのソースコードを変更したところ、以下のように確認することが出来ました。
(なお、以前のエントリで書いたように、VMware Player上のUbuntuでIntel Galileo x86 Linux Arduino
スケッチを実行出来るようにするため、VMware Player上のUbuntuに共有ライブラリを追加しています。)



Linux Arduino互換ライブラリのソースコードを変更した箇所は、以下の通りです。
ファイル: arduino-1.5.3\hardware\arduino\x86\variants\galileo_fab_d\variant.cpp
書き換えた箇所(赤字の箇所)
void init( int argc, char * argv[] )
{
if(argc > 1)
if(Serial.init_tty(argv[1]) != 0)
return;
if(argc > 2)
if(Serial1.init_tty(argv[2]) != 0)
return;
if(argc > 3)
if(Serial2.init_tty(argv[3]) != 0)
return;
sizeof_g_APinDescription = sizeof(g_APinDescription)/sizeof(struct _PinDescription);
// pinInit();
sizeof_g_APwmDescription = sizeof(g_APwmDescription)/sizeof(struct _PwmDescription);
// pwmInit();
sizeof_g_APinState = sizeof(g_APinState)/sizeof(struct _PinState);
}
試したスケッチは、以下の通りです。
void setup() {
Serial.begin(9600);
}
int i = 0;
void loop() {
Serial.print("Hello app!!\r\n");
delay(1000);
if(i++ == 10){ // しまった。++iと書こうとしてi++と書いてしまった。
Serial.print("Done.\r\n");
Serial.end();
exit(0);
}
}
追記 : メモ
またちょっと好奇心から、第1引数のシリアルクラスSerialの入出力先指定を/dev/ttyS1→/dev/ttyと変更
(つまり、ハードウェア仮想化されたCOMポートから通常のLinuxコマンドプロンプトウィンドウへ変更)
してみました。それらしく動いたのですが、残念ながら、その後、Linuxコマンドプロンプトウィンドウで
キーボード入力がエコーバックされなくなってしまいました。(端末設定がシリアル入出力用になったまま
実行プログラムが終了してしまっているのが原因のような気がします。端末設定を元に戻せば直るのかな?)

ちなみに、残念なことに、パイプは期待したようには動作してくれませんでした。(とはいえ想定していた
可能性の範囲内ですが。) それでも、よくよく考えてみればみるほど、今の仕組みでは出来ないことなの
だろうとは思うものの、せっかくのLinuxなのですから何か手はないものだろうか、とも思ってしまいます。

追記 : メモ
もっとずっとIntel GalileoにもLinuxにも詳しい人のブログ
Intel Galileoでprintfを使う
http://jtakao.blog.fc2.com/blog-entry-4.html
Intel Galileoで複数のスケッチを動かしてみる
http://jtakao.blog.fc2.com/blog-entry-5.html
Intel Galileo : トレース出力を活用してみる
http://jtakao.blog.fc2.com/blog-entry-11.html
追記 : メモ
Intel Galileoドキュメントページ
https://communities.intel.com/community/makers/documentation/galileodocuments/content/
Intel Galileoフォーラムページ
https://communities.intel.com/community/makers/content/
追記 : メモ
Intel GalileoダウンロードページからIntel Galileo Linux Examplesというファイルがダウンロード出来る
ようになっていました。スケッチからfgets()関数でボード上のセンサの値を読み出したり、スケッチから
system()関数でLinuxのコマンドを実行したり、といったサンプルプログラムが8個ほど含まれていました。
https://downloadcenter.intel.com/Detail_Desc.aspx?agr=Y&ProdId=3777&DwnldID=23552&DownloadType=%E3%83%A6%E3%83%BC%E3%83%86%E3%82%A3%E3%83%AA%E3%83%86%E3%82%A3%E3%80%81%E3%83%84%E3%83%BC%E3%83%AB%E3%80%81%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB&lang=jpn
- 関連記事
-
- QEMU | Linaro ARM Linux GCC 4.7でビルドしたARM Linux ArduinoスケッチをQEMUで実行
- Arduino IDE | Linux Arduino互換ライブラリをCEV Linux SDK V2.00.00 GCC 4.7でビルド→正常終了
- Arduino IDE | Linux Arduino互換ライブラリをUbuntu/Linaro x86 Linux GCC 4.7でビルド→正常終了
- Arduino IDE | Linux Arduino互換ライブラリをLinaro ARM Linux GCC 4.7でビルド→正常終了
- Arduino IDE | Linux Arduino互換ライブラリをUbuntu/Linaro x86 Linux GCCでビルド→途中でエラー
- Arduino IDE | Linux Arduino互換ライブラリをCygwin GCCでビルド→最初からエラー
- Arduino IDE | Intel Galileo Arduino IDEのマイコンボードメニューを冗談半分(?)に増やしてみた
- Arduino IDE | Intel Galileo Arduino IDEで作成した実行プログラムをLinuxから実行する時の引数
- Arduino IDE | Intel Galileo Arduino IDEでcppファイルをコンパイル
- Arduino IDE | Pleiades KeplerとIntel Galileo Arduino IDEでスケッチフォルダとビルドフォルダを共有
- Arduino IDE | Pleiades KeplerでLinux Arduino互換ライブラリをcppファイルから使用する
- Arduino IDE | Pleiades KeplerでLinux Arduinoスケッチのinoファイルをコンパイル
- Arduino IDE | Pleiades Kepler + VMware Player上のUbuntuでLinux Arduinoスケッチをデバッグ (2)
- Arduino IDE | Pleiades Kepler + VMware Player上のUbuntuでLinux Arduinoスケッチをデバッグ (1)
- Arduino IDE | Intel Galileo Arduino IDEのビルドフォルダを変更する
2014/01/10 blog-entry-403 category: Arduino Lib & CrossGCC
| h o m e |