register_chrdev_region / alloc_chrdev_regionとCDEV登録キャラクタデバイスドライバ

カーネルが文字デバイス番号のグループを登録するための3つの機能を提供し、これら3つの関数がregister_chrdev_region()、alloc_chrdev_region()とregister_chrdev()です。


(1)register_chrdevの   フォーム古いカーネルは、登録   の早期ドライブ
(2)register_chrdev_region / alloc_chrdev_region + CDEV新しいドライブフォーム

差:0動的登録register_chrdev()関数のデバイス番号登録機能の古いバージョンの内部に、静的および動的な登録が主として所与のメジャー番号によって区別することが2つの方法で達成することができるが、0です。register_chrdev_regionとalloc_chrdev_region登録番号スプリットを強化された上記静的および動的なデバイスの機能です

 

register_chrdev_region(最初のdev_t、unsigned int型、文字*名COUNT)
メジャー番号に割り当てるデバイス番号の範囲、デバイスのデバイス番号を開始連続番号のセットの初期値を、register_chrdevに対応():最初の

連続番号の範囲:カウントこのグループは、デバイス番号(倍のデバイス数が数)のサイズである
デバイスドライバのグループ名、番号(/ PROC /デバイス)に関連付けられているデバイスの名前:名前。

カーネルは自動的に私たちにデバイス番号を割り当ててみましょうするalloc_chrdev_region機能

(1)register_chrdev_regionマイナーデバイス番号に使用使用される事前に知られている主である猫の/ proc /デバイスを参照するために使用されていない参照するように依頼します。
(2)簡単に、よりスマートな方法は、使用alloc_chrdev_regionを自動的に割り当てることができ、私たちにカーネルが自動的にメジャー番号を割り当てできるようにすることです。
(3)自動的にデバイス番号を割り当てられ、我々は彼のメジャーとマイナーデバイス番号を知っている必要があります、または他のmknodは彼に対応するデバイスファイルを作成し、戻ることはできません。

 

int型alloc_chrdev_region(のdev_t * devの、符号なしbaseminor、符号なし数、CONST文字*名)

1:最初の引数は、デバイスに割り当てられた番号を取得し、出力パラメータです。MAJOR MINORは、マクロおよびマクロを使用するメジャー番号とマイナー番号、抽出されたプリントアウト、自動的に私たちはデバイスファイルを作成はmknodでメジャーとマイナー番号を使用する際に役立つように割り当てられているどのくらい見ることができます。mknodをは/ dev / xxxはCメジャー番号、マイナーデバイス番号

2:第二引数:最初のデバイス番号から割り当てられた回数基準デバイス、複数回。

3:第三のパラメータ:回数デバイス番号。

4:第四パラメータ:ドライバの名前。

5:戻り値:0未満の、誤り、間違った番号が自動的にデバイスを分配します。それ以外の場合は、それから抜け出すために割り当てられたデバイスの数は、第1引数でいました。

 

はじめにCDEV

CDEVがされ、カーネルへの登録・ドライブ、キャラクタデバイスの表現私たちを助けるために一緒に来ているのメンバーは、この構造体structのCDEVは人口、構造体である主に充填します

コードをコピー

CDEV {構造体

たkobject KOBJをストラクト、

構造体* Module1の所有者; //ブロックTHIS_MODULEする時間値を満たす

CONST構造体file_operationsを* OPS; // file_operations構造体変数の中に充填するために、この構造は、キー登録ドライブ、

構造体LIST_HEADをリスト; 

のdev_t DEVを; //デバイス番号、プライマリデバイス番号+マイナー番号

unsigned int型カウント; //回デバイス番号の数

};

コードをコピー

 

file_operationsこの構成変数、CDEVの構造変数値file_operations OPSメンバーの値となるよう。この構造は、カーネル関数を登録したいcdev_add経験です

CDEV構造は、多くの機能が彼を動作させるために使用することができます。

以下のような:

cdev_alloc:この構造体のカーネルメモリの割り当てをしましょう

cdev_init:バンドル構造体の構造体変数と構造CDEVタイプfile_operations

cdev_add:内部のカーネルにドライブを追加し、登録ドライブ

cdev_del:ドライブオフカーネルからログオフします。運転のキャンセル

デバイス番号

(1)のdev_tタイプ(マスター番号12のいくつかのマイナー番号が設定されているコア16と、いくつかの16ビット・デバイス番号で定義され、メジャー番号20をランク付けするように、異なるメジャーおよびマイナー番号などは同じではありません)

(2)のmkdev、MAJOR、MINOR 3マクロ

mkdevは:メジャー番号とマイナー番号のため、メジャーとマイナー番号に変換されます。(デバイス番号)

MAJOR:デバイス番号を裏返しメジャー番号から抽出されます。

MINORマクロ:マイナー番号のうち、デバイスから抽出された番号。

コントラストregister_chrdev_regionのregister_chrdevの使用:

コードをコピー

取付1つの//機能モジュール
 2は__init静的INT(ボイド)をchrdev_init 
 3 {     
 4 INT RETVALを、。
 。5      
 6のprintk(KERN_INFO "HelloWorldのがINIT \ N-をchrdev_init");。
 。7 
 。8 / * 
 9 //関数マクロmodule_initにコールを登録します文字デバイスドライバ
10の//主要なパス0に自動的に割り当てられ、私たちを助けるためにカーネルを作ることを誓った、適切な空白のメジャー番号が使用されていない
成功したが、割り当てられたマスターが返されます場合は11が//良いカーネルを割り当て、割り当てが失敗した場合負の戻り
12はmymajor = register_chrdev(0、MYNAME、&test_fops)であり、
13は、IF(mymajor <0)である
14 { 
のprintk(KERN_ERR "register_chrdev失敗の\ N-")15; 
16リターン-EINVAL; 
17} 
18のprintk(KERN_INFO「register_chrdev成功です。 %D = mymajor .. \ N-」、mymajor);. 
。19 * /     
20であります
21 // CDEV新規登録キャラクタ・デバイス・ドライバ・インターフェース
22 //新しいインタフェース・レジスタは、2つのステップキャラクタデバイスドライバ必要と
23は      
24 //ステップ1:登録/割り当てメジャーおよびマイナー番号
25 mydev =のmkdev(MYMAJOR、0 ) ; 
26はRETVAL = register_chrdev_region(すなわちmydev、MYCNT、MYNAME)である; //は、
他の行は以下のように除去される動的2526の直下に変更// 
// INT alloc_chrdev_region(たdev_t * DEV、符号なしbaseminor、符号なしカウント、CONST文字*名) 
27(RETVAL)IF { 
28のprintk(KERN_ERR "未成年者のために登録することができません%S \ N-"、MYNAME); 
29戻り-EINVAL; 
30} 
31のprintk(KERN_INFO "register_chrdev_region成功\ N-")である; 
32 //ステップ2 :登録されたキャラクタ・デバイス・ドライバ
33はcdev_init(&test_cdev、&test_fops)であり、
34はRETVAL = cdev_add(&test_cdev、そのmydev、MYCNT)です。
35(RETVAL)であれば{
printk 36(KERN_ERR "\ N- cdev_addことができません"); 
37 -EINVAL戻り、
38である} 
39のprintk( "成功\ N- cdev_add" KERN_INFO); 
40 
41である      
登録する動的マッピング操作を使用して@モード42 
43 IF(request_mem_regionを! (GPJ0CON_PA ,. 4、 "GPJ0CON"))
44が-EINVALを返すある
45 IF(!request_mem_region(GPJ0DAT_PA ,. 4、 "GPJ0CON"))
46 -EINVALを返すである
47      
48 pGPJ0CON = ioremap(GPJ0CON_PA ,. 4); 
49 pGPJ0DAT = ioremap (GPJ0DAT_PAは,. 4); 
50      
; 51はpGPJ0CON * = 0x11111111であり、
52はpGPJ0DAT * =((0 << 3)|(0 << 4)|(<< 0.5)。); //光
53は      
54である
55戻り0;
56} 
57 
58 //ダウンロード機能モジュール
59静的ボイド__exitのchrdev_exit(ボイド) 
60 { 
61のprintk(KERN_INFO "N- \のHelloWorld chrdev_exit出口")であり、
62は
63 pGPJ0DAT * =((<< 1 3)|(<< 1.4)|(<< 1.5)。。。)され、     
64      
65 //デマッパ
66 iounmap(pGPJ0CON); 
67 iounmap(pGPJ0DAT); 
68 release_mem_region(GPJ0CON_PA ,. 4); 
69 release_mem_region(GPJ0DAT_PA ,. 4); 
70 
71は、/ *     
72 //マクロコールmodule_exitキャラクタログアウトする機能でデバイスドライバ
73は、unregister_chrdev(mymajor、MYNAME)である
74 * /     
75 
76 //文字デバイスドライバ登録解除するための新しいインタフェースを使用して
二段階でキャンセル@ 77:
キャンセルcdev_del 78 //ステップ正体デバイスドライバ
79 cdev_del( test_cdev&); 
80 // 2番目のステップは、メジャーとマイナーデバイス番号の取り消しを申請することです 
81 unregister_chrdev_region(そのmydev、MYCNT); 
82}

コードをコピー

完全なコード:

 コードの表示

 コードの表示

 アウトヒープ領域を割り当てられたポインタ型の構造体CDEVを定義するcdev_alloc

内部cdev_allocが実際にヒープメモリを割り当てることstruct_cdevを与えるためにカーネルkmallocのと呼ばれ、メモリサイズは、構造体のCDEVのサイズです。

例:私たちはグローバルな静的構造体CDEVの*のpcdevを定義した場合、pcdevのためのスペースを割り当てるためにヒープメモリ、我々はpcdev = cdev_alloc()を使用することができます。ヒープメモリに、このアプリケーションのうちcdev_del、cdev_del内部関数がターゲット構造体のCDEVがスタックメモリまたはヒープメモリまたはデータ・メモリ・セグメントによって定義されている知っているリリース(pcdev)。この関数cdev_del呼び出しは、最初に、そして、あなたのために解放されたヒープメモリを行く場合に有用であることが、ヒープメモリを使用せずに参照してくださいする必要があります、そしてあなたは、このデバイスドライバをオフに書くとき。メモリリークを防ぎます。リリースは、ヒープメモリの一部から出て行くだろうと、内部レコードがドライブオフcdev_del書き込みにそうなりますので、もし構造体CDEVの使用ヒープメモリは、ヒープメモリを割り当てるためにカーネルによって提供されるこのcdev_allocを使用しなければならないことに注意してください。

cdev_alloc直接pcdev->オプス=のFOPSを使用して、バインドするために、この関数は、cdev_initを必要としません。

コード:

コードをコピー

 

静的のdev_t mydev。
//静的構造体CDEVのtest_cdev。
静的構造体CDEVの*のpcdev。

......... 

//ステップ2:登録文字デバイスドライバ
    pcdev = cdev_alloc(); // pcdevにメモリを割り当て、ポインタの例は
    // cdev_init(&test_cdev、&test_fops ); // 次のコード置き換え文応力
    > = THIS_MODULE所有者pcdev-; 
    pcdev-> OPS =&test_fops。

コードをコピー

cdev_init出典:

1

2

3

4

5

6

7

8

void cdev_init(struct cdev *cdev, const struct file_operations *fops)

{

    memset(cdev, 0, sizeof *cdev);

    INIT_LIST_HEAD(&cdev->list);

    cdev->kobj.ktype = &ktype_cdev_default;

    kobject_init(&cdev->kobj);

    cdev->ops = fops;

}

 cdev_allocで他の操作でcdev_initを行っています。

 

仕上げので、

http://blog.csdn.net/tommy_wxie/article/details/7195471

http://blog.sina.com.cn/s/blog_14f1867f70102wlrj.html

http://edu.51cto.com/pack/view/id-529.html

 http://blog.csdn.net/zqixiao_09/article/details/50839042(Haotie)

タグ:  Linuxの

おすすめ

転載: blog.csdn.net/ll148305879/article/details/93602359