81
www.interface.co.jp チュートリアル RTLinuxによるDIOボード制御プログラミング

チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

  • Upload
    others

  • View
    1

  • Download
    0

Embed Size (px)

Citation preview

Page 1: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

www.interface.co.jp

チュートリアル

RTLinuxによるDIOボード制御プログラミング

Page 2: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

www.interface.co.jp

商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。 保障の内容と制限 弊社はドキュメント内の情報の正確さに万全を期しています。万一、誤記または誤植等があった

場合、弊社は予告なく改訂する場合があります。ドキュメントまたはドキュメント内の情報に起

因するいかなる損害に対しても弊社は責任を負いません。 製品に含まれるバグ、あるいは製品の供給(納期遅延),性能、もしくは使用に起因する付帯的損害もしくは間接的損害に対して、弊社に全面的に責がある場合でも、弊社はその製品に対する改良

(正常に動作する)、代品交換までとし、金銭面での賠償の責任は一切負わないものとしますので、予めご了承ください。 ドキュメント内の図や表は説明のためであり、ユーザ個別の応用事例により変化する場合があり

ます。 著作権,知的所有権 弊社は本製品に含まれるおよび本製品に対する権利や知的所有権を保持しています。 本製品はコンピュータ ソフトウェア(プログラム),図,文章,写真等を含んでいます。 複製の禁止 弊社の許可なく、本製品(ドキュメント含む)の全て、または一部に関わらず、複製,改変等を行うことはできません。 責任の制限 弊社は、弊社または再販売者の予見の有無に関わらず、発生したいかなる特別損害,偶発的損害,間接的な損害,重大な損害について、責任を負いません。 補償の内容 本ドキュメントで使用している弊社製品の補償については、各製品のマニュアルを参照してくだ

さい。

Page 3: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

- 1 - Interface Corporation

改訂履歴

Ver. 年 月 改 訂 内 容 1.5 2006年8月 ●対応型式追加

●『第3章 デジタル入出力I/Oモジュール制御の第一歩』 配線図修正。 ●技術資料一覧更新 ●フォーマット変更

1.4 2004年9月 ●対応型式追加 ●セットアップユーティリティのバージョンアップに対応 ●技術資料一覧更新

1.3 2004年1月 ●セットアップユーティリティのバージョンアップに対応 1.2 2003年7月 ●対応型式追加 1.1 2002年6月 ●誤記修正 1.0 2002年5月 新規作成

本チュートリアルをご使用の際は、必ず各製品型式の最新のドキュメント(ユーザーズマニュアル,ヘルプ)をあわせて参照してください。また、最新のドライバソフトウェアをご使用ください。 ユーザーズマニュアル,ドライバソフトウェアは弊社Web site(www.interface.co.jp)からダウンロードできます。(ヘルプはドライバソフトウェアに含まれています)

Page 4: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

Interface Corporation - 2 -

目 次

第 1章 デジタル入出力概要 7

第 2章 DIO(Digital Input Output) on RTLinux 8

2.1 パフォーマンス ............................................................................................................................. 8 2.1.1 応答性 .................................................................................................................................. 8 2.1.2 周期性 ................................................................................................................................ 10

2.2 RTLinuxによるデジタル入出力制御 ........................................................................................ 11 2.2.1 デジタル入出力I/Oモジュール制御概略 ...................................................................... 12

第 3章 デジタル入出力I/Oモジュール制御の第一歩 13

3.1 RTLinuxリアルタイムモジュール組み込み............................................................................ 14 3.2 RTLinux デジタル入出力ドライバ組み込み.......................................................................... 16 3.3 デジタル入力プログラムを作ろう .......................................................................................... 19

3.3.1 プログラミング ................................................................................................................ 19 ■Step 1. 初期化処理と終了処理 ....................................................................................... 24 ■Step 2. デジタル入力処理の作成 ................................................................................... 26

3.3.2 コンパイル ........................................................................................................................ 29 3.3.3 動かしてみよう ................................................................................................................ 29

3.4 デジタル出力プログラムを作ろう .......................................................................................... 31 3.4.1 プログラミング ................................................................................................................ 31 ■Step 1.デジタル出力処理の作成 ..................................................................................... 37

3.4.2 コンパイル ........................................................................................................................ 39 3.4.3 動かしてみよう ................................................................................................................ 39

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

4.1 リアルタイムFIFOを使用したデジタル入力.......................................................................... 40 4.1.1 プログラム概要 ................................................................................................................ 40 4.1.2 処理の流れ ........................................................................................................................ 41 4.1.3 プログラミング ................................................................................................................ 42

Step 1. 共通定義ファイルの作成 ....................................................................................... 42 Step 2. デジタル入力処理の作成 ....................................................................................... 43 Step 3. デジタル入力データ表示アプリケーション作成............................................... 46

4.1.4 コンパイル ........................................................................................................................ 49 4.1.5 動かしてみよう ................................................................................................................ 49

4.2 リアルタイムFIFOを使用したデジタル出力.......................................................................... 51 4.2.1 プログラム概要 ................................................................................................................ 51 4.2.2 処理の流れ ........................................................................................................................ 51 4.2.3 プログラミング ................................................................................................................ 52 ■Step 1. 基本定義ファイルの作成 ................................................................................... 52 ■Step 2. デジタル出力処理の作成 ................................................................................... 53 ■Step 3. 出力開始,状態表示アプリケーション作成...................................................... 57

Page 5: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

- 3 - Interface Corporation

4.2.4 コンパイル ........................................................................................................................ 60 4.2.5 動かしてみよう ................................................................................................................ 61

4.3 割り込みイベントによる処理を行いたい! .......................................................................... 62 4.3.1 プログラム概要 ................................................................................................................ 62 4.3.2 処理の流れ ........................................................................................................................ 63 4.3.3 プログラミング ................................................................................................................ 64 ■Step 1. 割り込みイベントコールバックの作成........................................................... 64 ■Step 2. 割り込み要因表示アプリケーション作成....................................................... 66

4.3.4 コンパイル ........................................................................................................................ 68 4.3.5 動かしてみよう ................................................................................................................ 69

第 5章 デバッグ手法 70

5.1 ドライバデバッグ支援機能を使ってみる .............................................................................. 70 5.1.1 関数呼び出しトレース .................................................................................................... 71 5.1.2 エラー情報 ........................................................................................................................ 72 5.1.3 I/Oモジュールソース情報............................................................................................... 72 5.1.4 割り込み発生情報 ............................................................................................................ 73

第 6章 リファレンス 74

6.1 関数一覧 ....................................................................................................................................... 74 6.2 戻り値一覧 ................................................................................................................................... 75

技術資料紹介 76

Page 6: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

Interface Corporation - 4 -

はじめに

平素は格別のご高配を賜り、厚くお礼申し上げます。本冊子はRTLinux/Free上で弊社PCI,CompactPCIデジタル入出力I/Oモジュールを制御したい方を対象に、デジタル入出力I/Oモジュールの概要,ソフトウェアのインストール方法,プログラミング方法を記載しています。 RTLinux上での弊社デジタル入出力I/Oモジュールを使ったプログラミングにお役に立てれば幸いです。 本書では、以下記載がない限り、「RTLinux」は「RTLinux/Free」のことを指します。 なお本冊子はRTLinuxバージョン3.1を対象に作成されています。RTLinuxのバージョンが異なる場合、動作保証はいたしかねますので予めご了承ください。

●ご意見・ご要望 弊社へのご意見,ご要望がございましたら、下記までお問い合わせください。

www.interface.co.jp E-mail:[email protected]

●本冊子で扱うソフトウェア 本冊子で扱うソフトウェア製品を以下に列挙します。

ソフトウェア製品名 型式 デジタル入出力I/Oモジュール Linux/RTドライバソフトウェア GPG-2000

●ソフトウェアの入手方法について デジタル入出力I/OモジュールのLinux/RTLinux対応ドライバソフトウェア(GPG-2000)をお求めの際は、弊社お客様相談センタまでお問い合わせください。

●デジタル入出力I/OモジュールのLinux/RTLinux対応ドライバソフトウェア(GPG-2000)のドキュメント構成について 各ドキュメントに掲載している内容は下記のとおりです。 ドキュメント 内容

Readme 製品のインストール方法や、アンインストール方法,ファイル構成の他、製品に関する最新情報を掲載しています。 このドキュメントを最初に確認してください。

ヘルプ ドライバソフトウェアの仕様,関数の個別説明、および使用方法等の説明を掲載しています。プログラム作成時に確認してください。

チュートリアル 本ドキュメントです。初めてRTLinux上でデジタル入出力I/Oモジュールを制御する時や、デジタル入出力I/Oモジュールを使用したシステム構築時の参考として確認してください。 本ドキュメントの他、RTLinuxの導入編のチュートリアルを合わせて参照してください。 RTLinuxのインストールや、基本的なプログラミング等が記載されています。

また、本ドキュメントは、あらかじめRTLinuxのインストール、および使用されるソフトウェア(GPG-2000)のインストールを済ませた方を対象に記述しています。

Page 7: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

- 5 - Interface Corporation

●本書での表記について コマンドの実行例において、行頭に「%」がつく場合は一般ユーザでの実行、「#」がつく場合はrootでの実行を意味します。「%」や「#」は実際に入力する文字ではありませんのでご注意ください。

対象環境 本チュートリアルは以下の制約事項があります。 対象型式 (PCI)

PCI-2104C PCI-2130C PCI-2131 PCI-2131AM PCI-2135 PCI-2152C PCI-2230C PCI-2402C PCI-2426C PCI-2430C PCI-2464C PCI-2503 PCI-2702C PCI-2722 PCI-2724CL PCI-2725A PCI-2725L PCI-2726CL PCI-2727A PCI-2727L PCI-2753 PCI-2756AM PCI-2758AM PCI-2762CM PCI-2793 PCI-2826C PCI-287244 PCI-2994CV

PCI-2105A PCI-2130CL PCI-2131A PCI-2131L PCI-2135L PCI-2154C PCI-2230CV PCI-2403A PCI-2427 PCI-2431 PCI-2466C PCI-2512C PCI-2703 PCI-2723C PCI-2724CM PCI-2725AL PCI-2725M PCI-2726CM PCI-2727AL PCI-2727M PCI-2756A PCI-2758A PCI-2760C PCI-2768C PCI-2796C PCI-2826CV PCI-292388

PCI-2128 PCI-2130CM PCI-2131AL PCI-2131M PCI-2135M PCI-2162 PCI-2330CV PCI-2424 PCI-2427A PCI-2431A PCI-2470 PCI-2513 PCI-2703A PCI-2724C PCI-2725 PCI-2725AM PCI-2726C PCI-2727 PCI-2727AM PCI-2752C PCI-2756AL PCI-2758AL PCI-2762C PCI-2790C PCI-2798C PCI-287144 PCI-2994C

対象型式 (CPZ)

CPZ-2104 CPZ-2130L CPZ-2154 CPZ-2330V CPZ-2464 CPZ-2506 CPZ-2517 CPZ-2723 CPZ-2724M CPZ-2726M CPZ-2762 CPZ-2769 CPZ-2799 CPZ-2827V CPZ-287244 CPZ-2994

CPZ-2128 CPZ-2130M CPZ-2230 CPZ-2402 CPZ-2466 CPZ-2515 CPZ-2702 CPZ-2724 CPZ-2726 CPZ-2752 CPZ-2762M CPZ-2790 CPZ-2826 CPZ-286122 CPZ-292388 CPZ-2994V

CPZ-2130 CPZ-2152 CPZ-2230V CPZ-2430 CPZ-2505 CPZ-2516 CPZ-2703 CPZ-2724L CPZ-2726L CPZ-2760 CPZ-2768 CPZ-2798 CPZ-2826V CPZ-287144 CPZ-294188 CPZ-2995V

Page 8: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

Interface Corporation - 6 -

対象型式 (CTP)

CTP-2104 CTP-2130L CTP-2131L CTP-2135L CTP-2154 CTP-2230V CTP-2424 CTP-2464 CTP-2506 CTP-2517 CTP-2722 CTP-2724L CTP-2725L CTP-2726L CTP-2727L CTP-2753 CTP-2762M CTP-2790 CTP-2826 CTP-286122 CTP-292388 CTP-2994V

CTP-2128 CTP-2130M CTP-2131M CTP-2135M CTP-2162 CTP-2330V CTP-2430 CTP-2466 CTP-2515 CTP-2702 CTP-2723 CTP-2724M CTP-2725M CTP-2726M CTP-2727M CTP-2760 CTP-2768 CTP-2798 CTP-2826V CTP-287144 CTP-294188 CTP-2995V

CTP-2130 CTP-2131 CTP-2135 CTP-2152 CTP-2230 CTP-2402 CTP-2431 CTP-2505 CTP-2516 CTP-2703 CTP-2724 CTP-2725 CTP-2726 CTP-2727 CTP-2752 CTP-2762 CTP-2769 CTP-2799 CTP-2827V CTP-287244 CTP-2994

対象型式 (CSI)

CSI-292366 CSI-293166

対象型式 (LPC)

LPC-224140 LPC-251101 LPC-292366

LPC-234104 LPC-284122 LPC-293166

LPC-251100 LPC-285122

対象型式 (PEX)

PEX-224140 PEX-251101 PEX-292366

PEX-234104 PEX-284122 PEX-293166

PEX-251100 PEX-285122

対象ユーザ 制御用電子機器および、コンピュータ等に関して基本的な知識を有している方。

※本冊子は上記の弊社製品型式のみに対応しています。 製品の詳細は弊社Web siteを参照してください。

Page 9: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

- 7 - Interface Corporation

第1章 デジタル入出力概要

コンピュータはデジタル信号で動作しています。コンピュータに入力される情報,コンピュータから出力する情報は全てデジタルで処理されます。 また、世の中には様々なスイッチ,センサといったものが数多くありますが、電気的にON/OFFでその状態を示すことが可能な情報は、コンピュータに入力することが可能です。これとは逆に、

その状態をコンピュータから作り出す(出力する)ことも可能です。 身近な例でいえば、よくテレビ番組で「お手元のスイッチでYESかNOかお答えください」という司会者の問いかけに観客が答え、その集計結果が電光パネルに表示されるといったものをご覧に

なったことがあると思います。 これはスイッチの情報、つまりは「YES」か「NO」かといったデジタル情報がコンピュータに入力され、その集計結果の情報が電光パネルに出力され表示されるといった、デジタル入出力シス

テムの一例です。 集計結果を電光パネルに表示する際、コンピュータは電光パネルに対し「特定の箇所を光らせる」

といったことを行っています。言いかえれば、発光部品への「ON」,「OFF」のデジタル情報を電光パネルに送っているわけです。

ONON

ON OFF

OFF ON

ON

Yesの入力信号をカウント

‘5’と光らせる

Yes

Yes

Yes

Page 10: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

Interface Corporation - 8 -

第2章 DIO(Digital Input Output) on RTLinux

RTLinuxは、Linux上でリアルタイム処理を可能にするOSです。そのRTLinux上でデジタル入出力I/Oモジュールを動かすことにより、リアルタイム性が要求されるシステムを構築することが可能になります。

2.1 パフォーマンス

RTLinuxとLinuxで、応答性と周期性を比較します。 測定環境は次の通りです。

パフォーマンス測定環境

項目 内容 CPUモジュール CTP-PE09シリーズ デジタルI/Oモジュール CTP-2703 Linuxカーネルバージョン 2.4.4 RTLinux バージョン RTLinux 3.1

2.1.1 応答性

汎用入力信号IN1の割り込みが発生してから、コールバック関数内ですぐにデジタル出力関数を呼び出した場合の応答時間を測定しました。 RTLinux,Linuxともに、1000回応答時間を測定しています。

汎用入力信号IN1割り込み

 コールバック関数

コールバック関数呼び出し

デジタル出力処理

この時間を測定

デジタル出力

時間

IN1(割り込み)

OUT1

応答時間

デジタル出力処理

コールバック関数起動

IN1をON

応答性の測定,応答時間

Page 11: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

- 9 - Interface Corporation

RTLinuxでは、平均応答時間,最大応答時間,最小応答時間の全てにおいてLinuxよりも優れた結果が出ています。 RTLinuxの平均応答時間は、Linuxより8μs程度速い結果となりました また、注目されるのが、最大応答時間です。Linuxでは、36.3μsにまで応答時間のぶれが発生しているのに対し、RTLinuxでは、18.8μsまでしか、ぶれが発生していません。

0

5

10

15

20

25

30

35

40

0 100 200 300 400 500 600 700 800 900 10000

5

10

15

20

25

30

35

40

0 100 200 300 400 500 600 700 800 900 1000

RTLinux Linux

(件)

(μs)

(件)

(μs)

RTLinuxとLinuxの応答時間の比較グラフ

応答時間の分布

件数データ区間(μs) RTLinux Linux~8 0 09 0 010 845 011 153 012 0 013 0 014 0 015 0 016 1 017 0 45218 0 50519 1 3920 0 121 0 022 0 023 0 0

24~ 0 3

応答時間のトータル結果 測定環境

トータル結果RTLinux Linux

平均(μs) 9.6 17.3最大(μs) 18.8 36.3最小(μs) 9.4 16.7標準偏差(σ) 0.48 0.92

Page 12: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

Interface Corporation - 10 -

2.1.2 周期性

次に、指定した周期でデジタル信号出力を繰り返し行い、その周期性のぶれを測定しました。 こちらも1000回ずつ測定を行っています。 Linuxでは1ms周期を実行しても20msより短い周期実行が行えなかったため、100ms周期に出力を行う設定で測定しています。 RTLinuxは、1ms周期でも安定した動作が確認できたため、1ms周期の周期性を測定しました。

RTLinuxとLinuxの周期周期性測定結果

RTLinux Linux 測定環境 指定 周期(μs)

平均 (μs)

最大 (μs)

最小 (μs)

標準偏差(σ)

平均 (μs)

最大 (μs)

最小 (μs)

標準偏差(σ)

100000 98434.42 98439.98 98431.76 1.794 106808.75 106816.08 104424.12 75.56 10000 9844.188 9847.56 9839.34 1.757 19686.99 19729.37 19593.74 0.336 1000 971.8 975.57 967.2 0.944 19686.93 19723.89 19599.22 10.708

Linuxでは、指定した周期が100msであるにも関わらず、平均で7ms程度遅れが出ました。また、最大値と最小値のぶれ幅も大きい結果となりました。 RTLinuxでは、ほぼ指定周期通り実行され、さらに最大値と最小値のぶれも小さくなっています。 次の図は、周期性のぶれを、時間軸(X軸)を同じスケールにして比較したものです。

105700

105900

106100

106300

106500

106700

106900

0 200 400 600 800 10000

200

400

600

800

1000

1200

0 200 400 600 800 1000

RTLinux Linux

(件)

(μs)

(件)

(μs)

・ほぼ指定した周期 1ms(1000μs)通りに動作し、ぶれが少ない。・指定した周期は、100ms(100000μs)だが、107ms(107000μs)程度まで遅れている。また、ばらつきがある。

RTLinuxとLinuxの周期性結果グラフ

Page 13: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

- 11 - Interface Corporation

2.2 RTLinuxによるデジタル入出力制御

RTLinux上で弊社デジタル入出力I/Oモジュールを制御するには、リアルタイムタスクから、RTLinux対応デジタル入出力ドライバソフトウェアの関数をコールします。また、RTLinuxとLinuxとのやりとりをする場合は、リアルタイムFIFOを使用します。

DIO I/Oモジュール

RTLinux対応ドライバモジュール( )

リアルタイムタスク

デジタル出力

デジタル入力

リアルタイム

Linuxアプリケーション

外部機器

RTLinux上でのデジタル入出力I/Oモジュール制御構成

●リアルタイムタスク リアルタイム処理を行うモジュールです。リアルタイム処理を行うには、このリアルタイムタ

スクを作成しなければなりません。このリアルタイムタスクは通常のLinuxのプロセスよりも、リアルタイムタスクのほうが優先して実行されます。

●リアルタイムFIFO リアルタイムタスクとLinuxアプリケーション、またはリアルタイムタスクとリアルタイムタスクとの間のデータの受け渡しを行うものです。このリアルタイムFIFOを利用して、データの受け渡しを行います。 ★リアルタイムFIFO リアルタイムFIFOはデバイスとして扱われており、/dev/rtf0等という名前で存在しています。

Page 14: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

Interface Corporation - 12 -

2.2.1 デジタル入出力I/Oモジュール制御概略

デジタル入出力I/Oモジュールの制御は、下記の制御シーケンス(順番)で行います。

I/Oモジュール初期化

各種処理

終了処理 (3)

(2)

(1)

デジタル入出力I/Oモジュールの制御シーケンス

(1)I/Oモジュールの初期化 作成されたリアルタイムタスクがデジタル入出力I/Oモジュールへの操作を行うため、まず、I/Oモジュールを利用可能な状態にします。 この処理がI/Oモジュールの初期化です。I/Oモジュールの初期化を行うと、プログラムはI/Oモジュールへのアクセスが可能となります。本処理が行われないとI/Oモジュールへのアクセスは行えません。

(2)I/Oモジュールの入力ポートまたは出力ポートより、信号の入力または出力を行います。 (3)終了処理

I/Oモジュールの使用終了を行うための手続きです。プログラム終了時に行います。

Page 15: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

- 13 - Interface Corporation

第3章 デジタル入出力I/Oモジュール制御の第一歩

ここでは、実際に弊社デジタル入出力I/Oモジュールを用いて、デジタル信号入力,デジタル信号出力プログラムの作成を行います。この章では以下の製品を使用しています。

PCI-2726C 1枚:32/32デジタル入出力I/Oモジュール ECO-64xx,66xxシリーズ 1本:96芯ハーフピッチコネクタ両端コネクタケーブル

ケーブル長により型式が異なります。 例)ECO-6610:1m, ECO-6620:2m, ECO-6650:5m

CHK-2101 1枚:64点スイッチ,64点LEDテストI/Oモジュール

コンピュータにデジタル入出力I/Oモジュール(PCI-2726C)が1枚実装され、信号確認用に、弊社「64点スイッチ64点LEDテストI/Oモジュール(CHK-2101)」を使用しています。PCI-2726CとCHK-2101は弊社「96芯ハ-フピッチコネクタ両端コネクタケ-ブル(ECO-66xx)」で接続されます。

PCI-2726C

CHK-2101

CAB-66xxECO-66xx

PCI-2726CとCHK-2101の接続図

CHK-2101は入出力64点,制御信号10点の擬似入力スイッチと信号モニタ用LEDを装備していますので、信号ラインの状態を容易に確認することができるテストツールです。 CHK-2101は以下のように設定します。

c DC+12V

Page 16: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

Interface Corporation - 14 -

I/Oモジュールをシステムに組み込んでから、動かすまでの流れは下記のようになります。 各項目に従って、RTLinux上でのデジタル入出力I/Oモジュール制御プログラミングを行っていきましょう。

リアルタイムモジュールの組み込み

RTLinux DIOドライバ組み込み

プログラミング

コンパイル

実行

RTLinux上でのI/Oモジュール制御までの流れ

3.1 RTLinuxリアルタイムモジュール組み込み

RTLinuxをインストールすると、下記の5つのモジュールが、RTLinuxのインストールディレクトリの下の、modulesディレクトリに格納されます(RTLinuxのインストールに関してはRTLinux導入編のチュートリアルを参照してください)。 Linux上でリアルタイム処理を行うために、下記の5つのリアルタイムモジュールをLinuxカーネル内に組み込ます。 ● rtl.o ● rtl_fifo.o

● rtl_posixio.o

● rtl_sched.o ● rtl_time.o

これらのモジュールを組み込まなければ、リアルタイム処理が行えません。 モジュールを組み込むにはスーパーユーザになる必要があるため、まずはスーパーユーザになり

ましょう。 %su Password: ----- rootのパスワードを入力してください。

それでは、先の5つのリアルタイムモジュールを組み込みます。 RTLinuxに関するスクリプトを格納しているscriptsディレクトリに、リアルタイムモジュールを組み込むための便利なシェルスクリプトが用意されています。 RTLinuxをインストールしたソースディレクトリに移り、リアルタイムモジュール組み込みシェルスクリプトを実行します。 #cd /usr/src/rtlinux-3.1 #sh scripts/insrtl

Page 17: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

- 15 - Interface Corporation

★ シェルスクリプトについて シェルスクリプトとは、端末から打ち込むコマンドを、まとめて実行させるように記述したファイルです。高機能なバッチ処理を行うことができます。

ここで、insrtlがscriptsディレクトリにあるのならば、なぜ #cd /usr/src/rtlinux-3.1/scripts #sh insrtl とやらないかというと、/usr/src/rtlinux-3.1/scriptsからでは、RTLinuxのリアルタイムモジュールを格納しているディレクトリへのパスが、insrtlの設定しているパスと異なってエラーとなってしまうからです。 また、リアルタイムモジュールはinsmodで組み込むことができますが、それぞれのモジュールは、組み込む順番が決まっているため、間違った順番でモジュールを組み込もうとしても組み込むことができません。 用意されているinsrtlシェルスクリプトを使用することで簡単にモジュールを組み込むことができます。

これでリアルタイムモジュールが組み込まれました。組み込まれたかどうかをlsmodコマンドを使って確認してみましょう。 #lsmod Module Size Used by rtl_sched 43200 0 (unused) rtl_fifo 10016 0 (unused) rtl_posixio 7216 0 [rtl_fifo] rtl_time 10064 0 [rtl_sched rtl_posixio] rtl 27184 0 [rtl_sched rtl_fifo rtl_posixio

rtl_time]

5つのモジュールが組み込まれていることが分かります。 これで、リアルタイム処理を行うプログラミングができるようになりました。 ★RTLinuxのリアルタイムモジュール これらの5つのリアルタイムモジュールを組み込んだ後、 #less /proc/ksyms を実行すると、これらのモジュールが公開している関数等を確認することができます。それらを見ることによって、どのモジュールがどのような役割を持っているかが分かります。

これら5つのモジュールをカーネルから取り外す場合は、下記のようにコマンドを打ち込みます。 #cd /usr/src/rtlinux-3.1 #sh scripts/rmrtl

Page 18: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

Interface Corporation - 16 -

3.2 RTLinux デジタル入出力ドライバ組み込み

先ほどの5つのリアルタイムモジュール組み込み後に、デジタル入出力ドライバモジュールを組み込むことにより、デジタル入出力I/Oモジュールのリアルタイム制御が行えるようになります。デジタル入出力ドライバモジュールは、GPG-2000インストール後に/lib/modules/2.4.4-rtl/miscディレクトリに格納されます(GPG-2000のインストール方法については、Readmeを参照してください)。 デジタル入出力I/Oモジュールを制御するドライバモジュールは、dpg0100.o,dpg0102.o,rcp2000.oの3つあり、これら3つを組み込む必要があります。 ●rcp2000.o デジタル入出力I/Oモジュール制御のドライバモジュール本体です。 実際にI/Oモジュールを制御するためのモジュールです。このドライバモジュール内の関数をリアルタイムタスクからコールすることにより、デジタル入出力I/Oモジュールを制御することができます。

●dpg0100.o

dpg0102.o 弊社RTLinuxドライバ群の共用モジュールです。

★ その他のモジュールについて rcp2000t.oはI/Oモジュールがなくてもドライバを動かすことができるテストドライバです。rcp2000.oの代わりに、rcp2000t.oを組み込むことで、I/Oモジュールを実装しなくても、各関数を実行することができます。詳しい説明はヘルプを参照してください。

以降の説明中のディレクトリパスは、カーネルバージョンが2.4.4,インストールディレクトリをデフォルトに指定した場合です。

まず、次のようにスクリプトを実行してドライバモジュールを組み込みます。 #cd /usr/src/interface/gpg2000/i386/rtl/drivers #sh insdio.sh

次に、デバイス番号設定プログラムを起動して、デバイス番号の設定を行います。 インストール後、必ず1度は実行する必要があります。 次のようにスクリプトを実行します。 #cd /usr/src/interface/gpg2000/i386/rtl/drivers #sh setup.sh

Page 19: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

- 17 - Interface Corporation

デバイス番号設定ユーティリティを起動させると、以下の画面が表示されます。 ************************************************** Setup Utility -------------------------------------------------- Version: 1.10-05 -------------------------------------------------- Copyright 2003, 2004 Interface Corporation. All rights reserved. ************************************************** Enter the model number of the product: GPG/GPH- ============================================= Ref.ID | Model | RSW1 | Device No. --------------------------------------------- 1 | PCI-2726C | 0 | 1 ============================================= **************** Menu **************** 1. Change the device number. 2. Delete the device number. 3. Load new device setting file. 4. Run the CardBus ID setup utility. 5. Run the initialization program. 99. Exit the program. ************************************** Enter the command number:

入力画面では、”2000”を打ち込んでリターンキーを押してください。 I/Oモジュールが実装されている場合、認識したI/Oモジュールが表示されます。また、初期値として、デバイス番号は認識したI/Oモジュール順に1から割り振られます。デバイス番号は、変更が可能です。ここでは、初期値である「1」をそのまま使用するため、「99」を入力してリターンキーを押し、デバイス番号設定プログラムを終了させます。 これで、デバイス番号の設定は完了です。GPG-2000の各関数の引数パラメータにあるデバイス番号指定を「1」にすることで、制御することができるようになります。 それでは、デジタル入出力ドライバモジュールを組み込んでみましょう。 デバイス番号設定プログラムを起動するスクリプトと同じディレクトリに、ドライバモジュール

の組み込みスクリプトがあります。 #sh insdio.sh

モジュールが組み込まれているかどうかlsmodコマンドを使って確認します。 #lsmod Module Size Used by rcp2000 18448 0 (unused) dpg0102 5072 0 [rcp2000] dpg0100 4688 0 [rcp2000] rtl_sched 43200 0 [rcp2000] rtl_fifo 10016 0 (unused) rtl_posixio 7216 0 [rtl_fifo] rtl_time 10064 0 [rcp2000 rtl_sched rtl_posixio] rtl 27184 0 [rcp2000 dpg0102 rtl_sched rtl_fifo rtl_ posixio rtl_time]

Page 20: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

Interface Corporation - 18 -

dpg0100,dpg0102,rcp2000が組み込まれていることが分かります。 以上でデジタル入出力I/Oモジュールのリアルタイム制御を行うプログラミングの準備が整いました。 取り外すときは以下のようにスクリプトを実行します。 スクリプトは、ドライバモジュールの組み込みスクリプトと同じディレクトリにあります。 #cd /usr/src/interface/gpg2000/i386/rtl/drivers #sh rmdio.sh

以上で下準備は終わりです。次からいよいよプログラミングを行っていきます。

Page 21: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

- 19 - Interface Corporation

3.3 デジタル入力プログラムを作ろう

3.3.1 プログラミング

ここでは、デジタル入出力I/Oモジュールのリアルタイム制御を行うための第一歩として、周期的にデータを入出力する単純なプログラムを作成します。 RTLinuxのリアルタイム処理は、その確実な周期性が1つの特長になっています(『10ページ 2.1.2 周期性』参照)。ここでは、その特長を使って、周期的にデジタル入力するプログラムを作成しましょう。 『16ページ 3.2 RTLinux デジタル入出力ドライバ組み込み』までで、RTLinuxのリアルタイムモジュールの組み込み,GPG-2000のドライバモジュールの組み込みを行いました。 あとはプログラミング、コンパイルするだけですが、『11ページ 2.2 RTLinuxによるデジタル入出力制御』にあるように、リアルタイム処理を行うには、通常のアプリケーションプログラム

を作成するのではなく、リアルタイムタスクというモジュールを作成しなければなりません。

Linuxアプリケーションリアルタイム処理できない・・・。

リアルタイムタスク(モジュール)

リアルタイム処理できる!

Linuxアプリケーションとリアルタイムタスクの違い

それでは、デジタル入力を行うリアルタイムタスクモジュールを作成しましょう。 CHK-2101に設定された情報(スイッチのON/OFF)をコンピュータに取り込むプログラムの作成を行います。PCI-2726C以外では、対応するテストI/Oモジュールおよび接続用ケーブルの製品型式が異なる場合がありますのでご注意ください。

Page 22: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

Interface Corporation - 20 -

ここで記載するソースコードは、以下の製品型式において利用可能です。 デジタル入力 デジタル入出力 PCI-2104C PCI-2105A PCI-2128 PCI-2130C PCI-2130CL PCI-2130CM PCI-2131 PCI-2131A PCI-2131AL PCI-2131AM PCI-2131L PCI-2131M PCI-2135 PCI-2135L PCI-2135M PCI-2152C PCI-2154C PCI-2162 PCI-2230C PCI-2230CV

CTP-2104 CTP-2128 CTP-2130 CTP-2130L CTP-2130M CTP-2131 CTP-2131L CTP-2131M CTP-2135 CTP-2135L CTP-2135M CTP-2152 CTP-2154 CTP-2162 CTP-2230 CTP-2230V CPZ-2104 CPZ-2130 CPZ-2130L CPZ-2130M CPZ-2152 CPZ-2154 CPZ-2230 CPZ-2230V LPC-224140 PEX-224140

PCI-2702C PCI-2703 PCI-2703A PCI-2722 PCI-2723C PCI-2724C PCI-2724CL PCI-2724CM PCI-2725 PCI-2725A PCI-2725AL PCI-2725AM PCI-2725L PCI-2725M PCI-2726C PCI-2726CL PCI-2726CM PCI-2727 PCI-2727A PCI-2727AL PCI-2727AM PCI-2727L PCI-2727M PCI-2752C PCI-2753 PCI-2756A PCI-2756AL PCI-2756AM PCI-2758A PCI-2758AL PCI-2758AM PCI-2760C PCI-2762C PCI-2762CM PCI-2768C PCI-2790C

PCI-2793 PCI-2796C PCI-2798C PCI-2826C PCI-2826CV PCI-2994C PCI-2994CV PCI-287144 PCI-287244 PCI-292388 CSI-292366 CSI-293166 LPC-284122 LPC-285122 LPC-292366 LPC-293166 PEX-284122 PEX-285122 PEX-292366 PEX-293166

CTP-2702 CTP-2703 CTP-2722 CTP-2723 CTP-2724 CTP-2724L CTP-2724M CTP-2725 CTP-2725L CTP-2725M CTP-2726 CTP-2726L CTP-2726M CTP-2727 CTP-2727L CTP-2727M CTP-2752 CTP-2753 CTP-2760 CTP-2762 CTP-2762M CTP-2768 CTP-2769 CTP-2790 CTP-2798 CTP-2799 CTP-2826 CTP-2826V CTP-2827V CTP-2994 CTP-2994V CTP-2995V CTP-286122 CTP-287144 CTP-287244 CTP-292388 CTP-294188

CPZ-2702 CPZ-2703 CPZ-2723 CPZ-2724 CPZ-2724L CPZ-2724M CPZ-2726 CPZ-2726L CPZ-2726M CPZ-2727L CPZ-2752 CPZ-2760 CPZ-2762 CPZ-2762M CPZ-2768 CPZ-2769 CPZ-2790 CPZ-2798 CPZ-2799 CPZ-2826 CPZ-2826V CPZ-2827V CPZ-2994 CPZ-2994V CPZ-2995V CPZ-286122 CPZ-287144 CPZ-287244 CPZ-292388 CPZ-294188

注意!

テストI/Oモジュールのない型式もあります。詳細は弊社Web site(www.interface.co.jp)にて確

認してください。

各製品型式においては、入力点数が異なりますので、ご使用になる製品型式により一部実

行できない処理が含まれます。

Page 23: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

- 21 - Interface Corporation

弊社テストI/Oモジュールをご用意できない場合は、各製品仕様に応じ、以下の配線を行ってください。配線には弊社端子台(TRM-xxxx)等をご利用ください。 PCI-○○○○LやPCI-○○○○MやPCI-○○○○V等の最後に“L”や“M”や“V”がある型式は、“L”や“M”や“V”がない場合の型式と同じ配線を行ってください。また同様に“TK”や“TL”がある型式も“TK”や“TL”がない場合の型式と同じ配線を行ってください。 下表に示されていない型式の配線は、各型式のUSER’S MANUALを参照してください。

配線1 配線2 配線3 配線4 配線5 配線6

PCI-2130C PCI-2131 PCI-2131A PCI-2724C PCI-2725 PCI-2725A PCI-2726C PCI-2727 PCI-2727A PCI-2756A PCI-2758A PCI-2762C CTP-2130 CTP-2131 CTP-2724 CTP-2725 CTP-2726 CTP-2727 CTP-2762 CPZ-2130 CPZ-2724 CPZ-2726 CPZ-2762

LPC-285122 PEX-285122

PCI-2104C PCI-2105A PCI-2128 PCI-2152C PCI-2154C PCI-2162 PCI-2230C PCI-2702C PCI-2703 PCI-2703A PCI-2723C PCI-2752C PCI-2753 PCI-2760C PCI-2768C PCI-2790C PCI-2796C PCI-2798C PCI-2826C PCI-2994C PCI-292388 PCI-2793 PCI-2722 CTP-2104 CTP-2128 CTP-2152 CTP-2154 CTP-2162 CTP-2230 CTP-2702 CTP-2703 CTP-2722 CTP-2723 CTP-2752 CTP-2753 CTP-2760 CTP-2768 CTP-2769 CTP-2790 CTP-2798 CTP-2799 CTP-2826 CTP-2827 CTP-2994 CTP-2995 CTP-292388 CTP-294188

CPZ-2104 CPZ-2152 CPZ-2154 CPZ-2230 CPZ-2702 CPZ-2703 CPZ-2723 CPZ-2752 CPZ-2760 CPZ-2768 CPZ-2769 CPZ-2790 CPZ-2798 CPZ-2799 CPZ-2826 CPZ-2827 CPZ-2994 CPZ-2995 CPZ-292366 CPZ-294188 CSI-292388 CSI-293166 LPC-224140 LPC-284122 PEX-224140 PEX-284122

PCI-2135 CTP-2135 CTP-286122 CPZ-286122 LPC-251100 PEX-251100

PCI-287144 CTP-287144 CPZ-287144

PCI-287244 CTP-287244 CPZ-287244

Page 24: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

Interface Corporation - 22 -

外部電源

+極

-極

IN1IN2IN3

+COM*

+極-極

•••

•••

外部電源

配線 1 配線 2

IN1IN2IN3

-COM*

•••

•••

-COM*

デジタル入力配線1 デジタル入力配線2 使用できる外部電源電圧は、各製品によって異なり、下表のように分類されます。

12V 12V~24V 24V PCI-2130C PCI-2130CL PCI-2130CM PCI-2131 PCI-2731AL PCI-2131AM PCI-2131A PCI-2131L PCI-2131M PCI-2724C PCI-2724CL PCI-2724CM PCI-2725 PCI-2725AL PCI-2725AM PCI-2725A PCI-2725L PCI-2725M PCI-2726C PCI-2726CL PCI-2726CM PCI-2727 PCI-2727AL PCI-2727AM PCI-2727A PCI-2727L PCI-2727M PCI-2756A PCI-2756AL PCI-2756AM PCI-2758A PCI-2758AL PCI-2758AM PCI-2762C CTP-2130L PCI-2762CM CTP-2130 CTP-2131L CTP-2130M CTP-2131 CTP-2724L CTP-2131M CTP-2724 CTP-2725L CTP-2724M CTP-2725 CTP-2726L CTP-2725M CTP-2726 CTP-2727L CTP-2726M CTP-2727 CPZ-2130L CTP-2727M CTP-2762 CPZ-2724L CTP-2762M CPZ-2130 CPZ-2726L CPZ-2130M CPZ-2724 CPZ-2727L CPZ-2724M CPZ-2726 CPZ-2726M CPZ-2762 CPZ-2762M

Page 25: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

- 23 - Interface Corporation

IN1 IN2 IN3

-COM*

• • •

+極 -極

-極

外部電源

IN1IN2IN3

• • •

IN1IN2IN3• • •

+極

配線 3 配線 4

1点ごとに異なる外部電源を繋げることができます。

• • •

• • •

• • •

デジタル入力配線3 デジタル入力配線4 使用できる外部電源電圧は、各製品によって異なり、下表のように分類されます。

12V 12V~24V 24V PCI-2135 PCI-2135L PCI-2135M CTP-2135 CTP-2135L CTP-2135M CTP-286122 CPZ-286122 LPC-251100 PEX-251100

外部電源

+極

-極

配線 5

IN1IN2IN3

-COM*

•••

•••

COM*IN1IN2

配線 6

IN3•••

•••

デジタル入力配線5 デジタル入力配線6

Page 26: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

Interface Corporation - 24 -

■Step 1. 初期化処理と終了処理

それでは、デジタル入力I/Oモジュールを制御するプログラム(リアルタイムモジュール)を作成してみましょう。 まず、デジタル入力I/Oモジュール制御の第一歩として、もっとも最小のプログラム、I/Oモジュールの初期化(オープン)と終了処理(クローズ)のみのプログラムを作成します。 初期化(オープン)と終了処理(クローズ)は、デジタル出力I/Oモジュールを制御する場合も同じように必要です。 エディタを起動し、下記Listに示すコードを記述します。

inputtask.c 1

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32

#include <rtl.h> #include "fbidio.h" #define DIO_DEVICENO 1 int init_module(void) { int nRet; EXPORT_NO_SYMBOLS; nRet = DioOpen(DIO_DEVICENO,0); if(nRet){ rtl_printf(" Open error[DeviceNo%d]:Return vlaue=0x%x¥n", DIO_DEVICENO, nRet); return -1; } return 0; } void cleanup_module(void) { int nRet; nRet = DioClose(DIO_DEVICENO); if(nRet){ rtl_printf(" Close error[DeviceNo%d]:Return value=0x%x¥n", DIO_DEVICENO, nRet); } }

コードの記述が終われば、inputtask.cというファイル名で保存してください。 プログラムの記述は以上で終わりです。 では、プログラム内容を確認していきましょう。

Page 27: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

- 25 - Interface Corporation

(Line 6~20) 今作成しているリアルタイムタスクがカーネルに組み込まれたときに呼ばれるinit_module関数です。insmodコマンドを実行した段階で、この関数の処理が行われます。この部分に初期化コードを記述します。 リアルタイムタスクの中で何度もI/Oモジュールをオープン,クローズすることはパフォーマンスの低下に繋がります。init_module関数内でポートの初期化(オープン)を行う方が速度の面で有利です。 ★init_moduleでの禁止事項 リアルタイムタスクは、カーネル空間に存在するため、ユーザ空間でできないことができる反面、一歩間違えると、カーネルやファイルシステムを破壊してしまう恐れがあります。 代表的な禁止事項として、init_module関数内ではusleep関数を呼び出してはいけません。Linuxが起動しなくなってしまう場合があります。

(Line 10) EXPORT_NO_SYMBOLSマクロを定義することによって、グローバルシンボルを非公開にします。 ★グローバルシンボル モジュールがカーネル内に組み込まれると、グローバル変数や、グローバル関数等のシンボルは、他のカーネルモジュールから参照できるようになります。 本チュートリアルのリアルタイムタスクモジュールは、他のカーネルモジュールに変数や、関数を公開する必要がありませんので、シンボルの多重定義(名前汚染)を防ぐためにEXPORT_NO_SYMBOLSマクロを定義して、シンボルを公開しません。 カーネルのグローバルシンボルは、/proc/ksymsで確認することができます。

(Line 12~17) ポートの初期化(オープン)を行い、成功したかどうかをチェックしています。 DioOpen関数は、I/Oモジュール制御の一番最初にコールします。 (Line 22~31) モジュール取り外し時 (rmmodコマンド実行時 )に呼ばれる cleanup_module関数です。cleanup_module関数の中で終了処理を行います。 (Line 26~30) DioClose関数をコールしI/Oモジュールの終了処理(クローズ)を行い、成功したかどうかをチェックしています。 以上で初期化、終了処理のプログラムの完成です。init_module関数の中で、I/Oモジュールの初期化を行い、cleanup_module関数の中でI/Oモジュールの終了処理を行います。

Page 28: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

Interface Corporation - 26 -

■Step 2. デジタル入力処理の作成

次に、デジタル入力を行う処理を、さきほど作成した初期化と終了処理を行うプログラムに追加

してみましょう。 エディタを起動し、下記Listの網掛けの部分を追加します。

inputtask.c 2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63

#include <rtl.h> #include <rtl_sched.h> #include "fbidio.h" #define DIO_DEVICENO 1 void* input_task(void *arg); pthread_t inputhread; void* input_task(void *arg) { int i; int nRet; struct sched_param p; int nBuffer[8]; p.sched_priority = 1; pthread_setschedparam(pthread_self(), SCHED_FIFO, &p); pthread_make_periodic_np(pthread_self(), gethrtime(),1000000000); while(1){ pthread_wait_np(); nRet = DioInputPoint(DIO_DEVICENO, &nBuffer[0], 1, 8); if(nRet){ rtl_printf("Input error[DeviceNo%d]:Return value=0x%x¥n", DIO_DEVICENO, nRet); }else{ rtl_printf("Input success[DeviceNo%d]:¥n", DIO_DEVICENO); for(i=0;i<8;i++){ rtl_printf("IN%x:%x ", i+1, nBuffer[i] ); } rtl_printf("¥n"); } } return 0; } int init_module(void) { int nRet; EXPORT_NO_SYMBOLS; nRet = DioOpen(DIO_DEVICENO,0); if(nRet){ rtl_printf(" Open error[DeviceNo%d]:Return vlaue=0x%x¥n", DIO_DEVICENO, nRet); return -1; } pthread_create(&inputhread, NULL, (void*)input_task, 0); return 0; } void cleanup_module(void) { int nRet;

Page 29: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

- 27 - Interface Corporation

64 65 66 67 68 69 70 71 72 73

pthread_cancel(inputhread); pthread_join(inputhread, NULL); nRet = DioClose(DIO_DEVICENO); if(nRet){ rtl_printf(" Close error[DeviceNo%d]:Return value=0x%x¥n", DIO_DEVICENO, nRet); } }

コードの記述が終われば保存してください。 では、追加したプログラム内容を確認していきましょう。 (Line 3) 初期化と終了処理は、それぞれinit_module関数とcleanup_module関数で行いましたが、周期的な処理をさせるため、デジタル入力処理は、作成したスレッドの中で行います。スレッドを取り扱う

には、rtl_sched.hをインクルードします。 ★スレッド 一言で言えば、実行単位です。複数の処理を並行して行いたい場合は、その行いたい処理ごとにスレッドを用意します。

(Line 8) スレッドを作成した際に呼ばれるinput_task関数のプロトタイプ宣言です。 (Line 10) スレッドを使用するための変数を宣言します。この変数には、スレッドを作成する関数

pthread_create関数が成功した場合、作成されたスレッドを識別するためのIDが格納されます。スレッドに関するほとんどの関数は、このIDを使用して対象のスレッドを指定します。 (Line 55) このpthread_create関数を呼ぶことでスレッドを作成します。pthread_create関数によってスレッドが作られれば、登録したinput_task関数が並行して実行されます。 ★pthread_create その名のとおり、スレッドを作成する関数です。第1引数にはスレッドのIDを格納するpthread_t変数へのポインタを、第2引数にはスレッドの属性を指定するpthread_attr_t変数へのポインタを、第3引数には作られたスレッドで処理する関数を、第4引数にはその関数に渡す引数を指定します。 ここではスレッドの属性は指定しないため、NULLを指定しています。

(Line 12~40) スレッドを作成した際に呼ばれるinput_task関数です。 1秒ごとにデジタル入力を行うリアルタイムタスクの例です。

Page 30: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

Interface Corporation - 28 -

★pthread_setschedparam リアルタイムタスクのスケジューリングの方法、優先度等を指定します。

★pthread_self リアルタイムタスク中でコールすると呼び出したスレッドのIDを取得することができます。スレッドIDを引数パラメータに指定する関数に対して自身のスレッドIDを指定する場合等に使用します。

★pthread_make_periodic_np 指定した待機中のスレッドを、指定した周期で目覚めさせる関数です。 第1引数にはスレッドのIDを指定します(ここでは、関数を呼び出したスレッドのIDを返すpthread_self関数により、自身のIDを取得しています)。第2引数には、リアルタイム処理の実行を開始する時間をhrtime_t型で指定します(ここではシステム起動からの絶対時間を取得するgethrtime関数を用いて、開始時間を関数呼び出しと同時にしています)。第3引数には、リアルタイム処理を実行する周期をns単位で設定します。おなじくhrtime_t型です。 リストに示すようにpthread_wait_npによるタスクの待機箇所を起点として、指定された周期でWhileループ中の処理が実行されます。

★pthread_wait_np pthread_wait_np関数は、pthread_make_periodic_np関数により、指定された周期まで待つ関数です。例えば、pthread_make_periodic_np関数により10msの周期を指定された場合、10msが経過するまで、このpthread_wait_np関数で待つことになります。 また、pthread_wakeup_npを呼ぶことでも実行を再開することができます。

(Line 64,65) モジュール取り外し時にスレッドを終了させます。pthread_cancel関数で、指定したスレッドに終了を要求し、pthread_join関数で指定したスレッドが終了するまで待ちます。

★終了時の関数 pthread_cancel関数は、引数に終了要求を出すスレッドのIDを指定します。pthread_join関数も第1引数に同じくスレッドのIDを指定します。第2引数は、ここではNULLにしています。pthread_exit関数でスレッドの処理を終わらせた場合に、pthread_exit関数の引数が、pthread_join関数の第2引数に格納されます。以下に例を示します。 void* input_task(void *arg) { int status = 10; ・・・ pthread_exit(status); ・・・ } void cleanup_module(void) { int value; pthread_join(send_thread, &value); // valueには10が格納されます ・・・ }

以上でデジタル入力処理を行うプログラムは終了です。

Page 31: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

- 29 - Interface Corporation

3.3.2 コンパイル

コンパイルはgccにて行います。メイクファイルを作成して、コンパイルを行います。 エディタを開き、下記Listを記述してMakefileというファイル名で保存しましょう。

Makefile 1

1 2 3 4 5 6 7 8

include /usr/include/rtlinux/rtl.mk all: inputtask.o inputtask.o:inputtask.c $(CC) $(INCLUDE) $(CFLAGS) -o inputtask.o -c inputtask.c

★include /usr/include/rtlinux/rtl.mk このメイクファイルでインクルードしている/usr/include/rtlinux/rtl.mkというファイルは、リアルタイムタスクをコンパイルするために必要な定義を全て行ってくれています(ヘッダファイルのインクルード等)。この方法でコンパイルを行うのもよいですが、作成するリアルタイムタスク名とソースファイル名とが同じ場合(拡張子は除く。例えばtest.cとtest.oのような場合)、メイクファイルは、 include /usr/include/rtlinux/rtl.mk all: test.o tast.o:test.c のみでもコンパイル可能となります。 メイクファイルの作成が終われば、実際にコンパイルを行います。 #make

コンパイルを行うことで、inputtask.oの1つのファイルができます。 inputtask.oはデジタル入力を行うリアルタイムモジュールです。

3.3.3 動かしてみよう

それでは実行してみます。 まずは、リアルタイムモジュール、ドライバモジュールの組み込みを行った後(『14ページ 3.1 RTLinuxリアルタイムモジュール組み込み』『16ページ 3.2 RTLinux デジタル入出力ドライバ組み込み』参照)、inputtask.oを組み込みます。 #insmod inputtask.o モジュールを組み込むと同時にデジタル入力リアルタイムタスクがスタートします。 入力したデータはrtl_printf関数を使用してログに記録されます。ログを見てみます。 #tail -f /var/log/messages ・・・ Apr 23 15:41:03 localhost kernel: Input success[DeviceNo1] Apr 23 15:41:03 localhost kernel: IN1:0 IN2:1 IN3:0 IN4:0 IN5:0 IN6:1 IN7:1 IN8:0 Apr 23 15:41:04 localhost kernel: Input success[DeviceNo1] Apr 23 15:41:04 localhost kernel: IN1:0 IN2:0 IN3:0 IN4:0 IN5:0 IN6:1 IN7:1 IN8:0 Apr 23 15:41:05 localhost kernel: Input success[DeviceNo1] Apr 23 15:41:05 localhost kernel: IN1:1 IN2:0 IN3:0 IN4:0 IN5:0 IN6:1 IN7:1 IN8:0 ・・・

以上のように、ログが表示されます。

Page 32: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

Interface Corporation - 30 -

★ログの表示について #tail -f /var/log/messages とコマンドを打ち込むと、messagesファイルにログが追加されるたびに、その追加されたログが表示されるようになります。 rtl_printf関数の実行結果が、printfと同じように画面に表示されます。

“Input success[DeviceNo1]”メッセージの次の行に表示されるデータが入力されたデータです。左からIN1,IN2,…,IN8と並んでいます。 0がOFF状態です。1がON状態を表します。 1秒ごとにデジタル信号を入力し、表示します。 接続したCHK-2101のスイッチを動かしてデータが変化するか確認してください。 確認が終わったらリアルタイムタスクモジュールを削除し、リアルタイムタスクを終了させます。 #rmmod inputtask

Page 33: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

- 31 - Interface Corporation

3.4 デジタル出力プログラムを作ろう

3.4.1 プログラミング

ここでは、デジタル入出力I/Oモジュール(PCI-2726C)より、デジタル信号を出力しCHK-2101のLEDを発光させるプログラムの作成を行います。PCI-2726C以外では、対応するテストI/Oモジュールおよび接続用ケーブルの製品型式が異なる場合がありますのでご注意ください。

ここで記載するソースコードは、以下の製品型式において利用可能です。 デジタル出力 デジタル入出力 PCI-2330CV PCI-2402C PCI-2403A PCI-2424 PCI-2426C PCI-2427 PCI-2427A PCI-2430C PCI-2431 PCI-2431A PCI-2464C PCI-2466C PCI-2470 PCI-2503 PCI-2512C PCI-2513

CTP-2330V CTP-2402 CTP-2424 CTP-2430 CTP-2431 CTP-2464 CTP-2466 CTP-2505 CTP-2506 CTP-2515 CTP-2516 CTP-2517 CPZ-2330V CPZ-2402 CPZ-2424 CPZ-2430 CPZ-2431 CPZ-2464 CPZ-2466 CPZ-2505 CPZ-2506 CPZ-2515 CPZ-2516 CPZ-2517 LPC-234104 PEX-234104

PCI-2702C PCI-2703 PCI-2703A PCI-2722 PCI-2723C PCI-2724C PCI-2724CL PCI-2724CM PCI-2725 PCI-2725A PCI-2725AL PCI-2725AM PCI-2725L PCI-2725M PCI-2726C PCI-2726CL PCI-2726CM PCI-2727 PCI-2727A PCI-2727AL PCI-2727AM PCI-2727L PCI-2727M PCI-2752C PCI-2753 PCI-2756A PCI-2756AL PCI-2756AM PCI-2758A

PCI-2758AL PCI-2758AM PCI-2760C PCI-2762C PCI-2762CM PCI-2768C PCI-2790C PCI-2793 PCI-2796C PCI-2798C PCI-2826C PCI-2826CV PCI-2994C PCI-2994CV PCI-287144 PCI-287244 PCI-292388

CTP-2702 CTP-2703 CTP-2722 CTP-2723 CTP-2724 CTP-2724L CTP-2724M CTP-2725 CTP-2725L CTP-2725M CTP-2726 CTP-2726L CTP-2726M CTP-2727 CTP-2727L CTP-2727M CTP-2752 CTP-2753 CTP-2760 CTP-2762 CTP-2762M CTP-2768 CTP-2769 CTP-2790 CTP-2798 CTP-2799 CTP-2826 CTP-2826V CTP-2827V CTP-2994 CTP-2994V CTP-2995V CTP-286122 CTP-287144 CTP-287244 CTP-292388 CTP-294188

CPZ-2702 CPZ-2703 CPZ-2723 CPZ-2724 CPZ-2724L CPZ-2724M CPZ-2726 CPZ-2726L CPZ-2726M CPZ-2727L CPZ-2752 CPZ-2760 CPZ-2762 CPZ-2762M CPZ-2768 CPZ-2769 CPZ-2790 CPZ-2798 CPZ-2799 CPZ-2826 CPZ-2826V CPZ-2827V CPZ-2994 CPZ-2994V CPZ-2995V CPZ-286122 CPZ-287144 CPZ-287244 CPZ-292388 CPZ-294188

CSI-292366 CSI-293166 LPC-284122 LPC-285122 LPC-292366 LPC-293166 PEX-284122 PEX-285122 PEX-292366 PEX-293166

注意!

テストI/Oモジュールのない型式もあります。詳細は弊社Web site(www.interface.co.jp)にて確

認してください。

製品型式によって、出力点数が異なりますので、ご使用になる製品型式により一部実行でき

ない処理が含まれます。

Page 34: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

Interface Corporation - 32 -

弊社テストI/Oモジュールがご用意できない場合は、各製品仕様に応じ、以下の配線を行ってください。各配線には弊社、端子台などをご利用ください。 PCI-○○○○LやPCI-○○○○MやPCI-○○○○Vなどの最後に“L”や“M”や“V”がある型式は、“L”や“M”や“V”がない場合の型式と同じ配線を行ってください。また同様に“TK”や“TL”がある型式も“TK”や“TL”がない場合の型式と同じ配線を行ってください。

配線1 配線2 配線3 配線4 配線5

PCI-2330CV PCI-2402C PCI-2403A PCI-2424 PCI-2426C PCI-2427 PCI-2427A PCI-2464C PCI-2466C PCI-2702C PCI-2703 PCI-2703A PCI-2722 PCI-2723C PCI-2724C PCI-2725 PCI-2725A PCI-2752C PCI-2753 PCI-2760C PCI-2768C PCI-2790C PCI-2793 PCI-2796C PCI-2798C PCI-2826C PCI-292388 PCI-2994C CTP-2330V CTP-2402 CTP-2424 CTP-2464 CTP-2466 CTP-2702 CTP-2703 CTP-2722 CTP-2723 CTP-2724 CTP-2727 CTP-2752 CTP-2753 CTP-2760 CTP-2768 CTP-2769 CTP-2790

CTP-2798 CTP-2799 CTP-2826 CTP-2827 CTP-292388 CTP-294188 CTP-2994 CTP-2995 CTP-2330V CTP-2402 CTP-2464 CTP-2466 CTP-2702 CTP-2703 CTP-2723 CTP-2724 CPZ-2727L CPZ-2752 CPZ-2760 CPZ-2768 CPZ-2769 CPZ-2790 CPZ-2798 CPZ-2799 CPZ-2826 CPZ-2827V CPZ-292388 CPZ-294188 CPZ-2994 CPZ-2995V CSI-292366 CSI-293166 PEX-234104 PEX-284122 PEX-292366 PEX-293166 LPC-234104 LPC-284122 LPC-292366 LPC-293166

PCI-2430C PCI-2431 PCI-2431A PCI-2726C PCI-2727 PCI-2727A PCI-2756A PCI-2758A(トランジスタ出力部)PCI-2762C CTP-2430 CTP-2431 CTP-2725 CTP-2726 CTP-2762 CPZ-2430 CPZ-2726 CPZ-2762 LPC-285122 PEX-285122

PCI-2470 PCI-287144PCI-287244CTP-287144CTP-278244CPZ-287144CPZ-287244

PCI-2503 CTP-2505 CPZ-2505

PCI-2512C PCI-2513 PCI-2758A(リレー出力部)CTP-2506 CTP-2515 CTP-2516 CTP-2517 CPZ-2506 CPZ-2515 CPZ-2516 CPZ-2517 CPZ-286122 PEX-251100 PEX-251101 LPC-251100 LPC-251101

Page 35: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

- 33 - Interface Corporation

配線1

OUT1 OUT2 OUT3

発光ダイオード

抵抗

+極

-極

-COM*

• • • •

デジタル出力配線1

抵抗は、デジタル出力I/Oモジュールの出力仕様と、発光させるLEDの許容範囲を考慮し適切なものを使用してください。(PCI-2427A/2403Aの場合、-COM3, -COM4も電源の-極に接続してください) 使用できる外部電源電圧は、各製品によって異なり、下表のように分類されます。

DC+5V DC+5V~DC+48V DC+5V~DC+24V DC+12V~DC+24V DC+12V~DC+48V PCI-2402C PCI-2403A PCI-2702C PCI-2703 PCI-2703A PCI-2752C PCI-2753 PCI-2793 PCI-2796C PCI-292388 CTP-2402 CTP-2702 CTP-2703 CTP-2752 CTP-2753 CTP-292388 CPZ-2402 CPZ-2702 CPZ-2703 CPZ-2752 CPZ-292388 CSI-292366 PEX-292366 LPC-292366

PCI-2330CV PCI-2760C PCI-2768C PCI-2790C PCI-2798C PCI-2826C PCI-2826CV PCI-2994CV CTP-2330V CTP-2760 CTP-2768 CTP-2769 CTP-2790 CTP-2798 CTP-2799 CTP-2826 CTP-2826V CTP-2827V CTP-2994V CTP-2995V CTP-294188 CPZ-2330V CPZ-2464 CPZ-2466 CPZ-2760 CPZ-2768 CPZ-2769 CPZ-2790 CPZ-2798 CPZ-2799 CPZ-2826 CPZ-2826V CPZ-2827V CPZ-294188 CPZ-2994 CPZ-2994V CPZ-2995V

PCI-2426C PCI-2427 PCI-2427A PCI-2723C PCI-2724C PCI-2725 PCI-2725A PCI-2724CL PCI-2724CM PCI-2725L PCI-2725M PCI-2725AL PCI-2725AM CTP-2724 CTP-2724L CTP-2724M CTP-2727 CTP-2727L CTP-2727M CPZ-2723 CPZ-2724 CPZ-2724L CPZ-2724M CPZ-2727L CSI-293166 PEX-234104 PEX-284122 PEX-293166 LPC-234104 LPC-284122 LPC-293166

PCI-2424 PCI-2722 CTP-2424 CTP-2722 CTP-2723

PCI-2464C PCI-2466C PCI-2994C CTP-2464 CTP-2466 CTP-2994

Page 36: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

Interface Corporation - 34 -

配線2

OUT1 OUT2 OUT3

発光ダイオード

抵抗

+極

-極

-COM*

• • • •

+COM*

デジタル出力配線2

抵抗は、デジタル出力I/Oモジュールの出力仕様と、発光させるLEDの許容範囲を考慮し適切なものを使用してください。 使用できる外部電源電圧は、各製品によって異なり、下表のように分類されます。

DC+5V~DC+24V DC+12V~DC+24V CTP-2431 PCI-2430C CTP-2725 PCI-2431 CTP-2725L PCI-2431A CTP-2725M PCI-2726C CTP-2726 PCI-2726CL CTP-2726L PCI-2726CM CTP-2726M PCI-2727 CPZ-2430 PCI-2727L CPZ-2726 PCI-2727M CPZ-2726L PCI-2727A CPZ-2726M PCI-2727AL CPZ-2762 PCI-2727AM CPZ-2762M PCI-2756A PEX-285122 PCI-2756AL LPC-285122 PCI-2756AM PCI-2758A(トランジスタ出力部) PCI-2758AL(トランジスタ出力部) PCI-2758AM(トランジスタ出力部) PCI-2762C PCI-2762CM CTP-2430 CTP-2762 CTP-2762M

Page 37: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

- 35 - Interface Corporation

配線3

OUT1 OUT2 OUT3 OUT4

発光ダイオード

抵抗+極

-極

-COM*

• • • •

+COM*

デジタル出力配線3

抵抗は、デジタル出力I/Oモジュールの出力仕様と、発光させるLEDの許容範囲を考慮し適切なものを使用してください。 使用できる外部電源電圧は、各製品によって異なり、下表のように分類されます。

DC+5V~DC+24V DC+12V~DC+24V PCI-2470 PCI-287144 PCI-287244 CTP-287144 CTP-287244 CPZ-287144 CPZ-287244

配線4

OUT1OUT2

OUT1OUT2

デジタル出力配線4

OUT1BB~OUT8BB,OUT1BC~OUT8BCは使用しません。 抵抗は、発光させるLEDの許容範囲を考慮し適切なものを使用してください。 使用できる外部電源電圧は、各製品によって異なり、下表のように分類されます。

DC+5V~DC+24V PCI-2503 CTP-2505 CPZ-2505

Page 38: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

Interface Corporation - 36 -

配線5

OUT1OUT2

OUT1 OUT2

デジタル出力配線5 抵抗は、発光させるLEDの許容範囲を考慮し適切なものを使用してください。 使用できる外部電源電圧は、各製品によって異なり、下表のように分類されます。

DC+5V~DC+24V PCI-2512C PCI-2758A PCI-2758AL PCI-2758AM PCI-2513 CTP-2506

CTP-2515 CTP-2516 CTP-2517 CPZ-2506 CPZ-2515 CPZ-2516

CPZ-2517 CPZ-286122 PEX-251100 PEX-251101 LPC-251100 LPC-251101

抵抗値の求め方 例)順方向電圧2Vの発光ダイオードを外部電源DC+12Vを用いて、10mAの電流を流して点灯させる 場合

( ) W1.0mA10V2V12

k1mA10

V2V12

=×−=

Ω=−=

消費電力

抵抗値

2倍以上の定格電力の抵抗を使うことを推奨いたします。使用する抵抗は「1kΩ-1/4W以上」となります。

Page 39: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

- 37 - Interface Corporation

■Step 1.デジタル出力処理の作成

デジタル出力を行うリアルタイムタスクを作成します。 初期化処理と終了処理は先ほどのデジタル入力リアルタイムモジュールと同じです。リアルタイ

ムタスクの中でデジタル出力を行っています。 では、プログラムを作成していきます。 デジタル入力リアルタイムモジュールの例List 『inputtask.c2』と異なる点を網掛けしています。

outputtask.c

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57

#include <rtl.h> #include <rtl_sched.h> #include "fbidio.h" #define DIO_DEVICENO 1 void* output_task(void *arg); pthread_t outthread; void* output_task(void *arg) { int nRet; struct sched_param p; int nBufferPattern0[8] = {0,1,0,1,0,1,0,1}; int nBufferPattern1[8] = {1,0,1,0,1,0,1,0}; int fPattern = 0; p.sched_priority = 1; pthread_setschedparam(pthread_self(), SCHED_FIFO, &p); pthread_make_periodic_np(pthread_self(), gethrtime(),500000000); while(1){ pthread_wait_np(); if(fPattern == 0){ nRet = DioOutputPoint(DIO_DEVICENO, &nBufferPattern0[0], 1, 8); fPattern = 1; }else{ nRet = DioOutputPoint(DIO_DEVICENO, &nBufferPattern1[0], 1, 8); fPattern = 0; } if(nRet){ rtl_printf("Output error[DeviceNo%d]:Return value=0x%x¥n", DIO_DEVICENO, nRet); } } return 0; } int init_module(void) { int nRet; EXPORT_NO_SYMBOLS; nRet = DioOpen(DIO_DEVICENO,0); if(nRet){ rtl_printf(" Open error[DeviceNo%d]:Return value=0x%x¥n", DIO_DEVICENO, nRet); return -1; } pthread_create(&outthread, NULL, (void*)output_task, 0); return 0;

Page 40: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

Interface Corporation - 38 -

58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73

} void cleanup_module(void) { int nRet; pthread_cancel(outthread); pthread_join(outthread, NULL); nRet = DioClose(DIO_DEVICENO); if(nRet){ rtl_printf(" Close error[DeviceNo%d]:Return value=0x%x¥n", DIO_DEVICENO, nRet); } }

コードの記述が終われば、outputtask.cというファイル名で保存してください。 では、プログラム内容を確認していきましょう。 周期的な処理を行うための基本は、デジタル入力リアルタイムモジュールの作成にある説明を確

認してください。 (Line 3) スレッドを取り扱うには、rtl_sched.hをインクルードします。 (Line 8) スレッドを作成した際に呼ばれるinput_task関数のプロトタイプ宣言です。 (Line 10) スレッドを使用するための変数を宣言します。この変数には、スレッドを作成する関数

pthread_create関数が成功した場合、作成されたスレッドを識別するためのIDが格納されます。スレッドに関するほとんどの関数は、このIDを使用して、対象のスレッドを指定します。 (Line 56) このpthread_create関数を呼ぶことでスレッドを作成します。pthread_create関数によってスレッドが作られれば、登録したoutput_task関数が並行して実行されます。 (Line 12~41) スレッドを作成した際に呼ばれるotuput_task関数です。 500msごとにデジタル出力を行うリアルタイムタスクの例です。 出力データを2種類用意し、交互に出力します。 (Line 64,65) モジュール取り外し時にスレッドを終了させます。pthread_cancel関数で、指定したスレッドに終了を要求し、pthread_join関数で指定したスレッドが終了するまで待ちます。 ★ウェイトについて デジタル入力,出力制御において、外部機器とのタイミング調整等のために短い停止時間を挿入したい場合はnanosleep関数を使用することで処理中に簡単にウェイトを挿入することができます。 ★nanosleep 指定された時間だけウェイトを入れる関数です。 第1引数に、ウェイトをかける時間を格納したtimespec構造体へのポインタ(hrt2ts関数でhrtime_t型をtimespec構造体へのポインタに変換しています)、第2引数にシグナルが配送された場合のウェイト残り時間を格納するtimespec構造体へのポインタを指定します。

Page 41: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

- 39 - Interface Corporation

3.4.2 コンパイル

コンパイルはgccにて行います。メイクファイルを作成して、コンパイルを行います。 エディタを開き、下記Listを記述してMakefileというファイル名で保存しましょう。

Makefile 2

1 2 3 4 5 6 7 8

include /usr/include/rtlinux/rtl.mk all: outputtask.o outputtask.o: outputtask.c $(CC) $(INCLUDE) $(CFLAGS) -o outputtask.o -c outputtask.c

メイクファイルの作成が終われば、実際にコンパイルを行います。 #make

コンパイルを行うことで、outputtask.oというファイルができます。 outputtask.oはデジタル出力を行うリアルタイムモジュールです。

3.4.3 動かしてみよう

それでは実行してみます。 まずは、リアルタイムモジュール、ドライバモジュールの組み込みを行った後(『14ページ 3.1 RTLinuxリアルタイムモジュール組み込み』『16ページ 3.2 RTLinux デジタル入出力ドライバ組み込み』参照)、outputtask.oを組み込みます。 #insmod outputtask.o

接続したCHK-2101で確認してください。 デジタル出力リアルタイムモジュールを組み込むと同時に、500msごとにOUT1からOUT8のLEDが点滅します。 確認が終わったらリアルタイムタスクモジュールを削除し、リアルタイムタスクを終了させます。 #rmmod outputtask

Page 42: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

Interface Corporation - 40 -

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

第3章までで、RTLinux上でのデジタル入出力I/Oモジュールの制御方法を紹介しました。ここでは、より高度な処理を行うプログラムを作成していきましょう。 より複雑なシステムを構築するために、LinuxアプリケーションとRTLinuxのリアルタイムタスクとを組み合わせて使用する方法を説明します。

Linuxアプリケーション リアルタイムタスク(モジュール)

Linuxアプリケーションとリアルタイムタスクとのデータの橋渡しを行います!

リアルタイムFIFO

リアルタイムFIFO

ここでは、LinuxアプリケーションとRTLinuxリアルタイムタスクとのやり取りを行うために使用するリアルタイムFIFOの使用方法を知りましょう。 デジタル入出力I/Oモジュール(PCI-2726C)より、デジタル信号を一定間隔で入力して、アプリケーションへデータを転送するプログラム,アプリケーションが指定した周期,出力データのパターンに従って、デジタル信号を出力するプログラムの作成を行います。PCI-2726C以外では、対応するテストI/Oモジュールおよび接続用ケーブルの製品型式が異なる場合がありますのでご注意ください。

4.1 リアルタイムFIFOを使用したデジタル入力

4.1.1 プログラム概要

Linuxアプリケーションが、デジタル入力リアルタイムタスクに、デジタル入力周期実行の開始命令を出します。その指令を受けたリアルタイムタスクは、命令に従ってデジタル入力の周期実行

を開始します。 リアルタイムタスク中で取得したデジタル入力データをRT-FIFOを使用して、Linuxアプリケーションが受け取り、画面に表示します。 入力が100回行われた時点で周期実行は停止します。

デジタル入出力リアルタイムモジュール

PCI-2726C

入力指令&入力データ表示用Linux アプリケーション

デジタル入力リアルタイムタスク

周期的にデジタル入力

RT-FIFO1

外部機器

周期実行開始

入力データ

RT-FIFO2

Linuxアプリケーション・リアルタイムタスク・リアルタイムFIFOの関係1

Page 43: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

- 41 - Interface Corporation

4.1.2 処理の流れ

プログラムの処理の流れを示します。

(1) 周期実行開始命令発行

(2) デジタル入力周期実行開始

(4) 入力データ画面表示

(5) 終了

デジタル入力 周期実行

(3) デジタル入力周期実行停止

100回 入力して終了

デジタル入力周期実行の処理の流れ (1)実行開始命令発行

Linuxアプリケーションから、デジタル出力用リアルタイムタスクに対して、デジタル入力周期実行開始命令を出します。

(2)デジタル入力周期実行開始 命令を受けたデジタル入力用リアルタイムタスクは、指定された周期でデジタル入力を行いま

す。このデジタル入力は、100回入力するまで続けられます。 入力したデータはリアルタイムFIFOへ送信します。アプリケーション側は、FIFOからデータを取得し、表示します。

(3)周期実行停止

100回のデジタル入力が完了するとデジタル入力リアルタイムタスクは、停止します。

(4)終了 Linuxアプリケーションプログラムを終了させます。

Page 44: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

Interface Corporation - 42 -

4.1.3 プログラミング

ここでは、既にRTLinuxの5つのリアルタイムモジュールとGPG-2000の3つのドライバモジュールが組み込まれているものとします。(『14ページ 3.1 RTLinuxリアルタイムモジュール組み込み』『16ページ 3.2 RTLinux デジタル入出力ドライバ組み込み』参照してください。)

Step 1. 共通定義ファイルの作成

まず、リアルタイムタスクに渡すコマンドや、リアルタイムFIFOに入れるデータ等、プログラム間で共通に使用するものを定義するために、共通定義ファイルを作成します。

ps_control.h 1

1 2 3 4 5 6 7 8 9

#define START_INPUT_COMMAND 1 typedef struct dio_msg_struct { int command; int period; }DIO_MSG_STRUCT;

コードの記述が終われば、ps_control.hというファイル名で保存しておきます。それでは、各定義が何に利用されるかを確認しましょう。 (Line 2) START_INPUT_COMMANDは、Linuxアプリケーションが、デジタル入力リアルタイムタスクに周期実行を開始するように指示するコマンドを表します。 (Line 4~8) リアルタイムFIFOに渡す構造体です。commandは、先ほどLine 2で定義した実行開始のようなコマンドの値を格納するためのメンバで、periodは、デジタル入力を行う周期をμs単位で設定します。

Page 45: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

- 43 - Interface Corporation

Step 2. デジタル入力処理の作成

それではデジタル入力を行うリアルタイムタスクを作成します。流れは下記のようになります。 (1)init_module関数でスレッド、ふたつのリアルタイムFIFO(FIFO1,FIFO2)を作成します。また、デジタル入出力I/Oモジュールの初期化を行い、LinuxアプリケーションからリアルタイムFIFO1(コマンドと周期設定値を取得するためのFIFO)に指令が出たときに呼ばれる関数を登録します。

(2)作成したスレッドの中で、Linuxアプリケーションで指定された周期でデジタル入力を行います。 (3)cleanup_module関数でスレッド,リアルタイムFIFO1/FIFO2の削除,デジタル入出力I/Oモジュールの終了処理を行います。

では、流れに沿ってプログラムを作成していきます。 デジタル入力リアルタイムタスクのプログラム例List『inputtask.c2』と異なる箇所を網掛けしています。

inputtask.c 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46

#include <rtl.h> #include <rtl_sched.h> #include <rtl_fifo.h> #include "fbidio.h" #include "ps_control.h" #define DIO_DEVICENO 1 #define DIO_DATA_FIFO_SIZE 1024 void* input_task(void *arg); int rtf_handler(unsigned int fifo); pthread_t inputthread; unsigned long ulLoopCount; void* input_task(void *arg) { int nRet; int nBuffer[8]; while(1){ pthread_wait_np(); nRet = DioInputPoint(DIO_DEVICENO, &nBuffer[0], 1, 8); if(nRet){ rtl_printf("Input error[DeviceNo%d]:Return value=0x%x¥n", DIO_DEVICENO, nRet); }else{ rtf_put(2,nBuffer,sizeof(nBuffer)); } ulLoopCount++; if(ulLoopCount >= 100){ pthread_suspend_np(pthread_self()); } } return 0; } int rtf_handler(unsigned int fifo) { DIO_MSG_STRUCT msg; struct sched_param p; if((rtf_get(1, &msg, sizeof(DIO_MSG_STRUCT)))

Page 46: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

Interface Corporation - 44 -

47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104

== sizeof(DIO_MSG_STRUCT)){ switch(msg.command) { case START_INPUT_COMMAND: ulLoopCount = 0; p.sched_priority = 1; pthread_setschedparam(inputthread, SCHED_FIFO, &p); pthread_make_periodic_np(inputthread, gethrtime(), 1000 * msg.period); break; } } return 0; } int init_module(void) { int nRet; EXPORT_NO_SYMBOLS; rtf_destroy(1); rtf_create(1, sizeof(DIO_MSG_STRUCT)); rtf_create_handler(1, rtf_handler); rtf_destroy(2); rtf_create(2, DIO_DATA_FIFO_SIZE); nRet = DioOpen(DIO_DEVICENO,0); if(nRet){ rtl_printf("Device open error[DeviceNo%d]:Return value=0x%x¥n", DIO_DEVICENO, nRet); return -1; } pthread_create(&inputthread, NULL, input_task, 0); return 0; } void cleanup_module(void) { int nRet; rtf_destroy(1); rtf_destroy(2); pthread_cancel(inputthread); pthread_join(inputthread, NULL); nRet = DioClose(DIO_DEVICENO); if(nRet){ rtl_printf(" Close error[DeviceNo%d]:Return value=0x%x¥n", DIO_DEVICENO, nRet); } }

コードの記述が終われば、finputtask.cというファイル名で保存しておきましょう。

Page 47: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

- 45 - Interface Corporation

それでは、プログラム内容を読み取っていきます。 (Line 6) アプリケーションとリアルタイムタスク間で使用するコマンド等を定義したps_control.hをインクルードします。 (Line 70~75) リアルタイムFIFOを作成しています。rtf_destroy関数で、一旦リアルタイムFIFOを削除しておいてから、新たにリアルタイムFIFOを作成します。

(Line 72) Linuxアプリケーションが、リアルタイムFIFOにアクセスした際に呼び出される関数を登録します。 ★rtf_create_handler この関数では、ユーザ空間でリアルタイムFIFOがアクセスした際に呼ばれる関数を登録します。第1引数には、リアルタイムFIFO作成時に指定したIDを、第2引数には、ユーザ空間で指定したリアルタイムFIFOがアクセスされた場合に呼ばれる関数を指定します。 この関数は、ユーザ空間からリアルタイムFIFOにアクセスされた場合に呼ばれる関数を登録しますが、リアルタイム空間からアクセスされた(rtf_put, rtf_get関数を使用した)場合に呼ばれる関数を登録するには、rtf_create_rt_handler関数を使用します。

(Line 84) デジタル入力の周期実行を行うスレッドを作成します。 (Line 23) スレッドを一旦眠らせます。Linuxアプリケーションが、リアルタイムFIFO1に命令を出したら、スレッドが起きるようにします。 (Line 41~62) Linuxアプリケーションが、命令を出した場合(リアルタイムFIFO1に書き込みを行った場合)この関数が呼ばれます。Line 72で登録した関数です。 (Line 46~59) Linuxアプリケーションが出した命令を取得し、それを判別します。 (Line 47~51) Linuxアプリケーションから出された命令が、START_INPUT_COMMAND(デジタル入力の周期実行開始命令)の場合、Linuxアプリケーションで指定した周期(μs単位)で、デジタル信号入力の周期実行を開始します。 (Line 34~36) デジタル入力処理が100回完了すると、スレッドを一時中断し、周期処理を停止させます。

Page 48: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

Interface Corporation - 46 -

Step 3. デジタル入力データ表示アプリケーション作成

次に、デジタル入力の周期実行を開始し、その後、取得されたデータを取得したデータをリアル

タイムFIFOから取り出し、画面に表示するLinuxプログラムを作成します。 inputdisp_app.c

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67

#include <stdio.h> #include <sys/time.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include "fbidio.h" #include "ps_control.h" int main(void) { int i,n; fd_set rfds; struct timeval tv; int nRet; int fd1,fd2; int nBuffer[8]; DIO_MSG_STRUCT msg; if((fd1 = open("/dev/rtf1", O_WRONLY)) < 0){ fprintf(stderr, "Error opening /dev/rtf1¥n"); return -1; } if((fd2 = open("/dev/rtf2", O_RDONLY)) < 0){ fprintf(stderr, "Error opening /dev/rtf2¥n"); return -1; } msg.command = START_INPUT_COMMAND; msg.period = 100 * 1000; if(write(fd1, &msg, sizeof(DIO_MSG_STRUCT)) < 0){ fprintf(stderr, "Can't send a commannd to RT-task¥n"); } while(1){ FD_ZERO(&rfds); FD_SET(fd2, &rfds); tv.tv_sec = 5; tv.tv_usec = 0; nRet = select(FD_SETSIZE, &rfds, NULL, NULL, &tv); if(nRet > 0){ if(FD_ISSET(fd2, &rfds)){ n = read(fd2, nBuffer, sizeof(nBuffer)); for(i=0;i<(n/sizeof(int));i++){ printf("%d ", nBuffer[i]); } printf("¥n"); } }else{ break; } } printf("finish.¥n"); close(fd1); close(fd2); return 0; }

Page 49: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

- 47 - Interface Corporation

コードの記述が終われば、inputdisp_app.cというファイル名で保存してください。 以上でプログラムの作成は終わりです。それでは、プログラム内容を見てみましょう。 (Line 22~30) リアルタイムFIFOをオープンします。オープンしたリアルタイムFIFOを識別するための一意の値(ファイルディスクリプタ)が戻り値として返され、fd1,fd2に格納されます。

★open 第1引数には、オープンするデバイス(リアルタイムFIFO)のパスを指定します。 アプリケーションが書き込みを行う(コマンドを発行する)リアルタイムFIFO1のopen関数では、第2引数に、書き込み用のフラグO_WRONLYを指定します。 アプリケーションが読み込みを行う(リアルタイムタスクからデータを受け取る)リアルタイムFIFO2のopen関数では、第2引数に、読み込み用のフラグO_RDONLYを指定します。 ★ディスクリプタ open関数の実行が成功すると、戻り値としてファイルディスクリプタが返されますが、この値は、現在使用されていないファイルディスクリプタのうち、負でない最小の値が返されます。

(Line 32~37) リアルタイムFIFO1へ、リアルタイムタスクを開始させるコマンドを書き込みます。 (Line 40,41) FD_ZEROで監視を行うファイルディスクリプタのクリアを行います。これにより、どのファイルやデバイスも監視を行わないことになります。それからFD_SETにより、fd2(先ほどオープンしたリアルタイムFIFO2)を監視するようにセットしています。 ★FD_ZERO,FD_SETマクロ ここで使用しているFD_ZEROマクロとFD_SETマクロは、select関数に関係のあるものです。Line.45に記述しているselect関数は、複数のファイルディスクリプタに変化があるまで待つことができる関数です。 最初にFD_ZEROマクロにより指定したファイルディスクリプタの集合(ここではrfds)をクリア(消去)し、次に、クリアしたファイルディスクリプタの集合(rfds)にリアルタイムFIFOのディスクリプタ(fd2)を設定することにより、select関数は、リアルタイムFIFOの変化を監視するようになります。

(Line 42,43) select関数でのタイムアウト時間を設定しています。ここでは5秒でタイムアウトが発生するようにしています。 ★タイムアウト select関数では、指定したファイルディスクリプタの変化を監視する時間を設定することができます。 select関数の第5引数として、タイムアウト時間に0を指定するとすぐに処理が抜け、NULLを指定すると、指定したファイルディスクリプタに変化があるまでずっと待ちます。

(Line 45) Line 40,41で、fd2(リアルタイムFIFO2)のみを監視するように設定し、タイムアウトを5秒に設定していますので、select関数を呼んでから、リアルタイムFIFO2に変化がある(デジタル入力データが書き込まれる)か、5秒が経過するかのどちらかになった場合のみLine 46行以降の処理に移ります。

Page 50: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

Interface Corporation - 48 -

★select select関数の第1引数には、監視するファイルディスクリプタの中の最大値に1を足した値を指定するか、使用できるファイルディスクリプタの最大値であるFD_SETSIZEを指定します。 ここでは、FD_SETSIZEを指定しています。 第2引数には、読み込み可能かどうかを監視するファイルディスクリプタの集合、第3引数には書き込み可能かどうかを監視するファイルディスクリプタの集合、第4引数には例外の監視を行うファイルディスクリプタの集合を指定します。ここでは、リアルタイムFIFOからデータを読み出すので、先ほどFD_ZEROマクロ,FD_SETマクロで設定したファイルディスクリプタの集合を第2引数に設定します。 第5引数には、select関数のタイムアウト時間を設定するtimeval構造体を指定します。ここをNULLに指定すると、タイムアウトが発生しなくなりますので、ご注意ください。

(Line 47~55) リアルタイムFIFO2にデジタル入力データが書き込まれた場合、リアルタイムFIFO2から値を取り出しています。 ★FD_ISSET FD_ISSETマクロは、第2引数で指定されるファイルディスクリプタの集合に、第1引数で指定されるファイルディスクリプタが存在するかをチェックします。FD_ISSETが真を返せば、集合の中に指定したファイルディスクリプタが存在することになります。 複数のファイルディスクリプタの状態を監視ている場合は、FD_ISSETマクロを使用して、どのファイルディスクリプタに変化があったかを判断します。 ★read read関数の第1引数には読み込みを行うファイルディスクリプタ、第2引数には読み込みデータを格納するバッファ、第3引数には読み込みを行うサイズを指定します。戻り値には,実際に読み込み、取得できたバイト数が返されます。

以上で、デジタル入力アプリケーションプログラムの作成は終了です。

Page 51: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

- 49 - Interface Corporation

4.1.4 コンパイル

コンパイルはgccにて行います。メイクファイルを作成して、コンパイルを行います。 エディタを開き、下記Listを記述してMakefileというファイル名で保存しましょう。

Makefile 3

1 2 3 4 5 6 7 8 9 10 11 12

include /usr/include/rtlinux/rtl.mk TARGETS= finputtask.o inputdisp_app all: $(TARGETS) inputdisp_app: inputdisp_app.c ps_control.h $(CC) $(INCLUDE) $(USER_CFLAGS) -O2 -Wall -o inputdisp_app inputdisp_app.c finputtask.o: finputtask.c ps_control.h $(CC) $(INCLUDE) $(CFLAGS) -o finputtask.o -c finputtask.c

メイクファイルの作成が終われば、実際にコンパイルを行います。 #make

コンパイルを行うことで、inputdisp_appとfinputtask.oというファイルができます。 finputtask.oはデジタル入力を行うリアルタイムモジュールです。 inputdisp_appは取得したデータを表示するアプリケーションです。

4.1.5 動かしてみよう

それでは実行してみます。 まずは、リアルタイムモジュール、ドライバモジュールの組み込みを行った後(『14ページ 3.1 RTLinuxリアルタイムモジュール組み込み』『16ページ 3.2 RTLinux デジタル入出力ドライバ組み込み』参照)、finputtask.oを組み込みます。

#insmod finputtask.o

アプリケーションinputdisp_appを実行します。 #./inputdisp_app

アプリケーションが起動すると、デジタル入力の周期実行開始をリアルタイムタスクモジュール

に送信し、デジタル入力処理が周期的に実行されます。 そしてリアルタイムFIFO2を介してアプリケーションに送られてくる入力データを表示します。

Page 52: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

Interface Corporation - 50 -

表示されるデータは、左からIN1,IN2,…,IN8と並んでいます。 #0 0 1 0 0 1 0 0 #0 0 1 0 0 1 0 0 #0 0 1 0 0 1 0 0 #0 1 0 0 0 1 0 0 #0 1 0 0 0 1 0 0 #…

100回入力が完了すると終わります。 アプリケーションは、リアルタイムタスクが停止してから5秒後に終了します。 確認が終わったらリアルタイムタスクモジュールを削除し、リアルタイムタスクを終了させます。 #rmmod finputtask

Page 53: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

- 51 - Interface Corporation

4.2 リアルタイムFIFOを使用したデジタル出力

4.2.1 プログラム概要

Linuxアプリケーションが、デジタル出力リアルタイムタスクに、出力の周期実行の開始、および停止命令を出します。その指令を受けたリアルタイムタスクは、命令に従ってデジタル出力の周

期実行の開始と停止を行います。 また、RT-FIFOから出力開始、停止等の状態を取得し、Linuxアプリケーションが画面に表示します。

周期実行開始

周期実行停止

出力データ

デジタル入出力リアルタイムモジュール

PCI-2726C

指令&出力状態表示用Linuxアプリケーション

デジタル出力用リアルタイムタスク

周期的にデジタル出力

RT-FIFO1

外部機器

状態

RT-FIFO2

Linuxアプリケーション・リアルタイムタスク・リアルタイムFIFOの関係2

4.2.2 処理の流れ

(1)周期実行開始命令発行 Linuxアプリケーションから、デジタル出力用リアルタイムタスクに対して、デジタル出力周期実行開始命令を出します。また、それと同時に出力周期、出力データも指定します。

(2)デジタル出力周期実行開始 命令を受けたデジタル出力用リアルタイムタスクは、指定された周期でデジタル出力を行いま

す。このデジタル出力は、停止命令が出るまで続けられます。 (3)周期デジタル出力停止命令発行 リターンキーが押されたら、周期実行停止命令を出します。

(4)周期実行停止 命令を受けたデジタル出力用リアルタイムタスクは、停止します。

(5)終了 Linuxアプリケーションプログラムを終了させます。

Page 54: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

Interface Corporation - 52 -

(1) 周期実行開始命令発行

(2) デジタル出力周期実行開始

(4) デジタル出力周期実行停止

(5) 終了

デジタル出力周期実行

(3)周期処理 停止命令発行

デジタル入出力周期実行の処理の流れ

4.2.3 プログラミング

ここでは、既にRTLinuxの5つのリアルタイムモジュールとGPG-2000の3つのドライバモジュールが組み込まれているものとします。(『14ページ 3.1 RTLinuxリアルタイムモジュール組み込み』『16ページ 3.2 RTLinux デジタル入出力ドライバ組み込み』参照)

■Step 1. 基本定義ファイルの作成

まず、リアルタイムタスクに渡すコマンドや、リアルタイムFIFOに入れるデータ等、プログラム間で共通に使用するものを定義するために、共通定義ファイルを作成します。リアルタイムFIFOを使用したデジタル入力例で使用した共通定義ファイルList 『ps_contrlo.h 1』と異なる箇所を網掛けしています。

ps_control.h 2

1 2 3 4 5 6 7 8 9 10 11 12 13

#define START_INPUT_COMMAND 1 #define START_OUTPUT_COMMAND 2 #define STOP_OUTPUT_COMMAND 3 #define DIO_PATTERN_DATA_NUM 16 typedef struct dio_msg_struct{ int command; int period; int outpattern[DIO_PATTERN_DATA_NUM]; }DIO_MSG_STRUCT;

コードの記述が終われば、ps_control.hというファイル名で保存しておきます。それでは、各定義が何に利用されるかを確認しましょう。

Page 55: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

- 53 - Interface Corporation

(Line 2,3) START_OUTPUT_COMMANDは、Linuxアプリケーションが、デジタル出力用リアルタイムタスクに周期実行を開始するように指示するコマンドを表します。 STOP_OUTPUT_COMMANDは、Linuxアプリケーションが、デジタル出力用リアルタイムタスクに停止を指示するコマンドを表します。 (Line 8~12) リアルタイムFIFOに渡す構造体です。commandは、Line 2~Line 4で定義した実行開始、停止等のコマンドを格納するためのメンバで、periodは、デジタル出力を行う周期をμs単位で設定します。 outpatternは、出力するデータをリアルタイムタスクへ受け渡すために使用します。出力のパターンをアプリケーションで任意に変更できるようになります。

■Step 2. デジタル出力処理の作成

それではデジタル出力を行うリアルタイムタスクを作成します。 流れは下記のようになります。 (1)init_module関数でスレッド,二つのリアルタイムFIFO(FIFO1,FIFO2)を作成します。また、デジタル入出力I/Oモジュールの初期化を行い、LinuxアプリケーションからリアルタイムFIFO1(コマンドと周期設定値を取得するためのFIFO)に指令が出たときに呼ばれる関数を登録します。

(2)作成したスレッドの中で、Linuxアプリケーションで指定された周期でデジタル出力を行います。 (3)cleanup_module関数でスレッド,リアルタイムFIFO1/FIFO2の削除,デジタル入出力I/Oモジュールの終了処理を行います。

Page 56: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

Interface Corporation - 54 -

では、流れに沿ってプログラムを作成していきます。 リアルタイムFIFOを使用したデジタル入力プログラム例下記Listと異なる箇所に網掛けしています。

foutputtask.c

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66

#include <rtl.h> #include <rtl_sched.h> #include <rtl_fifo.h> #include "fbidio.h" #include "ps_control.h" #define DIO_DEVICENO 1 #define DIO_DATA_FIFO_SIZE 1024 void* output_task(void *arg); int rtf_handler(unsigned int fifo); pthread_t outputthread; int nBufferPattern[DIO_PATTERN_DATA_NUM]; unsigned long ulLoopCount; void* output_task(void *arg) { int nRet; char szBuffer[32]; while(1){ pthread_wait_np(); nRet = DioOutputPoint(DIO_DEVICENO, &nBufferPattern[ulLoopCount % DIO_PATTERN_DATA_NUM], 1, 1); if(nRet){ rtl_printf("Output error[DeviceNo%d]:ret=0x%x¥n", DIO_DEVICENO, nRet); }else{ ulLoopCount++; if(!(ulLoopCount % 10)){ sprintf(szBuffer,"Output loop count: %ld",ulLoopCount); rtf_put(2,szBuffer,strlen(szBuffer)); } } } return 0; } int rtf_handler(unsigned int fifo) { DIO_MSG_STRUCT msg; struct sched_param p; char szBuffer[80]; if((rtf_get(1, &msg, sizeof(DIO_MSG_STRUCT))) == sizeof(DIO_MSG_STRUCT)) { switch(msg.command) { case START_OUTPUT_COMMAND: ulLoopCount = 0; sprintf(szBuffer,"Start output."); rtf_put(2,szBuffer,strlen(szBuffer)); memcpy(nBufferPattern, msg.outpattern, sizeof(nBufferPattern)); p.sched_priority = 1; pthread_setschedparam(outputthread, SCHED_FIFO, &p); pthread_make_periodic_np(outputthread, gethrtime(), 1000 * msg.period); break;

Page 57: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

- 55 - Interface Corporation

67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120

case STOP_OUTPUT_COMMAND: sprintf(szBuffer,"Stop output."); rtf_put(2,szBuffer,strlen(szBuffer)); pthread_suspend_np(outputthread); break; } } return 0; } int init_module(void) { int nRet; EXPORT_NO_SYMBOLS; rtf_destroy(1); rtf_create(1, sizeof(DIO_MSG_STRUCT)); rtf_create_handler(1, &rtf_handler); rtf_destroy(2); rtf_create(2,DIO_DATA_FIFO_SIZE); nRet = DioOpen(DIO_DEVICENO,0); if(nRet){ rtl_printf("Device open error[DeviceNo%d]:Return value=0x%x¥n", DIO_DEVICENO, nRet); return -1; } pthread_create(&outputthread, NULL, output_task, 0); return 0; } void cleanup_module(void) { int nRet; rtf_destroy(1); rtf_destroy(2); pthread_cancel(outputthread); pthread_join(outputthread, NULL); nRet = DioClose(DIO_DEVICENO); if(nRet){ rtl_printf(" Close error[DeviceNo%d]:Return value=0x%x¥n", DIO_DEVICENO, nRet); } }

コードの記述が終われば、foutputtask.cというファイル名で保存しておきましょう。 それでは、プログラム内容を読み取っていきます。

Page 58: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

Interface Corporation - 56 -

(Line 6) アプリケーションとリアルタイムタスク間で使用するコマンド等を定義したps_control.hをインクルードします。 (Line 86~91) リアルタイムFIFOを作成しています。rtf_destroy関数で、一旦リアルタイムFIFOを削除しておいてから、新たにリアルタイムFIFOを作成します。 (Line 88) Linuxアプリケーションが、リアルタイムFIFOにアクセスした際に呼び出される関数を登録します。 (Line 100) デジタル出力の周期実行を行うスレッドを作成します。 (Line 43~78) Linuxアプリケーションが、命令を出した場合(リアルタイムFIFO1に書き込みを行った場合)この関数が呼ばれます。Line 88で登録した関数です。 (Line 49~75) Linuxアプリケーションが出した命令を取得し、それを判別します。 (Line 52~66) Linuxアプリケーションから出された命令が、START_OUTPUT_COMMAND(デジタル出力の周期実行開始命令)の場合、Linuxアプリケーションで指定した周期(μs単位)で、デジタル出力の周期実行を開始します。 (Line 68~73) Linuxアプリケーションから出された命令が、STOP_OUTPUT_COMMAND(デジタル出力の周期実行停止命令)の場合、スレッドを一時中断し、周期実行を停止させます。

Page 59: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

- 57 - Interface Corporation

■Step 3. 出力開始,状態表示アプリケーション作成

次に、デジタル出力周期処理の開始,停止のコマンド発行,処理出力状態をリアルタイムFIFOから取り出し、画面に表示するLinuxプログラムを作成します。

outputdisp_app.c 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62

#include <stdio.h> #include <sys/time.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include "fbidio.h" #include "ps_control.h" #define MAX_MESSAGE_LENGTH 80 int kbhit(void); int main(void) { fd_set rfds; int nRet; struct timeval tv; int fd1,fd2; char szStatusMsg[MAX_MESSAGE_LENGTH]; DIO_MSG_STRUCT msg; int nPatternData[DIO_PATTERN_DATA_NUM] = {0,1, 0,1, 0,1, 0,1, 0,1, 0,1, 0,1, 0,1}; if((fd1 = open("/dev/rtf1", O_WRONLY)) < 0){ fprintf(stderr, "Error opening /dev/rtf1¥n"); return -1; } if((fd2 = open("/dev/rtf2", O_RDONLY)) < 0){ fprintf(stderr, "Error opening /dev/rtf2¥n"); return -1; } msg.command = START_OUTPUT_COMMAND; msg.period = 500 * 1000; memcpy(msg.outpattern,nPatternData,sizeof(nPatternData)); if(write(fd1, &msg, sizeof(DIO_MSG_STRUCT)) < 0){ fprintf(stderr, "Can't send a commannd to RT-task¥n"); } while(!kbhit()){ FD_ZERO(&rfds); FD_SET(fd2, &rfds); tv.tv_sec = 1; tv.tv_usec = 0; nRet = select(FD_SETSIZE, &rfds, NULL, NULL, &tv); if (nRet > 0){ if (FD_ISSET(fd2, &rfds)){ nRet = read(fd2, szStatusMsg, MAX_MESSAGE_LENGTH - 1); szStatusMsg[nRet] = '¥0'; //set null terminate printf("Status message :%s¥n", szStatusMsg); } } } msg.command = STOP_OUTPUT_COMMAND;

Page 60: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

Interface Corporation - 58 -

63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106

if (write(fd1, &msg, sizeof(DIO_MSG_STRUCT))<0){ fprintf(stderr, "Can't send a commannd to RT-task¥n"); } FD_ZERO(&rfds); FD_SET(fd2, &rfds); tv.tv_sec = 5; tv.tv_usec = 0; nRet = select(FD_SETSIZE, &rfds, NULL, NULL, &tv); if(nRet > 0){ if(FD_ISSET(fd2, &rfds)){ nRet = read(fd2, szStatusMsg, MAX_MESSAGE_LENGTH-1); szStatusMsg[nRet] = '¥0'; //set null terminate printf("Status message:%s¥n", szStatusMsg); } } close(fd1); close(fd2); return 0; } int kbhit(void) { fd_set kbfds; struct timeval kbtv; int nRet; FD_ZERO(&kbfds); FD_SET(0, &kbfds); kbtv.tv_sec = 0; kbtv.tv_usec = 0; nRet = select(1, &kbfds, NULL, NULL, &kbtv); if(nRet > 0){ return 1; }else{ return 0; } }

コードの記述が終われば、outputdisp_app.cというファイル名で保存してください。 以上でプログラムの作成は終わりです。それでは、プログラム内容を見てみましょう。 (Line 26~34) リアルタイムFIFOをオープンします。オープンしたリアルタイムFIFOを識別するための一意の値(ファイルディスクリプタ)が戻り値として返され、fd1,fd2に格納されます。 (Line 36~43) リアルタイムFIFO1へ、リアルタイムタスクを開始させるコマンドと、出力データを書き込みます。 (Line 45) キーI/Oモジュールからの入力の有無を確認します。キーI/Oモジュールからの入力がなければ繰り返し処理を行います。 キーI/Oモジュールからの入力の有無を判断するサブルーチンはLine 88~105に記述しています。

Page 61: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

- 59 - Interface Corporation

(Line 46,47) FD_ZEROで監視を行うファイルディスクリプタのクリアを行います。これにより、どのファイルやデバイスも監視を行わないことになります。それからFD_SETにより、fd2(先ほどオープンしたリアルタイムFIFO2)を監視するようにセットしています。 (Line 48,49) select関数でのタイムアウト時間を設定しています。ここでは1秒でタイムアウトが発生するようにしています。 (Line 51) Line 46,47で、fd2(リアルタイムFIFO2)のみを監視するように設定し、タイムアウトを1秒に設定していますので、select関数を呼んでから、リアルタイムFIFO2に変化がある(出力状態に変化がある)か、1秒が経過するかのどちらかになった場合のみLine 52行以降の処理に移ります。 (Line 54~57) リアルタイムFIFO2に出力状態等のステータス情報が書き込まれた場合、リアルタイムFIFO2から値を取り出しています。 (Line 62~81) キーI/Oモジュールから入力があった場合、繰り返し処理を終了します。 繰り返し処理を抜けた後、リアルタイムFIFO1へ、リアルタイムタスクの終了コマンドを送信します。 また、コマンド送信後、リアルタイムFIFO2から状態情報が返されるのを待ちます。 以上で出力開始,状態表示アプリケーションプログラムの作成は終了です。

Page 62: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

Interface Corporation - 60 -

4.2.4 コンパイル

メイクファイルを作成して、コンパイルを行います。 エディタを開き、下記Listを入力してMakefileというファイル名で保存しましょう。

Makefile 4

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

include /usr/include/rtlinux/rtl.mk TARGETS= foutputtask.o outputdisp_app all: $(TARGETS) outputdisp_app: outputdisp_app.c ps_control.h $(CC) $(INCLUDE) $(USER_CFLAGS) -O2 -Wall -o outputdisp_app outputdisp_app.c foutputtask.o: foutputtask.c ps_control.h $(CC) $(INCLUDE) $(CFLAGS) -o foutputtask.o -c foutputtask.c clean: rm -f *.o ¥#* *~ $(TARGETS)

★メイクファイルのcleanについて メイクファイルのcleanセクションは、コンパイルには直接関係ありません。ここでは、不必要なバックアップファイルや、古くなったモジュールを削除するために、このようなセクションを用意しています。 #make clean と打ち込むと、メイクファイルが示すようにrmコマンドをモジュールファイルやバックアップファイルに対して実行したことになり、不必要なファイルを削除してくれます。 cleanという名前は任意です。

メイクファイルの作成が終われば、実際にコンパイルを行います。 #make

コンパイルを行うことで、outputdisp_appとfoutputtask.oというファイルができます。 foutputtask.oはデジタル出力を行うリアルタイムモジュールです。 outputdisp_appは出力状態の情報等を表示するアプリケーションです。

Page 63: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

- 61 - Interface Corporation

4.2.5 動かしてみよう

それでは実行してみます。 まずは、リアルタイムモジュール,ドライバモジュールの組み込みを行った後(『14ページ 3.1 RTLinuxリアルタイムモジュール組み込み』『16ページ 3.2 RTLinux デジタル入出力ドライバ組み込み』参照)、foutputtask.oを組み込みます。 #insmod foutputtask.o

アプリケーションoutputdisp_appを実行します。 #./outputdisp_app

アプリケーションが起動するとすぐに、デジタル出力の周期実行を行うため、コマンドが送られ

ます。 デジタル出力リアルタイムタスクが開始され、アプリケーションが指定した500ms周期でOUT1信号のON/OFFを繰り返し制御します。 リターンキーが押されると周期実行を停止するコマンドをリアルタイムタスクへ送り、アプリ

ケーションは終了します。 アプリケーションは、リアルタイムタスクから送信される状態情報を表示します。 スタート時/ストップ時、また、出力回数が10回に達するごとに情報を表示します。 #Status message: Start output. #Status message: Output loop count: 10 #Status message: Output loop count: 20 #Status message: Output loop count: 30 #… #Status message: Stop output.

確認が終わったらリアルタイムタスクモジュールを削除し、リアルタイムタスクを終了させます。 #rmmod foutputtask

Page 64: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

Interface Corporation - 62 -

4.3 割り込みイベントによる処理を行いたい!

デジタル入出力I/Oモジュールには、信号の変化等をハードウェア割り込みとして捉えることができる割り込み機能があります。 割り込みとは、何らかの条件により実行中のプログラムを中断し、他のプログラムに制御を移す

ことです。 ここでは、割り込み処理の方法に関し記載します。

実行中プログラム

割り込み発生

プログラム中断中

割り込み処理が終われば元のプログラムに制御を戻します。

割り込み処理プログラム

割り込み処理の概要図

CHK-2101の入力接点番号1(IN1)のスイッチより、入力(High Low)があった場合、それを割り込み信号として取得するプログラムの作成を行います。

4.3.1 プログラム概要

デジタル入出力リアルタイムモジュール

PCI-2726C

割り込みイベント要因表示用Linux アプリケーション

割り込みイベントコールバックルーチン

RT-FIFO1

割り込み要因など

外部機器信号入力割り込みイベント

Linuxアプリケーション・リアルタイムタスク・リアルタイムFIFOの関係3

Page 65: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

- 63 - Interface Corporation

4.3.2 処理の流れ

プログラムの処理の流れを示します。

(1)割り込みイベントコールバックルーチンの登録,要因マスク設定 割り込みイベントが発生した場合にコールされるコールバックルーチンを設定します。また、

どの割り込みイベント要因を検出するかのマスク設定を行います。

(2)割り込み検出 設定した割り込み要因で割り込みが発生するとコールバックルーチンが呼ばれます。

(3)アプリケーションへメッセージ送信 割り込みコールバックルーチンは、コールされると割り込み要因を、リアルタイムFIFOを使用してアプリケーションに通知します。

(4)割り込み要因画面表示 割り込み要因をリアルタイムモジュール内のコールバックルーチンで取得し、Linuxアプリケーションに返します。Linuxアプリケーション上で、割り込み要因を画面に表示します。

(5)終了 リターンキーが押されたらLinuxアプリケーションプログラムを終了させます。

Page 66: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

Interface Corporation - 64 -

4.3.3 プログラミング

ここでは、既にRTLinuxの5つのリアルタイムモジュールとGPG-2000の3つのドライバモジュールが組み込まれているものとします。(『14ページ 3.1 RTLinuxリアルタイムモジュール組み込み』『16ページ 3.2 RTLinux デジタル入出力ドライバ組み込み』参照)

■Step 1. 割り込みイベントコールバックの作成

流れは下記のようになります。 (1)init_module関数で、スレッド,リアルタイムFIFO1の作成,デジタル入出力I/Oモジュールの初期化を行い、LinuxアプリケーションからリアルタイムFIFO1に指令が出たときに呼ばれる関数を登録します。 また、コールバック関数の登録を行った後、割り込み要因設定、割り込みマスク設定を行いま

す。 コールバック関数内では、発生した割り込みの要因を、リアルタイムFIFOを使用してアプリケーションへ送信します。

(2)cleanup_module関数でスレッド,リアルタイムFIFO1の削除,デジタル入出力I/Oモジュールの終了処理を行います。

では、流れに沿ってプログラムを作成していきます。 eventtask.c

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35

#include <rtl.h> #include <rtl_fifo.h> #include "fbidio.h" #define DIO_DEVICENO 1 #define DIO_DATA_FIFO_SIZE 1024 void DioCallBackProc( unsigned long lUserData, unsigned char bEvent, unsigned short nDeviceNum); void DioCallBackProc( unsigned long lUserData, unsigned char bEvent, unsigned short nDeviceNum) { rtf_put(1, &bEvent,sizeof(unsigned char)); } int init_module(void) { int nRet; EXPORT_NO_SYMBOLS; rtf_destroy(1); rtf_create(1, DIO_DATA_FIFO_SIZE); nRet = DioOpen(DIO_DEVICENO,0); if(nRet){ rtl_printf("Device open error[DeviceNo%d]:Return value=0x%x¥n", DIO_DEVICENO,nRet); return -1; } nRet = DioRegistIsr(DIO_DEVICENO,0,DioCallBackProc); if(nRet){

Page 67: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

- 65 - Interface Corporation

36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90

rtl_printf("DioRegistIsr error[DeviceNo%d]:Return value=0x%x¥n", DIO_DEVICENO, nRet); DioClose(DIO_DEVICENO); return -1; } /* set irq config */ /* High --> Low */ /* IN1, IR.IN1, IR.IN2 */ nRet = DioSetIrqConfig(DIO_DEVICENO,0x0a); if(nRet){ rtl_printf( "DioSetIrqConfig error[DeviceNo%d]:Return value=0x%x¥n", DIO_DEVICENO, nRet); DioClose(DIO_DEVICENO); return –1; } /* Set IrqMask */ /* open mask SIGR, SIG4, SIG2, SIG1 */ nRet = DioSetIrqMask(DIO_DEVICENO,0x2b); if(nRet){ rtl_printf( "DioSetIrqMask error[DeviceNo%d]:Return value=0x%x¥n", DIO_DEVICENO, nRet); DioClose(DIO_DEVICENO); return -1; } return 0; } void cleanup_module(void) { int nRet; rtf_destroy(1); /* mask all */ nRet = DioSetIrqMask(DIO_DEVICENO,0x0); if(nRet){ rtl_printf("DioSetIrqMask error[DeviceNo%d]:Return value=0x%x¥n", DIO_DEVICENO, nRet); } nRet = DioClose(DIO_DEVICENO); if(nRet){ rtl_printf(" Close error[DeviceNo%d]:Return value=0x%x¥n", DIO_DEVICENO, nRet); } }

コードの記述が終われば、eventtask.cというファイル名で保存しておきましょう。それでは、プログラム内容を読み取っていきます。 (Line 12~16) 割り込みが発生した時にコールされる関数(コールバックルーチン)です。 発生した割り込み要因を、リアルタイムFIFOを使用してアプリケーションへ送信します。 (Line 34) 割り込みが発生した時にコールされる関数(コールバックルーチン)を登録します。 (Line 43~66) 割り込み要因設定と割り込みマスク設定を行います。

Page 68: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

Interface Corporation - 66 -

■Step 2. 割り込み要因表示アプリケーション作成

次に、リアルタイムFIFOから、割り込みが発生した時に保存された割り込み要因データを取り出し、画面に表示するLinuxプログラムを作成します。

eventdisp_app.c

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64

#include <stdio.h> #include <sys/time.h> #include <fcntl.h> #include <unistd.h> #include "fbidio.h" #define MAX_MESSAGE_LENGTH 80 int kbhit(void); int main(void) { fd_set rfds; struct timeval tv; int nRet; int fd1; unsigned char bEventData; if((fd1 = open("/dev/rtf1", O_RDONLY)) < 0){ fprintf(stderr, "Error opening /dev/rtf1¥n"); return -1; } while(!kbhit()){ FD_ZERO(&rfds); FD_SET(fd1, &rfds); tv.tv_sec = 1; tv.tv_usec = 0; nRet = select(FD_SETSIZE, &rfds, NULL, NULL, &tv); if(nRet > 0){ if(FD_ISSET(fd1, &rfds)){ read(fd1, &bEventData, sizeof(bEventData)); if(bEventData & 0x01){ printf("Signal : IN1¥n"); } if(bEventData & 0x02){ printf("Signal : IR.IN1¥n"); } if(bEventData & 0x08){ printf("Signal : IR.IN2¥n"); } if(bEventData & 0x20){ printf("Signal : RSTIN¥n"); } } } } close(fd1); return 0; } int kbhit(void) { fd_set kbfds; struct timeval kbtv; int nRet; FD_ZERO(&kbfds); FD_SET(0, &kbfds); kbtv.tv_sec = 0; kbtv.tv_usec = 0;

Page 69: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

- 67 - Interface Corporation

65 66 67 68 69 70 71 72 73

nRet = select(1, &kbfds, NULL, NULL, &kbtv); if(nRet > 0){ return 1; }else{ return 0; } }

コードの記述が終われば、eventdisp_app.cというファイル名で保存してください。 以上でプログラムの作成は終わりです。それでは、プログラム内容を見てみましょう。 (Line 20~23) リアルタイムFIFOをオープンします。オープンしたリアルタイムFIFOを識別するための一意の値(ファイルディスクリプタ)が戻り値として返され、fd1に格納されます。

(Line 25) キーI/Oモジュールからの入力の有無を確認します。キーI/Oモジュールからの入力がなければ繰り返し処理を行います。 キーI/Oモジュールからの入力の有無を判断するサブルーチンはLine 55~72に記述しています。 (Line 26,27) FD_ZEROで監視を行うファイルディスクリプタのクリアを行います。これにより、どのファイルやデバイスも監視を行わないことになります。それからFD_SETにより、fd1(先ほどオープンしたリアルタイムFIFO)を監視するようにセットしています。 (Line 28,29) select関数でのタイムアウト時間を設定しています。ここでは1秒でタイムアウトが発生するようにしています。 (Line 31) Line 26,27で、fd1(リアルタイムFIFO)のみを監視するように設定し、タイムアウトを1秒に設定していますので、select関数を呼んでから、リアルタイムFIFOに変化がある(割り込み要因データが書き込まれる)か、1秒が経過するかのどちらかになった場合のみLine 32行以降の処理に移ります。 (Line 34~47) リアルタイムFIFOに割り込み要因データが書き込まれた場合、リアルタイムFIFOから値を取り出しています。 以上で割り込み要因表示アプリケーションプログラムの作成は終了です。

Page 70: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

Interface Corporation - 68 -

4.3.4 コンパイル

メイクファイルを作成して、コンパイルを行います。 エディタを開き、下記Listを入力してMakefileというファイル名で保存しましょう。

Makefile 5

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

include /usr/include/rtlinux/rtl.mk TARGETS= eventtask.o eventdisp_app all: $(TARGETS) eventdisp_app: eventdisp_app.c $(CC) $(INCLUDE) $(USER_CFLAGS) -O2 -Wall -o eventdisp_app eventdisp_app.c eventtask.o: eventtask.c $(CC) $(INCLUDE) $(CFLAGS) -o eventtask.o -c eventtask.c clean: rm -f *.o ¥#* *~ $(TARGETS) execute: -insmod eventtask.o ./eventdisp_app -rmmod eventtask

★メイクファイルのexecuteについて 作成したモジュールを組み込み、プログラムを実行するまでをexecuteセクションにより行えるようにしています。 #make execute とコマンドを打ち込むと、eventtask.oを組み込み、eventdisp_appを実行後、eventtask.oの取り外しまで行います。

メイクファイルの作成が終われば、実際にコンパイルを行います。 #make

コンパイルを行うことで、eventdisp_appとeventtask.oというファイルができます。 eventtask.oは割り込み処理を行うリアルタイムモジュールです。 eventdisp_appは発生した割り込みの要因を表示するアプリケーションです。

Page 71: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

- 69 - Interface Corporation

4.3.5 動かしてみよう

それでは実行してみます。 まずは、リアルタイムモジュール,ドライバモジュールの組み込みを行った後(『14ページ 3.1 RTLinuxリアルタイムモジュール組み込み』『16ページ 3.2 RTLinux デジタル入出力ドライバ組み込み』参照)、eventtask.oを組み込みます。 #insmod eventtask.o

eventtask.oを組み込むと、割り込み発生の通知およびその要因情報をアプリケーションで受け取ることができるようになります。 割り込み要因を表示するアプリケーションeventdisp_appを実行すると、割り込みが発生するごとに、その要因を表示します。

#./eventdisp_app #Signal : IR.IN1 #Signal : IR.IN1 #Signal : IR.IN2 #Signal : IR.IN1 #Signal : IN1

リターンキーが押されるとアプリケーションは終了します。 確認が終わったらリアルタイムタスクモジュールを削除し、リアルタイムタスクを終了させます。 #rmmod eventtask

Page 72: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

Interface Corporation - 70 -

第5章 デバッグ手法

これまでの章で、RTLinux上でのデジタル入出力制御プログラミングはどのようなものかがお分かりいただけたと思います。この後、プログラミングを行っていく上で、避けては通れないデバッ

グを補助する機能を説明します。

作成したプログラムは、デジタル入出力ドライバを使用した部分の処理と、デジタル入出力ドラ

イバを使用しない部分の処理に分かれると思います。デジタル入出力ドライバを使用しない部分

については、デバッグのやり方(rtl_printfの説明,gdbの使用方法等)をRTLinuxチュートリアル導入編に記載していますので、そちらを参照してください。 ここでは、RTLinux デジタル入出力ドライバを使用した部分の処理について、デバッグしていきます。

5.1 ドライバデバッグ支援機能を使ってみる

GPG-2000ドライバには、デバッグ情報を出力するデバッグ支援機能がついています。ドライバ組み込み時、rcp2000_debuglevelパラメータにデバッグレベルを指定することでドライバデバッグ情報が出力されます。 デバッグレベルは以下の5段階があります。

ドライバのデバッグレベル

デバッグレベル 機能 0 デバッグ情報を出力しません 1 関数呼び出しトレース 2 エラー情報 4 I/Oモジュールリソース情報 16 割り込み発生情報

ドライバ組み込み時にオプションを指定しない場合は、デバッグレベルは0となります。 デバッグ支援機能を使うと、システムの負荷が高くなってしまうため、デバッグ時以外は、この

機能を使用しないようにしてください。

★デバッグ情報を複数出力する デバッグレベルの値の論理和を取った値を指定することで、複数のデバッグレベルを使用できます。 例)関数呼び出しトレースとエラー情報を出力する場合(’=’の前後にスペースはいりません。) #insmod rcp2000.o rcp2000_debuglevel=3

Page 73: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

- 71 - Interface Corporation

5.1.1 関数呼び出しトレース

この関数呼び出しトレースを使用すると、処理の実行状況や、関数呼び出し時の引数の値を容易

に知ることができます。では実際にデバッグ支援機能を使用して、さきほど作成したサンプルプ

ログラムを動かしてみましょう。 関数呼び出しトレースを指定して、ドライバを組み込みます。 (’=’の前後にスペースはいりません。) #insmod rcp2000 rcp2000_debuglevel=1

次にI/Oモジュールの初期化,デジタル入力,終了処理を行うモジュール(List 3-2で作成したinputtask.o)を組み込んでみます。 #insmod transtask.o

現段階では、DioOpen関数とDioInputPoint関数が呼び出されているはずです。 それでは、ログを確認してみましょう。 #less /var/log/messages ・・・ Feb 25 15:41:58 localhost kernel: rcp2000:DioOpen(1,0) Feb 25 15:41:58 localhost kernel: rcp2000:DioInputPoint(1, [0xc8 920271], 1, 8) (END)

ログにもDioOpen関数,DioInputPonit関数の順番に呼び出されていることが分かります。ログ中の[ ]で表されている部分は、引数がポインタの場合の変数のアドレスを示しています。 次に組み込んだinputtask.oを取り外してみます。 #rmmod inputtask

ログを見てみます。DioClose関数が呼び出されていることが分かります。 #less /var/log/messages ・・・ Feb 25 15:41:58 localhost kernel: rcp2000:DioOpen(1, 0) Feb 25 15:41:58 localhost kernel: rcp2000:DioInputPoint(1, [0xc8 920271], 1, 8) Feb 25 15:47:50 localhost kernel: rcp2000:DioClose(1) (END)

以上のように、関数が呼ばれた順番にログが残されています。

Page 74: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

Interface Corporation - 72 -

5.1.2 エラー情報

エラー情報を出力するように設定しておくと、関数のエラーコードよりも詳細なエラー情報を出

力します。 では、エラー情報出力を指定してドライバを組み込みます。 #insmod rcp2000.o rcp2000_debuglevel=2

下記Listのinputtask.cのLine44行目 DioOpen関数の第1パラメータに存在しないデバイス番号(10等)を記述してください。

inputtask.c_2

・・・ 46 ・・・

ret = DioOpen(10,0);

コンパイルしてモジュールを組み込んでください。 #make #insmod inputtask.o inputtask.o: init_module: Operation not permitted

エラーが出てドライバモジュールを組み込むことができません。 それでは、ログを見てみましょう。 #less /var/log/message Feb 25 16:30:25 localhost kernel: Open error[DevcieNo1]: Return value=0xc0001001

最後の行には、プログラム中で記述した部分が表示され、エラーコードより、引数パラメータの

値が不正であることがわかります。さらに、その上の行を見ると、Device number parameter errorという文字が残されているため、デバイス番号の指定が間違っていることが分かります。

5.1.3 I/Oモジュールソース情報

I/Oモジュールのリソースが正常かどうかを見ることにより、ソフトウェアが原因かハードウェアが原因かを知ることができます。 では、I/Oモジュールリソース情報を出力するようにしてみましょう。 #insmod rcp2000.o rcp2000_debuglevel=4

I/Oモジュールリソース情報は、ドライバを組み込んだ時点で出力されます。 ではログを見てみましょう。 #less /var/log/messages Feb 25 16:42:37 localhost kernel: rcp2000:DeviceID=0xAA6, SubsystemID=0x1, RevisionID=0x1 Feb 25 16:42:37 localhost kernel: rcp2000: I/O address=0xd000,Irq=9

拡張スロットに実装されているrcp2000が対応しているPCII/Oモジュールのリソースが表示されます。

Page 75: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

- 73 - Interface Corporation

リソース情報の項目

項目 内容 DeviceID デバイスID SubsystemID サブシステムID RevisionID リビジョンID I/O address I/Oポートアドレス Irq 割り込み番号

この値が異常の場合(0が表示された等の場合)は、ハードウェアが原因ということも考えられます。

5.1.4 割り込み発生情報

I/Oモジュールから割り込みが発生するたびに、発生した割り込み要因を確認することができます。 では第4章の割り込みイベントコールバックのプログラム例List 『eventtask.c』を使用して、割り込み発生情報を出力してみましょう。

#insmod rcp2000.o rcp2000_debuglevel=16

eventtask.oを組み込みます。 #insmod eventtask.o

割り込み発生要因のログを見てみましょう。 #less /var/log/messages Feb 25 17:21:59 localhost kernel: rcp2000:Interrupt factors:1h

割り込み発生要因の項目

項目 内容 Interupt factors 16進数のビットイメージで割り込み要因が表されます。

ビットと各要因の対応は、DioSetIrqMask関数のマスク値と同じです。

Page 76: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

Interface Corporation - 74 -

第6章 リファレンス

この章では、GPG-2000の関数,構造体,,戻り値の一覧を掲載しています。より詳しい情報は、ヘルプを参照してください。

6.1 関数一覧 No. 区分 関数名 機能

1 DioOpen 初期化 2

初期化終了 DioClose 終了

3 DioInputPoint 接点単位入力 4 DioInputByte バイト単位入力 5 DioInputWord ワード単位入力 6 DioInputDword ダブルワード単位入力 7 DioOutputPoint 接点単位出力 8 DioOutputByte バイト単位出力 9 DioOutputWord ワード単位出力 10

入出力

DioOutputDword ダブルワード単位出力 11 DioSetLatchStatus ラッチ回路接続設定 12

ハンドシェーク 入出力 DioGetLatchStatus ラッチ回路接続設定値取得

13 DioGetAckStatus ACK2,STB2,IR.IN2状態取得 14 DioSetAckPulseCommand ACK1,PULS.OUT1出力 15 DioSetStbPulseCommand STB2,PULS.OUT2出力 16 DioGetStbStatus STB1,ACK1,IR.IN1状態取得 17

制御信号制御

DioGetResetInStatus 外部リセット入力端子(RSTIN)状態取得18 DioSetIrqMask 割り込みマスク設定 19 DioGetIrqMask 割り込みマスク設定値取得 20 DioSetIrqConfig 割り込み論理設定 21 DioGetIrqConfig 割り込み論理設定値取得 22 DioRegistIsr 割り込みコールバック設定 23

割り込み

DioRegistIsrEx 割り込みコールバック設定 2162拡張

24 DioGetDeviceConfig デバイス情報取得 25 DioGetDeviceConfigEx デバイス情報取得

2162拡張 26

デバイス情報

DioCommonGetPciDeviceInfo デバイスID,リソース情報,I/OモジュールID(RSW1)等の情報取得

27 DioSetTimerConfig インターバルタイマ設定 28 DioGetTimerConfig インターバルタイマ設定値取得 29

インターバルタイマ

DioGetTimerCount インターバルタイマカウント値取得 30 DioEintSetIrqMask エッジ検出割り込みマスク設定

PCI-2162,CTP-2162用 31 DioEintGetIrqMask エッジ検出割り込みマスク設定値取得

2162用 32 DioEintSetEdgeConfig エッジ検出割り込み論理設定

PCI-2162,CTP-2162用 33 DioEintGetEdgeConfig エッジ検出割り込み論理設定値取得

PCI-2162,CTP-2162用 34

PCI-2162,CTP-2162 専用

DioEintInputPoint エッジ検出データ入力(接点単位) PCI-2162,CTP-2162用

Page 77: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

- 75 - Interface Corporation

No. 区分 関数名 機能 35 DioEintInputByte エッジ検出データ入力(バイト単位)

PCI-2162,CTP-2162用 36 DioEintInputWord エッジ検出データ入力(ワード単位)

PCI-2162,CTP-2162用 37 DioEintInputDword エッジ検出データ入力(ダブルワード単位)

PCI-2162,CTP-2162用 38 DioEintSetFilterConfig デジタルフィルタ時間設定

PCI-2162,CTP-2162用 39

PCI-2162 CTP-2162 専用

DioEintGetFilterConfig デジタルフィルタ時間設定値取得 PCI-2162,CTP-2162用

40 外部リセット DioSetRstinMask 外部リセット入力信号(RSTIN)のマスク設定 41 入力信号 DioGetRstinMask 外部リセット入力信号(RSTIN)のマスク設定状態

の取得

6.2 戻り値一覧 エラー識別子 値 意味 対処方法

FBIDIO_ERROR_SUCCESS 0 正常終了 FBIDIO_ERROR_NOT_DEVICE C0000001h ドライバが呼び出せ

ません。 指定されたデバイスが見つかりませんでした。指定しているデバイス名が存在するかどうかを確認してください。

FBIDIO_ERROR_NOT_OPEN C0000002h ドライバがOPENできません。

デバイスのオープン時に何らかのエラーが発生しました。ドライバの内部作業領域の確保に失敗した等。

FBIDIO_ERROR_INVALID_ DEVICE_NUMBER

C0000003h デバイスハ番号が正しくありません。

不正なデバイス番号で呼び出しを行おうとしました。OPEN関数で指定したデバイス番号を使用してください。

FBIDIO_ERROR_ALREADY_ OPEN

C0000004h 既にOPENしているデバイスをOPENしようとしました。

既にOPENされているデバイスです。

FBIDIO_ERROR_NOT_SUPPORTED C0000009h サポートされていない機能です。

ご使用になるI/Oモジュールがサポートしていない機能を制御する関数をコールした場合にエラーコードFBIDIO_ERROR_NOT_SUPPORTEDが返されます。DioOutputByte関数にDII/Oモジュールのデバイス番号を指定してコールした場合等が当てはまります。

FBIDIO_ERROR_PARAMETER C0001021h 引数パラメータの値が不正です。

API関数に指定する値が不正もしくは範囲外です。

Page 78: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038

Interface Corporation - 76 -

技術資料紹介 弊社では下記の技術資料を提供しております。 詳しくは、弊社Web site(www.interface.co.jp)、または弊社窓口までお問い合わせください。 カタログ

PRM-0061 CPZカタログ(日本語版) PRM-0062 PCIカタログ(日本語版) PRM-0063 CSIカタログ(日本語版)

チュートリアル TUT-0058 チュートリアル CPZ拡張ユニット 入門編 TUT-0056 チュートリアル XP Embedded OS構築編 TUT-0055 チュートリアル 画像入力I/Oモジュール TUT-0054 CANチュートリアル TUT-0053 モーションコントロールチュートリアル TUT-0050 RTLinuxによるモーションコントローラI/Oモジュール制御プログラミング チュートリアル(GPG-7400用) TUT-0048 RTLinuxによるメモリンクI/Oモジュール制御プログラミング チュートリアル TUT-0044 RTLinuxによるメモリ共有インタフェースI/Oモジュール制御プログラミング チュートリアル TUT-0043 RTLinuxによる調歩同期シリアル通信I/Oモジュール制御プログラミング チュートリアル TUT-0041 RTLinuxによるGP-IBI/Oモジュール制御プログラミング チュートリアル TUT-0040 RTLinuxによるDAI/Oモジュール制御プログラミング チュートリアル TUT-0039 RTLinuxによるADI/Oモジュール制御プログラミング チュートリアル TUT-0038 RTLinuxによるDIOI/Oモジュール制御プログラミング チュートリアル TUT-0037 RTLinuxによるHDLCI/Oモジュール制御プログラミング チュートリアル TUT-0036 RTLinuxによるPCI/CompactPCI/CardBus制御入門書(導入編) TUT-0034 Visual C++によるPPI入門書 TUT-0033 Visual Basicによるメモリ共有インタフェース入門書 TUT-0032 Visual C++によるメモリ共有インタフェース入門書 TUT-0031 Visual Basicによるメモリンク入門書 TUT-0030 Visual C++によるメモリンク入門書 TUT-0029 Visual BasicによるHDLC入門書 TUT-0028 Visual C++によるHDLC入門書 TUT-0027 Visual BasicによるGP-IB入門書 TUT-0026 Visual C++によるGP-IB入門書 TUT-0025 Visual BasicによるDIO入門書 TUT-0024 Visual C++によるDIO入門書 TUT-0023 Visual BasicによるDA入門書 TUT-0022 Visual C++によるDA入門書 TUT-0021 Visual BasicによるAD入門書 TUT-0020 Visual C++によるAD入門書 TUT-0019 Visual Basicによるモーションコントローラ入門書 TUT-0018 Visual C++によるモーションコントローラ入門書 TUT-0017 メモリンクを使用した負荷分散システム事例チュートリアル TUT-0016 Visual BasicによるPPI入門書 TUT-0015 モーションコントロールチュートリアル TUT-0014 Microsoft Visual Studio .NET移行ガイド TUT-0008 拡張ユニット チュートリアル(問題解決編) TUT-0007 拡張ユニットチュートリアル(入門編) TUT-0006 C(98)/ISA製品からPCI/CompactPCI製品への移行チュートリアル(DOS編) TUT-0005 DOSによるLAP-B入門書 TUT-0004 DOSによるAD入門書 TUT-0003 LinuxによるPCI/CompactPCI/CardBus制御 入門書 TUT-0002 PCI-ISAバスブリッジチュートリアル TUT-0001 PCI-Cバスブリッジチュートリアル

技術情報資料 初めてのCANインタフェース Linux, リアルタイムLinux移植(SH-4)経験談及び当社の今後の取り組みについて LinuxからPCI/CompactPCII/Oモジュールを制御する方法 ActiveXコントロールによるシステム組み込み技術 CompactPCIへの置き換え+システム構築/移行ガイド MS-DOSからPCI/CompactPCII/Oモジュールを制御する方法

Page 79: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

TUT-0038 2006年 8月 Ver. 1.5 発行 発行所

〒732-0828 広島県広島市南区京橋町10-21 TEL 082-262-7777 FAX 082-262-5066

定価 ¥2,000

本書の内容の一部または全部を、無断で転載することを禁止します。 本書の内容は、将来予告なく変更することがありますので、あらかじめご了承ください。 © 2002, 2006 Interface Corporation. All rights reserved.

Page 80: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

www.interface.co.jp

サポート体制

本製品についてのお問い合わせは、お客様相談センタで承ります。弊社Web siteのオンライ

ンQA(「サポート」→「お客様相談センタ」をクリック)、E-mailまたはフリーダイヤルをご利用く

ださい。 お問い合わせ先 <お客様相談センタ> TEL 0120-447213 FAX 0120-458257 (祝日および弊社休業日を除く月~金 AM9:00~PM5:00迄) E-mail [email protected]

TUT-0038 Ver. 1.5 Vol. 1/1

Page 81: チュートリアルenomoto/kgrsr/hardware/data/tut... 商標/登録商標 本ドキュメントに掲載されている会社名,製品名は、それぞれ各社の商標または登録商標です。

www.interface.co.jp

RTLinuxによるDIOボード制御プログラミング チュ-トリアル

TUT-0038 Ver. 1.5