沼津高専 電子制御工学科
MIRSATLM プログラム詳細仕様書
MIRSATLM-SOFT-0001
改訂記録
版数 作成日 作成者 承認 改訂内容
A01 2000.10.13 田口 大庭 初版
A02 2000.10.20 田口 大庭 ロータリーエンコーダ・PWMタスクとLCDドライバ部分を一部変更
A03 2001.1.6 田口 大庭 赤外線・タッチセンサドライバ部分を作成、LCDドライバ部分を修正

目次

1 .はじめに

 本仕様書は、MIRSATLMソフトウェア設計書に規定された動作規定・状態遷移を実現する各タスク・ドライバプログラムの動作を説明するものである。

2 .システム概要

 MIRSATLMソフトウェアはRT-Linux上で動作する各タスク・ドライバとユーザプログラムで構成される。Real Timeで動作すべきハードウェアに対してはRTタスクプログラムで、それ以外のハードウェアに対してはデバイスドライバプログラムで処理を行う。ユーザプログラムは、スイッチの状態やセンサ情報をもとに動作を決定しそれに対応したタスク・ドライバの起動を行う。

3 .各タスク・ドライバの基本仕様

    3-1 .超音波センサタスク

    3-2 .ロータリーエンコーダ・PWMタスク

    3-3 .タッチセンサ・赤外線センサドライバ

    3-4 .LCDドライバ

4 .各タスク・ドライバの動作説明

    4-1 .超音波センサタスク

      本モジュールの動作の流れを示した図を以下に示す。


      Fig.1 超音波センサタスク制御フローチャート


      1. FIFO1にコマンドが書き込まれると、コマンドハンドラが起動する。コマンドハンドラでタイムアウト監視タスクを生成し、周期タスクとして0.1秒後に起動するよう設定する。また、FIFO1に書き込まれたコマンドを読み取り、超音波送信関数に引数として渡す。
      2. 超音波送信関数は、引数で与えられた番号に対応する超音波センサのアドレスにコマンドを書き込む。(=超音波センサ回路部に超音波送信の指示を出す。)また、その時刻をシステムカウンタから記憶し、割込み許可の状態にする。
        • 割込み信号が入った場合 : 割込み信号が入ると、割込みハンドラが起動する。割込みハンドラはその時刻を記憶し、タイムアウト監視タスクを削除する。その後、送信時の時刻データと先程の受信時の時刻データから距離を換算する。その換算式を以下に示す。

             距離 = (受信時の時間 − 送信時の時間) * (331.5 + 0.61t) / (100000 * 2)

          ここでtは摂氏温度であり、本モジュールではこれを20℃としている。

        • 0.1秒たっても割込み信号が入らなかった場合 : タイムアウト監視タスクが起動する。Linuxカーネルを割込み拒否の状態にし、FIFO1、FIFO2にエラー値を書き込む。その後、タイムアウト監視タスクを削除する。
      3. FIFO2に値が書き込まれると、この一連の動作は終了する。(ユーザプログラムで、FIFO2に値が入るまで待つような設定をする。)

    4-2 .ロータリーエンコーダ・PWMタスク

      1. ユーザプログラムから送られてくるFIFO5からSTARTの指令とタスクの実行周期をハンドラーで読み込む。
         ※用いる関数:rtf_get()
         
      2. STARTの指令をうけたら、左右のカウンタにリセットをかける。次にタスクが指定した周期ごとに実行されるようにする。
         ※用いる関数:pthread_make_periodic_np()

      3. RT-タスクが実行を指示されたら・・・・
        @ カウント値をラッチ(保持)する。
        A 左右のカウンタをリセットする。(リセット信号を関数outb()を使ってIOポート120Hへ送る。)
        B 左のタイヤのカウント値の上位4ビットと下位8ビットを、IOポートの122Hから関数inb()を用いて、分けて持ってくる。
        C 次に右のタイヤのカウント値の上位4ビットと下位8ビットを、IOポートの122Hから関数inb()を用いて、分けて持ってくる。
        D 左右それぞれのカウント値の、上位4ビットと下位8ビットを結合させて12ビットのデータにする。
        E カウント値をFIFO3へと書き込んで、上位のプログラムへと送る。
         ※用いる関数:rtf_put()
        F FIFO4よりPWMの速度データを読み込む。
         ※用いる関数:rtf_get()
        G 読み込んだ速度データを、関数outw()を用いてIOポートの110H(左速度)、112H(右速度)に送る。
        新しい速度データがFIFO4に書き込まれていなかった場合は現在の速度を保持する。
        この3.の動作がサスペンドをかけられるまで繰り返される。

      4. FIFO5にSTOPの指令が書き込まれて来たらハンドラーは周期タスクを停止させる。
         ※用いる関数:pthread_suspend_np()
      5. ハンドラーによってRESTARTがかけられるまで待機。
         ※用いる関数:pthread_wakeup_np()

      注)RT-タスクの実行周期について
        RT-タスクの実行周期の下限は、FPGAボードから左右のそれぞれのカウント値を下位8ビット、上位4ビットとわけてよみこんできて、それを結合させて12ビットのデータにするのにどれだけの時間がかかるかによって決まってくる。
        また、上限は最高速でMIRSを走らせた場合にカウント用のICμPD4701Aの中に組み込まれているカウンタが一周するのにどれだけの時間がかかるかによって決まってくる。

      本ソフトウェアの制御フロー図を下に示す。

      Fig.4 ハンドラの動作

      Fig.5 RT-タスクの動作

    4-3 .タッチセンサ・赤外線センサドライバ

         ※タッチセンサ・赤外線センサデバイスドライバを扱う上での注意:

    Fig.5 タッチセンサ・赤外線センサドライバ制御フローチャート

    4-4 .LCDドライバ

         ※LCDデバイスドライバを扱う上での注意:

Fig.5 LCDドライバ制御フローチャート

5 .アプリケーションインターフェース

制御関数
動作説明
pwm_enco_start(int period)
実行周期period(単位はμsec)を引数として与える。この関数の中ではFIFO5へSTART指令と実行周期の書き込みを行う。この関数をまず始めに実行しないと、関数encoder_data()やpwm_data()を使用することはできない。
pwm_enco_stop(void)
RT-タスクを停止させる。この関数の中ではFIFO5へSTOP指令の書き込みを行っている。
pwm_enco_restart(void)
encorder_stop()により停止したタスクを再スタートさせる。この関数の中ではFIFO5へRESTART指令の書き込みを行っている。
encorder_data(int *l_distance, int *r_distance, int *l_speed, int *r_speed)
FIFO3からカウント値を読み込んで、それをもとに左右のタイヤの移動距離と左右のタイヤの速度を求めそれを戻り値として返す。
タイヤの速度は、この関数でカウント値を読み込んだ際の最新のカウント値(FIFOから一番最後に取り出したデータを元に計算したもの)から、その一つ前のカウント値を引いたものをRT-タスクの実行周期で割ることにより求める。
また、タイヤの移動距離と速度の単位はそれぞれ、[cm]、[cm/s]である。
pwm_both_data(int l_speed, int r_speed)
左右の速度データを引数として与える。この関数の中で、与えられたそれぞれの速度データをそれに対応する8ビットのデータに置き換えた後FIFO4に書き込んでRT-タスクに送る。
引数に正の値を入れるとタイヤは正転し、負の値を入れると逆転する。
pwm_left_data(int l_speed)
左の速度データを引数として与える。pwm_both_data()と同様、与えられた速度データを 8ビットのデータに置き換えた後FIFO4に書き込んでRT-タスクに送る。
pwm_right_data(int r_speed)
右の速度データを引数として与える。pwm_both_data()と同様、与えられた速度データを 8ビットのデータに置き換えた後FIFO4に書き込んでRT-タスクに送る。
制御関数
動作説明
fc=open("/dev/irs_ts",f_mode)
タッチセンサ・赤外線センサデバイスファイルをopenし、I/Oポートアドレスのチェックと登録を行う。
read(int file, char buf,size_t count,loff_t offset)
タッチセンサ・赤外線センサ・パワーオン信号処理モジュールからデータを読み込む。
ioctl(int fc,int cmd,int &ctl_nr)
タッチセンサ・赤外線センサ・パワーオン信号を、選択したコマンドによってそれぞれ分けて読み込む。
close(fd)
I/Oポートアドレスを解放する。
制御関数
動作説明
fd=open("/dev/lcd",f_mode)
LCDデバイスファイルをopenし、I/Oポートアドレスのチェックと登録を行う。
LCDモジュールのディスプレイON等の最低限の初期設定を行う。
read(int file, char buffer,size_t count,loff_t offset)
LCDモジュール(I/Oポート)に書き込まれている文字データを読み込む。
write(int file, char buffer,int count,loff_t offset)
表示したい文字データをLCDモジュール(I/Oポート)に書き込む。
ioctl(int fd,int cmd,int &ctl_nr)
デバイスの初期設定を行う。選択したコマンドによって表示クリアやカーソルなどを設定する。そしてLCDモジュール(I/Oポート)に書き込む。
close(fd)
I/Oポートアドレスを解放する。
I/Oポート
使用タスク・ドライバ
内容
0100H
LCDドライバ
表示設定データの書き込み
0102H
LCDドライバ
文字データの書き込み/読み込み
0110H
ロータリーエンコーダ・PWMタスク
方向・PWM信号の生成とラッチ確認(右)
0112H
ロータリーエンコーダ・PWMタスク
方向・PWM信号の生成とラッチ確認(左)
0120H
ロータリーエンコーダ・PWMタスク
ロータリーエンコーダカウントの動作制御
0122H
ロータリーエンコーダ・PWMタスク
ロータリーエンコーダカウント値の読み込み
0130H
超音波センサタスク
センサ送信信号
0132H
超音波センサタスク
割り込み信号のマスク・アンマスク&リセット
0140H
タッチ・赤外線センサドライバ
赤外線・タッチセンサの状態
0142H
タッチ・赤外線センサドライバ
割り込み信号のマスク・アンマスク&リセット


関連文書