なんとかなるさね

マイコンをネタにブログを始めてみました


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

関連記事

2014/01/10   blog-entry-403   category: Arduino Lib & CrossGCC

go page top