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側でやって、というように、、、 (もちろん、半導体ベンダやボードベンダから
提供されるボードサポートパッケージ内のマイコン専用デバイスドライバは、使わせてもらうとして、、、)
これまで試した通り、幾つかの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側でやって、というように、、、 (もちろん、半導体ベンダやボードベンダから
提供されるボードサポートパッケージ内のマイコン専用デバイスドライバは、使わせてもらうとして、、、)
- 関連記事
-
- 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のビルドフォルダを変更する
- Arduino IDE | Intel Galileo Arduino IDEで呼び出すGCCやオプションを変えてビルドする
- Arduino IDE | Intel Galileo Arduino IDEのGCCでビルドしたプログラムをUbuntuで実行してみた
- Arduino IDE | Intel Galileo Arduino IDEにGCCを呼び出す時のオプションを表示させる
- Arduino IDE | Intel Galileo ArduinoスケッチにLinuxのスレッド制御関数を書いてビルドしてみた
- Arduino IDE | Intel Galileo x86 Linux Arduino互換ライブラリに使用されているGCC
- Visual Studio | デバッガ機能の拡張方法について書かれたMSDNのページ
- RXマイコン | アプリケーションノート + 付加価値 をライブラリファイルで配布可?
- Renesas Eclipse | the FIT plug-in in e2studio v2.2
- Renesas Eclipse | AppliletがKPIT GNU RL78/RX C Compilerをサポートしたらしい
- Visual Studio | GCC + Makefileを使ってRLduino78ライブラリをVisual Studio上でビルド (5)
- Visual Studio | GCC + Makefileを使ってRLduino78ライブラリをVisual Studio上でビルド (4)
2013/12/24 blog-entry-392 category: Arduino Lib & CrossGCC
| h o m e |