/****************** * 高度な文字デバイス ドライバー *********************/ (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 の文字セット構成の詳細なグラフィック説明
前回の記事では、Navicat for Mysql 接続エラー 1251 (接続失敗) の問題を解決...
この記事では、階段スライド効果を実現するためのjQueryの具体的なコードを参考までに紹介します。具...
たとえば、新しいテーブルを作成したり、既存のテーブルのデータを更新したりすると、これらのイベントは、...
前回の記事に引き続き、web02 サーバーを作成し、web01 サーバーと web02 サーバーの ...
https をサポートしていない Web サイトは、ブラウザによって徐々に安全でないとマークされるた...
目次1. 百度百科事典1. MySQL 2. PostgreSQL 3. MySQL に対する Po...
//文法: @media mediatype and | not | only (メディア機能) ...
目次MySQL 5.6以前MySQL 5.6以降要約する知らせMySQL 5.6以前更新手順元のテー...
MySQL x64 はインストーラーを提供していません、インストーラーを提供していません、インストー...
この記事では、ネイティブ JS で実装された複合モーションを紹介します。複合モーションとは、異なる属...
以前、フロントエンド技術グループに所属していたとき、グループのメンバーが面接中に問題に遭遇したと言っ...
1. my.cnfを変更する #全体的な効果としては、グローバルがオンになっている場合はテーブルとロ...
この記事では、例を使用して、MySQL の日付と時刻の間隔計算について説明します。ご参考までに、詳細...
XHTML 言語では、ul タグに li が含まれ、dl タグに dt と dd が含まれることは誰...
1. 背景Sysbench は、システムのハードウェア パフォーマンスをテストできるストレス テスト...