簡単なアプリを動かしてみよう(コーディング)
クロスコンパイル環境も出来たので、下図のようなタッチセンサに触れると走り出す簡単なアプリを作って動かしてみましょう。
OSEK仕様のリアルタイムOSを使用しますが、今回はシングルタスクで作ります。コンパイル後、実行バイナリをNXTに転送し実行します。
1.サンプルアプリ用のフォルダの準備
samples直下にnxtTestという名前でフォルダを作成します。
2.makefileの準備
- makefileをAlarmTestからnxtTestへコピーします。
- makefileのTOPPERS_OSEK_OIL_SOURCE の値をnxtTest.oilに変更します。
- makefileのTARGET の値を nxtTestに変更します。
3.oilファイルの作成
oilファイルを作成し、ファイル名「nxtTest.oil」で保存します。
oilファイルとは、OSEK OSのコンフィギュレーションファイルになります。OSで使用するモジュールを定義します。今回の設定は、アプリ起動後タイマが1回ファイヤし、TASK(HighTask)が実行されるというものです。詳しくは次回説明します。
#include "implementation.oil" CPU ATMEL_AT91SAM7S256 { /** * OS定義 * */ OS LEJOS_OSEK { STATUS = EXTENDED; STARTUPHOOK = FALSE; ERRORHOOK = FALSE; SHUTDOWNHOOK = FALSE; PRETASKHOOK = FALSE; POSTTASKHOOK = FALSE; USEGETSERVICEID = FALSE; USEPARAMETERACCESS = FALSE; USERESSCHEDULER = FALSE; }; /** * アプリケーションモード定義 * テストモードなど起動モードを変えたいときに使用する。 */ APPMODE appmode1{}; /** * リソースの定義 */ RESOURCE lcd { RESOURCEPROPERTY = STANDARD; }; /** * タスク定義 * */ TASK HighTask { AUTOSTART = FALSE; SCHEDULE = FULL; PRIORITY = 3; ACTIVATION = 1; SCHEDULE = FULL; STACKSIZE = 512; RESOURCE = lcd; }; /** * カウンタ * */ COUNTER SysTimerCnt { MINCYCLE = 1; MAXALLOWEDVALUE = 10000; TICKSPERBASE = 1; }; ALARM cyclic_alarm1 { COUNTER = SysTimerCnt; ACTION = ACTIVATETASK { TASK = HighTask; }; AUTOSTART = TRUE { ALARMTIME = 1000; CYCLETIME = 1; APPMODE = appmode1; }; }; };
4.ソースコーディング
サンプルアプリを実装し、ファイル名「template.c」で保存します。TASK(HighTask)が実行される関数です。
#include <time.h> #include <stdio.h> #include "kernel.h" #include "kernel_id.h" #include "ecrobot_interface.h" #include "systick.h" #define TOUCHED 0 /*--------------------------------------------------------------------------*/ /* OSEK declarations */ /*--------------------------------------------------------------------------*/ DeclareCounter(SysTimerCnt); DeclareResource(lcd); DeclareTask(HighTask); /*--------------------------------------------------------------------------*/ /* Definitions */ /*--------------------------------------------------------------------------*/ int digits; /*--------------------------------------------------------------------------*/ /* ECRobot hooks */ /*--------------------------------------------------------------------------*/ const U8 target_subsystem_name[] = "DesignTest"; void ecrobot_device_initialize() { /* write NXT device initializations */ } void ecrobot_device_terminate() { /* write NXT device terminations */ } /*--------------------------------------------------------------------------*/ /* OSEK hooks */ /*--------------------------------------------------------------------------*/ void StartupHook(void){} void ShutdownHook(StatusType ercd){} void PreTaskHook(void){} void PostTaskHook(void){} void ErrorHook(StatusType ercd){} /*--------------------------------------------------------------------------*/ /* Function to be invoked from a category 2 interrupt */ /*--------------------------------------------------------------------------*/ void user_1ms_isr_type2(void) { StatusType ercd; /* * Increment OSEK Alarm System Timer Count */ ercd = SignalCounter( SysTimerCnt ); if( ercd != E_OK ){ ShutdownOS( ercd ); } } /** * HighPriortyTask * * タッチセンサをタッチすると3秒間直進します。 * */ TASK(HighTask) { /** タッチセンサがタッチされるのを待つ タッチセンサは入力1ポートに接続されている */ while( TOUCHED == ecrobot_get_touch_sensor(NXT_PORT_S1) ); U32 hw_ms_count = systick_get_ms(); /** 両輪のモータを50%の速度で正転させる モータは出力A,Bに接続されている */ nxt_motor_set_speed(NXT_PORT_A, 50, 1); nxt_motor_set_speed(NXT_PORT_B, 50, 1); /** 3秒間待つ */ while ( (systick_get_ms() - hw_ms_count) <= 3 * 1000 ); /** 両輪のモータを停止する */ nxt_motor_set_speed(NXT_PORT_A, 0, 0); nxt_motor_set_speed(NXT_PORT_B, 0, 0); /** タスクを終了する */ TerminateTask(); }
5.samba_nxtTest.tclの作成
SAM-BAのスクリプトファイルを以下のように作成し、samba_nxtTest.tclというファイル名で保存します。
send_file {SRAM} "C:/usrs/lejos_osek/samples/nxtTest/nxtTest_samba_ram.bin" 0x202000 0 go 0x202000
6.コンパイル
make allを実行します。