どのようにLinuxカーネル内の文字のデバイスドライバは、そのレコードのドライバエントリ関数を呼び出します

?* /ドライバのエントリ関数を呼び出す方法/ *カーネル
/ * A:使用module_init()関数、
構造体のmodule_init()関数定義、関数ポインタを持つ構造、
first_drv_initを指している()ドライバのエントリ関数、ときに我々ドライバがインストールまたはロードされたときに、
カーネルが自動的にこのような構造を見つけるだろうし、その後、この構造では、関数ポインタを呼び出す
駆動機能エントリ有する(ボイド)ドライバエントリ機能first_drv_init、起動する
(メジャー番号register_chrdevを、デバイス名、構造体file_operations構造ポインタ)機能、
カーネルまでに沿って行わそのドライバのメジャー番号と一緒に機能するfile_operations構造
タイプstruct file_operationsの構造のドライバ入力機能がコアに送信するように、
カーネルは、特定の運転操作の機能を呼び出すために、この関数ポインタの構造を呼び出すことができ
    、最終的になるアプリケーション・プログラム・ファイルは、操作装置がオープンと呼ばれる、読み取り、書き込み、およびその他の機能
/ *タイプstruct file_operations構造を呼び出します

 

#include <linuxの/ module.h> 
の#include <linuxの/ kernel.hを> 
する#include <linuxの/ fs.h> 
の#include <linuxの/ init.h> 
の#include <linuxの/ delay.h> 
の#include <ASM / uaccess.h> 
の#include <ASM / irq.h> 
の#include <ASM / io.h> 
の#include <ASM /アーチ/ REGS-gpio.h> 
の#include <ASM / hardware.h> 静的構造体クラス * firstdrv_class。
静的構造体 class_device * firstdrv_class_dev。揮発性の符号なしの長い * gpfcon = NULL;


   

* gpfdat = NULL; 


静的 int型 first_drv_open(構造体のinode * iノード、構造体ファイル*のファイル)
{ 
    // のprintk( "first_drv_open \ nを"); 
    / * 配置GPF4,5,6为输出* / 
    * gpfcon&=〜((0x3の <<(4 * 2))|(0x3の <<(5 * 2))|(0x3の <<(6 * 2 )) );
    * gpfcon | =((0x1の <<(4 * 2))|(0x1の <<(5 * 2))| 0x1の <<(6 * 2 )))。
    リターン 0 ; 
} 

静的 ssize_tののfirst_drv_write(構造体ファイル*ファイル、CONST  チャー __user * bufは、size_tのカウント、loff_t * するPPO)
{ 
    int型のval; 

    // のprintk( "first_drv_writeの\ nを"); 

    copy_from_user(&valを、bufが、カウント); //     copy_to_user(); 

    もし(ヴァル== 1 
    { 
        // 点灯 
        * gpfdat&=〜((1 << 4)|(1 << 5)|(1 << 6 )); 
    } 
    
    { 
        // 消灯 
        * gpfdat | =(1 << 4)|(1 << 5)|(1 << 6 ); 
    } 
    
    戻り 0 ; 
} 

静的 構造体 file_operations = first_drv_fops { 
    .owner   = THIS_MODULE、     / * これは、自動的にコンパイル・モジュール中に作成__this_moduleにマクロ変数である* / 
    .Open    =    first_drv_open、      
    .WRITE     =     first_drv_write、       
}。


int型の主要な;
静的 INT first_drv_init(ボイド/ * 驱动的入口函数* / 
{ 
    主要 = register_chrdev(0" first_drv "、&​​first_drv_fops)。/ * 注册、把first_drv_fops告诉内核* / 

    firstdrv_class = class_create(THIS_MODULE、" firstdrv " )。

    firstdrv_class_dev = class_device_create(firstdrv_class、NULL、のmkdev(メジャー、0)、NULL、" XYZ ")。/ * は/ dev / XYZ * /
 
    gpfcon =(揮発符号なしロング *)ioremap(0x5600005016 ); 
    gpfdat = gpfcon + 。1 ; 

    戻り 0 ; 
} 

静的 ボイド first_drv_exit(ボイド
{ 
    unregister_chrdev(メジャー、" first_drv "); // 搬出

    class_device_unregister(firstdrv_class_dev); 
    class_destroy(firstdrv_class ); 
    iounmap(gpfcon); 
} 
/ * ?どのカーネル・ドライバ・エントリ関数を呼び出す* / 
/ * A:使用module_init()関数 
module_init()関数は、関数ポインタを持つ構造体を構造体を定義し、
ポイントfirst_drv_init()ドライバエントリ機能は、我々は、ドライバや負荷をインストールするときに、
カーネルが自動的にこのような構造を発見し、その後、この構造体に関数ポインタを呼び出して
、(無効)ドライバエントリ関数first_drv_initを呼び出すためにドライバ入力機能は有し
register_chrdev(マスタデバイス番号、デバイス名、構造体file_operations構造ポインタ)関数、
そのマスターカーネル番号と共にドライバを登録するように機能するfile_operations構造を、
その運転者入力機能構造体の構造体file_operationsタイプがカーネルに伝達され、
カーネルは、機能の特定の運転操作を呼び出すために、この構造における関数ポインタを呼び出すことができ
    、アプリケーション動作デバイスファイルがオープンと呼ばれる読み取り、書き込み、および他の機能、最終的に
構造体を呼び出しますfile_operations構造タイプ* / 
module_init(first_drv_init); 
/ ** / 
module_exit(first_drv_exit); 

/ ** / 
MODULE_LICENSE(" GPL ");

 

おすすめ

転載: www.cnblogs.com/yan-hui/p/11290522.html