• 検索結果がありません。

RTLinuxモジュールの動き

ドキュメント内 B5size manual.dot (ページ 58-62)

第 4 章  より高度な処理を行おう 27

4.4  DaStartSamplingを使ったアナログ出力更新の解説

4.4.3  RTLinuxモジュールの動き

ここでは、RTLinuxモジュール(module3.o)の動きに注目して見てみましょう。

RTLinuxモジュールでは、サンプリングを実現するために、 init_module関数内で、幾つかリソース

を生成しています。それを下表に示します。

項  目  内  容 

RT-FIFO(FIFO_COMMAND)

Linuxプロセスからの指示を受けるためのRT-FIFOです。指示は、ハ

ンドラmy_handlerに渡されます。

RT-FIFO(FIFO_THRU_CMD)

ハンドラにて、Linuxプロセスから受け取った情報を、RTLinuxスレ

ッド(my_task)に渡すためのRT-FIFOです。

ハンドラ(my_handler) Linuxプロセスからの指示を受け取るための処理の入り口です。

RT-FIFO経由で送られた情報は、一旦このハンドラが受け取り、然 る処理に回されます。

RTLinuxスレッド(my_task)

DAドライバモジュールに対して、アナログ出力更新のスタート,

ストップ,データのセット,クリアを指示するRTLinuxスレッドです。

コールバック関数

(my_smp_callback)

DAドライバモジュールにてアナログ出力更新中に、何らかのイベン ト事象を検出すると呼び出されるコールバック関数です。

次に、生成された各リソースの相互関係と処理の流れを下図に示します。

ハンドラ(my_handler)

RTLinuxスレッド(my_task) FFO_COMMAND

FIFO_THRU_CMD

Linuxプロセス

ID_START ID_STOP

←周期呼び出し 周期実行

DaGetStatus関数 コマンド指示

ID_CLEAR_DA

ID_SET_DATA

DAドライバモジュール アナログ出力更新

『40ページ 

4.2.2  RTLinuxモジュールの動き

』の図と比較してみてください。

先のサンプルでは、アナログ出力更新の処理は、RTLinuxスレッド(my_task)にて行っていましたが、こ のサンプルでは、DAドライバモジュール内で行われます。

実際のアナログ出力更新を行っているのは、DAドライバモジュールです。

このサンプルでは、トリガを指定せずにアナログ出力更新しているので、ストップ指令を送らない限 りサンプリングを続けるようになっています。

LinuxプロセスからRTLinuxスレッドへの指示は、ハンドラ(my_handler)を経由して行われます。このサ ンプルのハンドラは、Linuxプロセスからの指示を、そのまま横流しする単純なものです。

以降では、処理順に、これらの処理を眺めてみましょう。

(195〜201行目:RT-FIFOおよびハンドラの生成と初期化)

195〜201行目では、RTLinuxモジュールおよびLinuxプロセスで使用するRT-FIFOおよび、Linuxプロセ スからの指示を受け取るハンドラを生成しています。

次に、DA製品の制御を開始するために、204行目のDaOpenEx関数を使ってオープンしています。ここ で取得するデバイス番号は、他の関数で共通して使われるため、グローバル変数g_device_noに格納さ れています。

第4引数でコールバック関数の関数ポインタ

(上の例では、CallbackFunc)を、第5引数でコールバッ

ク関数の第1引数のパラメータを渡します。

例えば、第5引数に123を渡すと、上の例ではuserArg変数に123が渡されます。

(220行目:内部データバッファの設定)

DaSetBoardConfigEx関数は、ドライバが使用する内部データバッファを与えています。

第4引数で、内部データバッファのポインタ(inner_da_buff)を、第2引数でバッファのサイズ

(BUFF_SIZE)を指定しています。

★DaSetBoardConfigExの引数と、内部バッファサイズの関係

DaSetBoardConfigEx関数の第2引数は、内部データバッファのサイズを指定します。

サンプル中の、内部データバッファを確保している行と比較してみましょう。

↓内部データバッファを確保している行。

15: DA_TYPE inner_da_buff[CH_NUM * BUFF_SIZE];

↓DAドライバモジュールに、内部データバッファのサイズを指示している行。

220: ret = DaSetBoardConfigEx(g_device_no, BUFF_SIZE, 0, inner_da_buff);

2引数で指定するサイズは、データ件数にあたります。

内部データバッファの総バイト数ではありません。

(227〜247行目:アナログ出力更新の条件設定)

DaSetSamplingConfig関数は、アナログ出力更新の条件設定を行います。

どのチャンネルをアナログ出力するか,周波数はいくらで行うのか,リピート回数はいくらか、等の 設定をここで行います。

サンプルでは、

DaGetSamplingConfig関数にて、 DAドライバモジュールが保持するデフォルトの条

件設定パラメータを取得し、これに修正を加える形式を取っています。

デフォルトのパラメータは、DAドライバモジュールがオープン時に初期値として持っています。

この値は、「その製品でアナログ出力更新できる、理想的と思われる値」がセットされています。

ここでは、デフォルト値に修正を加える形式にすることで、アナログ出力更新の条件の諸設定を 簡易にしています。

(250〜253行目:アナログ出力更新用データの初期化)

250〜253行目の、 make_sampling_data関数は、アナログ出力更新用データの初期化を行うサブルー

チンを、順次呼び出しています。

サブルーチン本体は、134〜

182行目にあります。処理内容を以下に示します。

項  目  内  容 

サイン波データ サイン波データを作成します。

データは、da_sin_wave_data配列に格納されます。

三角波データ 三角波データを作成します。

データは、da_triangle_wave_data配列に格納されます。

のこぎり波データ のこぎり波データを作成します。

データは、da_teeth_saw_wave_data配列に格納されます。

矩形波データ 矩形波データを作成します。

データは、da_rectangle_wave_data配列に格納されます。

(256行目:pthread_create関数)

pthread_create関数では、アナログ出力更新等の処理を実行する、 RTLinuxスレッド(my_task)を生成

しています。

(121〜129行目:ハンドラの処理)

ハンドラ(my_handler)の役目は、LinuxプロセスからRT-FIFOを経由して送られる指示を、RTLinux スレッド(my_task)に渡すことにあります。

この処理は、ほとんど定型的なものです。

RT-FIFO RT-FIFO

my_handler

ハンドラ

rtf_get rtf_put

Linuxプロセス側 RTLinuxスレッド側

(39〜108行目:RTLinuxスレッドの処理)

RTLinuxスレッド(my_task)の処理の中心は、この39〜108行のwhileループです。

ここで、

Linuxプロセスから与えられた指示によって、データのセットとクリア、アナログ出力更

新の開始と停止を行い(48〜98行の処理)、アナログ出力更新の状態をチェック(102行目の

DaGetStatus関数)しています。

処理の決定は、CMD_IDS列挙体の定数値により決定されます。

列挙定数値  内  容 

ID_START

53行目のDaStartSampling関数で、DAドライバモジュールに対して、アナログ出

力更新の開始を指示しています。

そ の 後 、smp_period_msメ ン バ 変 数 の 値 をms単 位 の 実 行 周 期 と し て 、 pthread_make_periodic_np関数を呼び出し、自身の実行周期の間隔を指定してい ます。

これは、アナログ出力更新の状態をチェックする間隔です。

ID_STOP

65行目のDaStopSampling関数で、DAドライバモジュールに対して、アナログ出

力更新の停止を指示しています。

その後、pthread_suspend_np関数を呼び出し、自身のスレッドをスリープ状態に しています。

ID_SET_DATA

アナログ出力更新を行うデータ配列に対して、前ページで作成したデータ配列

を、data_kindで指定された種類に従って設定します。(83〜95行目) DAドライバモジュールに対して、データのセットは、92行目の DaSetSamplingData関数にて行っています。

ID_CLEAR_DATA

76行目のDaClearSamplingData関数で、DAドライバモジュールに対して、

内部データバッファのクリアを指示しています。

★DaStartSampling関数の同期/非同期指定について

53行目のDaStartSampling関数では、第2引数にFLAG_ASYNCを指定しています。

これは、アナログ出力更新を非同期に行うよう指示するものです。この引数を指定して関数を呼び出す と、処理が完了するのを待たず、すぐ関数の呼び出しから戻ります。

FLAG_SYNCを指定すると、アナログ出力更新を同期で行うよう指示することになります。

100件のアナログ出力更新を行うよう指示していた場合、この関数の呼び出しから戻った時、100件のサ ンプリングが終了しています。

FLAG_ASYNC を指定した場合、アナログ出力更新が終了している保証はありませんので、DaGetStatus

関数やコールバック関数を用いて、アナログ出力更新が終了したことを監視する必要があります。

サンプルでは、リピート回数(236行目のulSmplRepeatメンバ変数)を0として、永久にアナログ出力更新 を繰り返すよう指示しているので、FLAG_SYNC を指定すると、関数の呼び出しから戻らず、永遠にア ナログ出力更新を続けてしまいます。

従って、ここではFLAG_ASYNCを指定しています。

(23〜26行目:コールバック関数の処理)

アナログ出力更新完了時、DAドライバモジュールは、このコールバック関数を呼び出します。

サンプルでは、特に何も処理をしていません。お客様がサンプルに処理を付け加える時、アナロ グ出力更新終了時に、何らかの終了処理を加えたい時、このコールバック関数に処理を加えると 良いでしょう。

ドキュメント内 B5size manual.dot (ページ 58-62)

関連したドキュメント