/****************** * 高度な文字デバイス ドライバー *********************/ (1)ioctl ほとんどのドライバーでは、デバイスの読み取りと書き込みに加えて、デバイス ドライバーを通じてさまざまな種類のハードウェア制御を実行する機能も必要です。たとえば、メディアの取り出し、ボーレートの変更などです。これらの操作は、同じ名前のシステム コールを実装する ioctl メソッドによってサポートされます。 ユーザー空間では、ioctl システム コールのプロトタイプは次のようになります。
ドライバーの ioctl メソッドのプロトタイプは、ユーザー空間バージョンとは少し異なります。
ほとんどの ioctl 実装には、cmd パラメータに基づいて対応する操作を選択するための switch ステートメントが含まれています。ユーザー空間とカーネル空間のコマンド番号は一貫している必要があります。 (2)ioctlコマンド番号を選択する ioctl コードを書く前に、さまざまなコマンドに対応する番号を選択する必要があります。 Linux ではこのコマンド番号がシステム全体で一意である必要があるため、単純に 0 または 1 から始まる番号を選択することはできません。 Linux カーネルは、ドライバの ioctl 番号を選択するために規則を使用します。include/asm/ioctl.h および Documentation/ioctl-number.txt を参照できます。 ioctl 番号は 32 ビット長です。Linux ではこれを 4 つの部分に分割します。ioctl 番号を構築するために必要なマクロは <linux/ioctl.h> で定義されています。
<linux/ioctl.h>のマクロを使用してioctl番号を構築することができます。
戻り値 システムコールの場合、正の戻り値が最初に保護され、負の値はエラーと見なされ、ユーザー空間でエラー変数を設定するために使用されます。 ioctl メソッドを呼び出すときに未定義の ioctl 番号が渡された場合、システムによって返されるエラー値は -ENVAL および -ENOTTY になります。 (3)ブロッキング操作と非ブロッキング操作 読み取りや書き込みなどの操作の場合、デフォルトの操作はブロッキングであり、その特性は次のとおりです。 *プロセスが read を呼び出しても読み取るデータがない場合、プロセスはブロックする必要があります。データが到着すると、データ量が count パラメータで指定されたデータ量より少ない場合でも、プロセスが起動され、データが呼び出し元に返されます。 *プロセスが write を呼び出してもバッファにスペースがない場合、このプロセスはブロックされ、読み取りプロセスとは異なる待機キューでスリープする必要があります。ハードウェア デバイスにデータが書き込まれ、出力バッファの一部が解放されると、プロセスが起動され、書き込み呼び出しが成功します。 場合によっては、この機能を変更して非ブロッキングにし、デバイスに読み取りまたは書き込みするデータがあるかどうかに関係なく、読み取り/書き込みメソッドがすぐに返されるようにする必要があります。 ファイルを非ブロッキングに設定する場合は、filp->f_flags の O_NONBLOCK フラグを設定する必要があります。非ブロッキング ファイルを扱う場合、非ブロッキングの戻りを EOF と間違えやすいため、アプリケーションは stdio 関数を呼び出すときに非常に注意する必要があります。そのため、errno を常にチェックする必要があります。 (4)非同期通知 a. 非同期通知の役割 ほとんどの場合、ブロッキング操作と非ブロッキング操作、および select メソッドの組み合わせにより、デバイスを効果的に照会できますが、この手法が効率的でない場合もあります。特定のランダムな状況やまれにしか発生しない状況 (キーボードで CTRL+C を入力するなど) が発生した場合は、非同期通知が必要になります。 b. ユーザー空間プログラムで非同期通知を開始する方法 ファイルの非同期通知メカニズムを開始するには、ユーザー プログラムは次の 2 つの手順を実行する必要があります。
(5)ドライバーに非同期通知を実装する方法 a. カーネル内のユーザー空間操作の対応
b. デバイス構造体にfasync_structポインタを追加する この構造体は <linux/fs.h> で定義されています: 構造体fasync_struct { int マジック; 整数fa_fd; 構造体 fasync_struct *fa_next; 構造体ファイル *fa_file; }; c. ドライバーが呼び出す2つの関数 これら 2 つの関数は <linux/fs.h> で宣言されています。 /fs/fcntl.c で定義されています。 プロトタイプは次のとおりです。
開いているファイルの FASYNC フラグが変更されると、関連付けられているプロセスのリストにファイルを追加または削除するために fasync_helper が呼び出され、データが到着すると kill_fasync が関連付けられているすべてのプロセスに通知します。 d. 例 01. デバイスタイプにfasync_struct動的データ構造を定義する 構造体my_pipe{ struct fasync_struct *async_queue; /* 非同期読み取り構造体*/ ...... }; 02. ドライバーのfasync関数はfasync_helperを呼び出す int my_fasync(fasync_file fd、構造体ファイル *filp、int モード) { my_pipe *dev = filp->private_data; fasync_helper(fd, filp, mode, &dev->async_queue) を返します。 } 03. 非同期通知条件が満たされたらkill_fasyncを呼び出す 非同期通知は読み取りプロセス用なので、kill_fasync は write を使用して送信する必要があります。 kill_fasync を呼び出して、デバイス上の非同期キュー async_queue に登録されているすべてのプロセスに SIGIO シグナルを送信します。 ssize_t my_write(構造体ファイル*filp、const char *buf、size_t count、 オフセット(f_pos) { ...... (dev->async_queue) の場合 kill_fasync(&dev->async_queue、SIGIO、POLL_IN); ...... } 04. ファイルを閉じるときにfasyncメソッドを呼び出す必要があります アクティブな非同期リーダーのリストからファイルを削除するには、ファイルを閉じるときに fasync メソッドを呼び出す必要があります。 リリースを呼び出します: scull_p_fasync(-1, filp, 0); 要約する 以上がこの記事の全内容です。この記事の内容が皆様の勉強や仕事に何らかの参考学習価値をもたらすことを願います。123WORDPRESS.COM をご愛顧いただき、誠にありがとうございます。これについてもっと知りたい場合は、次のリンクをご覧ください。 以下もご興味があるかもしれません:
|
<<: JavaScriptは、ユーザーがチェックボックスをオンにする必要があるプロトコルの例を実装します。
>>: MySql5.7.18 の文字セット構成の詳細なグラフィック説明
1. Navicat for MySQL 15をダウンロードするhttps://www.navica...
背景スレッド•マスタースレッドコア バックグラウンド スレッドは主に、バッファー プール データをデ...
1. デフォルトでアクセスするには、curl コマンドを使用します。 # curl -I http:...
この記事では、ウォーターフォールフローが底に達したときにデータを動的にロードするためのjsの具体的な...
文字列を動的に連結する場合、文字連結を使用することが多いです。次のような連結の引用符の意味がわかりま...
目次1. CentOS 7.9 20にDockerをインストールする2. MySQL クラスターをデ...
目次1. 配列の分離割り当て1.1 配列分離割り当てとは何ですか? 1.2 配列分離割り当てに失敗し...
MySQL には次のログ ファイルがあります。 1: 再実行ログ2: ロールバックログ(元に戻すログ...
HTML メタビューポート属性の説明ビューポートとはモバイル ブラウザは、Web ページを仮想の「ウ...
VMware Workstation を使用して Windows 10 で仮想マシンを開くと、VMw...
設定する前に、次の操作を行う必要があります。 1. まずjdk bloggerをインストールします。...
目次序文変換関係具体的な実装file2DataUrl(ファイル、コールバック) file2Image...
ページで CSS を使用する主な方法は、スタイル属性値をインラインで追加する方法、ページ ヘッダーで...
この記事では、MySQL データベースでのアカウントの作成、認証、データのエクスポートおよびインポー...
目次1. マスタースレーブレプリケーションマスタースレーブレプリケーション3スレッドマスタースレーブ...