= FAQ =
{{{
#!html
}}}
== 開発環境の構築に関する質問 ==
==== Q:Linux で gcc (例えば,gcc-arm-none-eabi-7-2017-q4-major)をインストールしました。コンパイル自体は成功するのですが、アプリが正常に動作せず,電源がOFFになります。 ====
A:2018年5月時点で,ARM用GCCの開発状況やバージョンアップに伴って、ご質問のような問題が発生するようになりました。 環境構築用のスクリプトを用意していますので、以下のページを参考に環境構築をし直してください。
https://dev.toppers.jp/trac_user/ev3pf/wiki/DevEnvLinux
==== Q:Linux でgccをインストールしようとしたら、「E: 'gcc-arm-none-eabi' のバージョン '4.9.3.2014q4-0trusty12'が見つかりませんでした」いうようなエラーが出てインストールできませんでした。どうすれば良いでしょうか? ====
A:Linuxでの環境構築方法を変更しましたので、以下のページを参考に環境構築をし直してください。
https://dev.toppers.jp/trac_user/ev3pf/wiki/DevEnvLinux
==== Q:EV3RTのバージョンをβ6に更新したら、workspace ディレクトリがなくなりました。どこに移動されたのでしょうか? ====
A:β6から,workspaceの場所が以下のように変更になりました。アプリケーションのフォルダを移動してから、再度ビルドしてください。
* 【β6以降】hrp2/sdk/workspace
* 【β5.2以前】hrp2/workspace
== ダイナミックローディング/アプリケーションローダ(apploader)に関する質問 ==
==== Q:ダイナミックローディング用の実行ファイルを作成するために、make mod=<フォルダ名>と実行したら、以下のように表示されました。これはどんな意味でしょうか? ====
{{{
$ make mod=<フォルダ名>
make img=
make app=
}}}
A:EV3RTのβ6以降では、ビルドの方法が以下のように変更されました。
* スタンドアローン用実行ファイルの生成方法
* 【β5.2以前】$ make app =
* 【β6以降】$ make img =
* 動的ローディング用実行ファイルの生成方法
* 【β5.2以前】$ make mod =
* 【β6以降】$ make app =
'''Q:ダイナミックローディングによりアプリケーションを実行しようとしています。apploaderで「Loadapp from SDcard」を選択すると、「Open application folder '/ev3rt/apps' failed.」というエラーが出ます。何が原因でしょうか?'''
A:いくつか原因が考えられます。以下を確認してください。
* SDカードがFATで初期化されているか?
* SDカード内に /ev3rt/apps/ ディレクトリが存在しているか?
* SDHC対応4GB以上のSDカードを使用しているか?
==== Q:ダイナミックローディングでアプリケーションを実行するために、 workspace ディレクトリの下に app ファイルを作成しました。複数のアプリケーションを実行する場合、ファイル名が同じになってしまうのですがどうすれば良いでしょうか?appファイルの名称を変更しても良いでしょうか? ====
A:はい、変更して構いません。複数のアプリケーションを試す場合には、それぞれのapp ファイルの名称を変更し、SDカードの /ev3rt/apps/ の下に保存してください。apploader で、アプリケーションのファイル名を選択すれば、再起動することなしに、アプリケーションを切り替えることができます。
== アプリケーションの開発方法に関する質問 ==
==== Q:EV3RT β7-3とv1.0で,カーネルがHRP2からHRP3に変わったようなのですが,どのような違いがありますか? ====
A:カーネルの機能の違いは色々ありますが,アプリを開発する上での主な違いは,以下の通りです。
* 周期ハンドラAPIの名称変更
* ev3_sta_cyc(廃止) → sta_cyc
* ev3_stp_cyc(廃止) → stp_cyc
* 周期ハンドラの静的APIの名称と仕様の変更
* EV3_CRE_CYC(廃止) → CRE_CYC
* 引数パラメータにも変更あり
* 詳細は,[https://dev.toppers.jp/trac_user/ev3pf/wiki/FAQ#Q周期的な処理を追加するためにはどうすれば良いでしょうか こちら]や,サンプルプログラムperiodic-taskのapp.cfgを参照してください。
* システム時刻の単位の変更
* システム時刻の単位がミリ秒からマイクロ秒に変更されたので,アプリでの時刻,時間の指定値を1000倍にする
* C++ライブラリの引数も,マイクロ秒に変更されている
カーネルの機能の違いについては,TOPPERS第3世代カーネル統合仕様書をご覧ください。
==== Q:周期的な処理を追加するためには、どうすれば良いでしょうか? ====
A:(1) app.cfg ファイルに、CRE_CYC(β7-3以前は,EV3_CRE_CYC)を使って周期ハンドラを作成します。以下の例に従って、cfgファイルに追記してください。
【v1.0の場合】
{{{
DOMAIN(TDOM_APP) {
...
CRE_TSK(TEST_EV3_CYC_TSK1, { TA_NULL, 0, test_ev3_cychdr, MAIN_PRIORITY, STACK_SIZE, NULL }); ← 周期的に起動したいタスク
...
CRE_CYC(TEST_EV3_CYC1, { TA_STA, { TNFY_ACTTSK, TEST_EV3_CYC_TSK1 }, 500 * 1000, 0U }); ← この行を追加
...
}
ATT_MOD(app.o)
}}}
CRE_CYCの各パラメータの意味は、以下の通りです。
* 【第1パラメータ】TEST_EV3_CYC1:周期ハンドラの名称(実際にはID番号だが、コンフィギュレータによって、ここで指定した名称のマクロが自動的に定義される)
* 【第2パラメータ】TA_STA:周期ハンドラの属性。
* TA_STAを指定すると、アプリケーションの起動時に周期処理も開始する。
* TA_NULLを指定すると、アプリケーションでsta_cyc(TEST_EV3_CYC1)を呼び出すまで動作しない。
* 【第3パラメータ】TNFY_ACTTSK:タスクの起動による通知(通知処理モード)
* 【第4パラメータ】TEST_EV3_CYC_TSK1:起動するタスクのID
* 【第5パラメータ】500000:起動周期(EV3RT v1.0の場合、単位はマイクロ秒で指定)
* 【第6パラメータ】0:起動位相。周期ハンドラの動作開始を指定してから、最初に周期ハンドラが呼ばれるまでの相対時間。
* 属性にTA_STAを指定して、起動位相に0を指定するとシステムが起動して最初のタイムティックが発生した時に動作する。
詳細は、TOPPERS第3世代カーネル統合仕様書p.283 CRE_CYCの説明,及びp.266 4.6 時間管理機能を参照してください。
【β7-3以前の場合】
{{{
DOMAIN(TDOM_APP) {
...
EV3_CRE_CYC(TEST_EV3_CYC1, { TA_STA, 0, test_ev3_cychdr, 500, 0 }); ← この行を追加
...
}
ATT_MOD(app.o)
}}}
EV3_CRE_CYCの各パラメータの意味は、以下の通りです。
* 【第1パラメータ】TEST_EV3_CYC1:周期ハンドラの名称(実際にはID番号だが、コンフィギュレータによって、ここで指定した名称のマクロが自動的に定義される)
* 【第2パラメータ】TA_STA:周期ハンドラの属性。
* TA_STAを指定すると、アプリケーションの起動時に周期処理も開始する。
* TA_NULLを指定すると、アプリケーションでEV3_sta_cyc(TEST_EV3_CYC1)を呼び出すまで動作しない。
* 【第3パラメータ】0:周期ハンドラに渡される値(拡張情報)
* 【第4パラメータ】test_ev3_cychdr:周期ハンドラの先頭番地(周期的に実行される関数)。Cファイルに同名の関数を定義してください((2)を参照のこと)。
* 【第5パラメータ】500:起動周期(EV3RTの場合、単位はミリ秒で指定)
* 【第6パラメータ】0:起動位相。周期ハンドラの動作開始を指定してから、最初に周期ハンドラが呼ばれるまでの相対時間。
* 属性にTA_STAを指定して、起動位相に0を指定するとシステムが起動して最初のタイムティックが発生した時に動作する。
詳細は、TOPPERS次世代カーネル統合仕様書のCRE_CYCの説明を参照してください。
(2) アプリケーションのCファイルに周期ハンドラの関数を追加します。例えば、app.h と app.c に以下を追加します。
* app.h
{{{
extern void test_ev3_cychdr(intptr_t exinf);
}}}
* app.c
{{{
static int count;
void test_ev3_cychdr(intptr_t idx) {
char buf[100];
sprintf(buf, "EV3CYC %d count %d", idx, ++count);
ev3_lcd_draw_string(buf, 0, 0); // EV3のLCDに文字列 buf を表示
}
}}}
==== Q:タスクの優先度を変更するには、どうすれば良いでしょうか? ====
A:cfg ファイルに記述してある CRE_TSK のパラメータを変更します。
gyroboy のサンプルを例に説明します。workspace/gyroboy/app.cfg に以下の記述があります。
{{{
DOMAIN(TDOM_APP) {
CRE_TSK(BALANCE_TASK, { TA_NULL, 0, balance_task, TMIN_APP_TPRI, STACK_SIZE, NULL });
CRE_TSK(MAIN_TASK, { TA_ACT, 0, main_task, TMIN_APP_TPRI + 1, STACK_SIZE, NULL });
CRE_TSK(IDLE_TASK, { TA_NULL, 0, idle_task, TMIN_APP_TPRI + 2, STACK_SIZE, NULL });
}
}}}
CRE_TSKの各パラメータの意味は、以下の通りです。
* 【第1パラメータ】BALANCE_TASK:タスクの名称(実際にはID番号だが、コンフィギュレータによって、ここで指定した名称のマクロが自動的に定義される)
* 【第2パラメータ】TA_NULL:タスクの属性。
* TA_ACTを指定すると、アプリケーション起動時にタスクを実行可能状態に遷移させる。
* TA_NULLを指定すると、アプリケーション起動時には休止状態である。
* 【第3パラメータ】0:タスクに渡される値(拡張情報)
* 【第4パラメータ】balance_task:タスクのメインルーチンの先頭番地(周期的に実行される関数)。
* 【第5パラメータ】TMIN_APP_TPRI:タスクの起動時優先度。EV3RTの場合、TMIN_APP_TPRIは、タスクに指定できる最高優先度(値は最小値)を示す。
* 数値を小さくすると優先度が高くなり、大きくすると優先度が下がる。
* したがって、この例では、BALANCE_TASKの優先度が最も高く, IDLE_TASKの優先度が最も低く設定されている。
* 【第6パラメータ】STACK_SIZE:タスクのスタック領域のサイズ。
* 【第7パラメータ】NULL:タスクのスタック領域の先頭番地
* NULLとした場合,第6パラメータで指定したサイズのスタック領域が,コンフィギュレータまたはカーネルにより確保される。
詳細は、TOPPERS次世代カーネル統合仕様書のCRE_TSKの説明を参照してください。また、アプリケーションの動作中に優先度を変更する chg_pri というAPIもあります。
==== Q:アプリケーションのソースコードを複数のディレクトリに分けて管理するにはどうすれば良いでしょうか? ====
A:主に,2つの方法がありますので,目的に応じてどちらを選んでください。なお,ここで説明する方法は,EV3RT β6-3でサポートされました。それ以前のバージョンをお使いの場合は,β6-3以降に更新してからお試しください。
hrp2/sdk/workspace 以下にアプリケーションのディレクトリ(appとする)が存在していることを前提とします。hrp2/sdk/workspace で,make を実行すると,アプリケーションのディレクトリ下にあるソースコード(app/app.h や app/app.c)と,以下のルールに従ってソースコードを探索します。
* include という名称のディレクトリにあるヘッダファイル
* src という名称のディレクトリにある .c ファイル
これ以外の場所にソースコードを置きたい場合には,以下のファイルを修正する必要があります。
{{{
ev3rt/hrp2/sdk/common/Makefile.prj.common
}}}
具体的な修正方法は,主に,以下の2つあります。修正した後,再度,make を実行してください。
===== すべてのディレクトリを探索対象に入れる場合 =====
アプリケーションのディレクトリの下に,複数のディレクトリを作成し,それら全部を探索対象に入れたい場合には,
{{{
APPL_DIR += $(foreach dir,$(shell find $(APPLDIR) -type d),$(dir))
}}}
と修正すればOKです。
この場合,すべてのディレクトリが対象になるので,例えば,バージョン1(ver1ディレクトリ)と機能を追加したバージョン2(ver2ディレクトリ)のディレクトリを切り替える(どちらか1つのディレクトリのソースコードのみを使う)という用途には使えません。その場合は,次のディレクトリ指定の方法を使います。
===== ソースコードのディレクトリを指定する場合 =====
例えば,src の下にtestというディレクトリを作成し,そこに.cファイルを置きたい場合には,以下のように,1行追加すればOKです。
{{{
APPL_DIR += $(foreach dir,$(shell find $(APPLDIR) -type d -name src),$(dir))
APPL_DIR += $(foreach dir,$(shell find $(APPLDIR) -type d -name test),$(dir)) ←これをディレクトリごとに追加/削除
…
}}}
==== Q:ログの出力先を変更することはできますか? ====
A:ログの出力先は、以下のいずれかから選択できます。
* UART(EV3の1番ポートにケーブルを接続)
* Bluetooth
* LCD(EV3の画面)
SDカード内の ev3rt/etc/rc.conf.ini ファイルに以下のように追加・修正してください。
{{{
[Debug]
DefaultPort = UART ← UARTを使用する場合
DefaultPort = BT ← Bluetoothを使用する場合
DefaultPort = LCD ← LCDを使用する場合
}}}
何も指定しない場合(上記の設定を何も書かない場合)は、出力先はLCDになります。
==== Q:Eclipse などの統合開発環境を使うことはできますか? ====
A:使用できる可能性はありますが、現時点では正式にサポートされていません。サポートでき次第、設定方法を公開します。
もし使用されている方がいましたら、ぜひ情報を[wiki:Contacts こちら]にお寄せください。
== Bluetooth 接続に関する質問 ==
==== Q:Bluetooth のデバイス名(PCで検索したときに表示される名称)を変更する方法はありますか? ====
A:バージョンβ4から、SDカード内に /ev3rt/etc/ ディレクトリを作成して rc.conf.ini というファイルを置き、その内容を修正することで変更できます。
ダウンロードしたパッケージに含まれている、 sdcard/ev3rt/etc/rc.conf.ini をSDカードにコピーしてお使いください。
{{{
[Bluetooth]
LocalName=Mindstorms EV3 ← デバイス名の指定
PinCode=0000 ← PINコードの指定
}}}
また、バージョンβ3以前では、カーネルのソースコードを修正する必要があります。
hrp2/target/ev3_gcc/ev3.hのBLUETOOTH_LOCAL_NAME というマクロを修正して、もう一度ビルドしてください。
例えば、
{{{
#define BLUETOOTH_LOCAL_NAME ("Mindstorms EV3") //!< Name for service discovery
↓
#define BLUETOOTH_LOCAL_NAME ("TEST EV3") //!< Name for service discovery
}}}
と修正すると、Bluetoothデバイスを検索した時に TEST EV3 という名称で表示されるようになります。