なんとかなるさね

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


Arduino IDE | Intel Galileo ArduinoスケッチにLinuxのスレッド制御関数を書いてビルドしてみた 

CEV Linux SDK V1.00.00のセットアップフォルダ内にあった'samples'フォルダの'kensa'プログラムですが、
これまで試した通り、幾つかのGCCでビルドした結果、スレッド制御に関する部分とファイル排他制御に関する
部分がコンパイルエラーになるGCCとならないGCC(Linuxと互換性が高いものと低いもの)に2分されることに
気付きました。Intel Galileo x86 Linux Arduino互換ライブラリに使用されているi586-poky-linux-uclibcと
いうGCCは互換性が高いグループだと思い、'kensa'プログラムを参考にArduino IDEでLinuxのスレッド制御
関数を書いてみたところ、コンパイルエラー無くビルド出来ました。(ただし、動くかどうか分かりませんが。)
もし、CEV-RZ/A1L Linuxでも同じようにIDEが使えたら、それはそれで、ちょっと面白そうな気がしました。
(Arduino互換ライブラリが無かったとしても。でも、ボードへのダウンロード機能と実行機能は、絶対欲しい
ところです。)



試しに書いてみたスケッチは、以下の通りです。

#include <stdio.h>

int quit_flag = 0;

void *thread_led(void *arg)
{
  for ( ; !quit_flag ; ) {
    usleep(300000);
  }
  return NULL;
}

void setup() {
  pthread_t mythread;

  quit_flag = 0;
  if ( pthread_create( &mythread, NULL, thread_led, NULL/*arg*/ ) ) {
    printf("error creating thread.");
    abort();
  }

  quit_flag = 1;
  if ( pthread_join ( mythread, NULL ) ) {
    printf("error joining thread.");
    abort();
  }
}

void loop() {
}


ちなみに、Intel Galileo x86 Linux Arduino互換ライブラリの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;
}


追記 : メモ

前のエントリで、Windows上のIntel Galileo Arduino IDEでビルドしたプログラムを、VMware Player上の
Ubuntuにコピーし、実行しようして失敗した
のですが、main()関数の引数チェックが怪しいような気がして
きました。

    // debug for the user
    if (argc < 3){
        fprintf(stderr, "./sketch tty0 tty1\n");
        return -1;
    }


追記 : メモ

main()関数を見ていて、以下のコードに気付いたのですが、そういえば、Intel Galileo x86 Linux Arduino
互換ライブラリで端子入力割り込みをどのように処理しているのか気になります。Arduino互換ライブラリ
では、端子入力割り込みハンドラ関数は、ユーザが登録したユーザ記述の関数の筈ですので。

    // Init IRQ layer
    interrupt_init();


端子入力割り込みに関しては、以下のソースに記述されているようですので、後日、追っかけてみたいです。

ファイル: arduino-1.5.3\hardware\arduino\x86\cores\arduino\interrupt.c

ちらっと見た印象では、スレッドが起動されてデバイスドライバからの割り込み検出イベントを待っている
ようです。つまり、全体の流れとして、Linuxのプロセスの1つとしてスケッチが起動され、そこでLinuxの
スレッドの1つとして端子入力割り込みディスパッチャが起動され、割り込み検出イベントの発生を待って、
適宜、ユーザが登録したユーザ記述の割り込みハンドラ関数の呼び出しが行われるようです。

追記 : メモ

なお、interrupt.cでLinuxのスレッド制御関数が使用されていましたので、上で試しに書いてみたスケッチも
動くような気がします。

追記 : メモ

よくよく考えてみると、x86 Linux Arduino互換ライブラリ(いわゆるクラスライブラリというもの)がリンク
された普通のLinuxプログラムのような気がしますので、コンパイル/リンク時に-gオプション(デバッグ情報
生成オプション)付きでビルド出来れば、普通のLinuxプログラムと同様にGDBとかGDB/GDBSERVERとかで
普通にデバッグ出来てしまいそうな気がします。

追記 : 雑感

Linuxのデバイスドライバとか、こんな風に作る(IDE上でゴソゴソと作る)ことって、出来ないものなのかな?
(もっとも、Linuxのデバイスドライバを作らずに済ますことが出来れば、それに越したことは無いのですが。)

追記 : 雑感2

ひょっとして、TOPPERS SafeGを使うと、ハードウェア制御部分がリアルタイムカーネル側のプログラムで
実装されることになって、結果的に、Linuxのデバイスドライバを作らずに済ませられたりするのかな? RX
マイコンやRL78マイコン的な処理はリアルタイムカーネル側でやって、既存のデバイスドライバで事足りる
パソコン的な処理だけLinux側でやって、というように、、、 (もちろん、半導体ベンダやボードベンダから
提供されるボードサポートパッケージ内のマイコン専用デバイスドライバは、使わせてもらうとして、、、)

関連記事

2013/12/24   blog-entry-392   category: Arduino Lib & CrossGCC

go page top