ITRON4仕様準拠のオープンソースRTOS、TOPPERS/JSPを動かしてみましょう。
TOPPERS/JSPのソースコードはTOPPERSプロジェクトのダウンロードページから入手できます。2005年4月の時点で最新版は1.4.1です。VisualDSP++で使用しますのでWindows版をダウンロードします。
ダウンロードしたらアーカイブを展開します。
図1 展開後のアーカイブ
ディレクトリjspが基準ディレクトリとなります。jsp\configの下には各種プロセッサ用のサブディレクトリが置いてありますが、使いませんのですべて削除して結構です。また、jsp\tools, jsp\utils, jsp\windevも使いませんので削除して結構です。
Blackfin依存部はTOPPERS/JSPの正式リリースには含まれません。そこで、SourceforgeのTOPPERS/JSP for Blackfinのblackfin_portから依存部をダウンロードします。ダウンロードしたらjsp\configの下に展開してください(図2)。
図2 Blackfin依存部を展開する
展開したら、jsp\config\blackfin-vdsp\bf533のjsp_bf533.dpjをVisualDSP++で開いてビルドを行います。ビルドが完了すると、libkernel.dlbが生成されます。これがTOPPERS/JSPのカーネル・ライブラリです。
TOPPERS/JSPを使うには、タスクやセマフォを静的に用意するコンフィグレータが必要です。コンフィグレータはjsp\cfgにC言語によるソースがあります。これをVisualC++か、GNU/Cygwinでビルドしてください。自分でビルドしたくない場合は、もなみソフトウェアが提供しているPizza Factory Ovenless版をフリーで使うことが出来ます。
インストールすると、Program Files\MonamiSoftware\PizzaFactory2\TOPPERS\JSP\1.4\cfgにcfg.exeがインストールされます。これがコンフィグレータです。コマンドラインから使いますので、パスを通すか作業ディレクトリにコピーしておくといいでしょう。
アプリケーションを置くディレクトリはどこでもかまいません。ここではjsp\applicationにします。
コンフィグレーション・ファイルは、静的な資源の割り付けや、割り込みハンドラの登録を指示するためのものです。
/* * ユーザーインクルードファイル */ INCLUDE("\"tskdef.h\""); /* * ユーザー資源のコンフィグレーション */ CRE_TSK(MAIN_TASK, { TA_HLNG|TA_ACT, 0, main_task, 3, 512, NULL }); /* * 初期化。 */ ATT_INI({ TA_HLNG, 0, init_port }); /* * システムタイマーの登録。必ずINHNO_TIMERに登録する。 */ ATT_INI({ TA_HLNG, 0, timer_initialize }); VATT_TER({ TA_HLNG, 0, timer_terminate }); DEF_INH(INHNO_TIMER, { TA_HLNG, timer_handler }); /* * システムインクルードファイル */ INCLUDE("<timer.h>"); INCLUDE("<sys_defs.h>");
タスクはセマフォは実行プログラム中で生成することも出来ますが、普通はコンフィグレーション・ファイルで宣言してしまったほうが簡単です。宣言に使用する関数はユーザー・インクルード・ファイルの中でプロトタイプ宣言しておきます。上の例ではmain_taskがそれにあたります。コンフィグレーション・ファイルに関するその他の詳細はTOPPERS/JSPのマニュアルやITRON4の仕様を参照してください。
システム・タイマーはユーザーがコンフィグレーション・ファイルで宣言しなければなりません。これを忘れるとシステムは正常に動作しません。
コンフィグレーション・ファイルをコンフィグレータにかけると、kernel_id.hとkernel_cfg.cが生成されます。このふたつはアプリケーション・プロジェクトに加えてください。
コンフィグレーション・ファイルのなかでATT_INIを使うと、ユーザー初期化コードをいくつでも登録できます。ユーザー初期化コードは、システム初期化コード実行の後、ユーザータスク実行の前に一度だけ実行されます。複数のユーザー初期化コードを登録した場合は、コンフィグレーション・ファイルに現れる順番で実行します。
この例ではユーザー初期化コードはinit_port.cの中で定義されており、次のようになっています。
#include "s_services.h" #include "tskdef.h" #include <cdefBF53x.h> void init_port(VP_INT vp_int) { *pFIO_DIR = 1 | 2; // set output for PF0 and PF1 *pFIO_FLAG_D = 0x0002; *pEBIU_AMBCTL0 = 0x7bb07bb0; // 非同期ポート0,1の初期化 *pEBIU_AMBCTL1 = 0x7bb07bb0; // 非同期ポート2,3の初期化 *pEBIU_AMGCTL = 0x000f; // 全非同期ポートをイネーブル *pFLASHA_PORTB_DIR = 0x3f; // bit0-5を出力に *pFLASHA_PORTB_OUT = 0x00; // LED オフ *pFLASHA_PORTB_OUT ^= 0x0; // 000000を出力 }
このコードはEZ-KIT Liteのペリフェラルのうち、EBIUと外部のFLASHポートを初期化してLEDを扱えるようにしています。tskdef.hは、ユーザー初期化コードやタスクのプロトタイプ宣言を行うユーザー定義のヘッダーファイルです。
また、このコードのほかに、システム・タイマーの初期化コードもATT_INIを使って登録します。システム・タイマーの初期化コードの名前は常にtimer_initializeで、これはlibkernelの中に含まれているのでユーザーがプログラムをする必要はありません。
タスクは関数の形をしており、コンフィグレーション・ファイルの中でCRE_TSKにより宣言します。タスク本体のコードはこの例ではmain_task.cで定義されています。
#include "t_services.h" #include "kernel_id.h" #include "tskdef.h" void main_task(VP_INT extinf) { while(1) { *pFLASHA_PORTB_OUT ^= 0x31; // 110001を出力 tslp_tsk( 500 ); } }
このタスクは無限ループになっており、500m秒休止しては、LED状態変更を繰り返します。システム起動時に作ったタスクがすぐに実行開始するかどうかは、コンフィグレーション・ファイルのなかで指定できます。詳しくはTOPPERS/JSPのマニュアルや、ITRON4の仕様書を参照してください。
VisualDSP++のアプリケーション・プロジェクトには、libkernel.dlbを追加してください。アプリケーションとカーネルのプロジェクトを同時に開いている場合、メインメニュー⇒Project⇒Dependencies...によってプロジェクト間の依存関係を宣言できます。アプリケーション・プロジェクトがカーネル・プロジェクトに依存すると宣言しておけば、カーネルのソースを変更するたびにアプリケーションも再ビルドされます。アプリケーションのプロジェクトとカーネルのプロジェクトをいつも同時に開きたいならば、プロジェクト・グループ・ファイル(.dpg)として保存しておけばいいでしょう。
また、jsp用のインクルード・ファイルを正しく読めるよう、プリプロセッサに検索パスを指定する必要があります。プロジェクト・オプションのProjects / Compiler / Preprocessorによって指定できます。私は次のように相対表記で検索パスを指定しています。相対パスを指定しておけば、jspごとプロジェクトを別ディレクトリに移動した場合も正しく動作します。
..\kernel; ..\include; ..\config\blackfin-vdsp; ..\config\blackfin-vdsp\bf533;
ふう。一度設定しておけばなんと言うこともないのですがこうして書き下すと結構大変そうに見えますね。コンフィグレーション済みのアプリケーションをソースごとアップロードしておきます。ファイル・サイズが大きいのは、libkernel.dlbもバイナリで提供しているからです。
TOPPERS/JSP for Blackfin BF533によるEZ-KIT Lite LED点滅プログラム : ダウンロード (245KB)