Class_create()、class_device_create()、またはdevice_create()は、デバイスファイルノードを自動的に作成します



Class_create Class_device_create



/*2.6.15関数:
class_device_create();
class_device_destroy();
2.6.27になります:
device_create()
device_destroy()

この関数は、include / linux /device.hで宣言されています。
プロトタイプ:drivers / base / core.c



* /

Class_create()、class_device_create()、またはdevice_create()は、デバイスファイルノードを自動的に作成します



2.6.15の関数:
class_device_create();
class_device_destroy();
2.6.27になります:
device_create()
device_destroy()

この関数は、include / linux /device.hで宣言されています。
プロトタイプ:drivers / base / core.c

Linuxカーネル2.6のバージョン以降、devfsは存在しなくなり、udevがdevfsの代わりになります。 devfsと比較して、udevには多くの利点があるため、面倒ではありません。udevはアプリケーション層であることを思い出してください。カーネル構成オプションでそれを見つけようとしないでください。udevのサポートを追加するのは、作成者にとって非常に簡単です。キャラクターデバイスドライバーが書かれています。ドライバー初期化のコードでは、デバイスのクラスを作成するためにclass_createが呼び出され、次に各デバイスに対してclass_device_createが呼び出されて、対応するデバイスが作成されます。 (どのdevfs、udevがLinuxのファイルシステムの概念ではないのかよくわかりません。)
大まかに次のように使用されます。
struct class * myclass = class_create(THIS_MODULE、“ my_device_driver”)
class_device_create(myclass、NULL、MKDEV(major_num、0)、NULL、“ my_device”)
このようなモジュールがロードされると、udevデーモンは/ devの下にmy_deviceデバイスファイルを自動的に作成します。



class_create()

linux-2.6.22 / include / linux / device.h
struct class * class_create(struct module * owner、const char * name)
class_create-構造体クラス構造体を作成します
@owner:この構造体クラスを「所有」するモジュールへのポインタ
@name:このクラスの名前の文字列へのポインタ。
/ sys / class /の下にクラスディレクトリを作成します

class_device_create()

linux-2.6.22 / include / linux / device.h
struct class_device * class_device_create(struct class * cls、
struct class_device * parent、
dev_t devt、
struct device * device、
const char * fmt、…)

class_device_create - creates a class device and registers it with sysfs @cls: pointer to the struct class that this device should be registered to. @parent: pointer to the parent struct class_device of this new device, if any. @devt: the dev_t for the char device to be added. @device: a pointer to a struct device that is assiociated with this class device. @fmt: string for the class device's name

ドライバモジュール初期化機能でのデバイスノードの自動作成

Linuxデバイスドライバーの作成を最初に開始したときは、mknodコマンドを使用してデバイスノードを手動で作成することがよくありました。実際、Linuxカーネルは、モジュールがロードされたときに/ devディレクトリで自動的に使用できる一連の関数を提供します。対応するデバイスノードを作成し、モジュールがアンインストールされたときにノードを削除します。もちろん、ユーザースペースはudevに移植されます。
構造体クラスの構造はカーネルで定義されています。名前が示すように、構造体クラスの構造型変数はクラスに対応します。カーネルは、クラスの作成に使用できるclass_create(...)関数も提供します。このクラスはsysfsの下に保存されます。クラスが作成されたら、device_create(...)関数を呼び出して、/ devディレクトリに対応するデバイスノードを作成します。したがって、モジュールがロードされると、ユーザースペースのudevは自動的にdevice_create(...)関数に応答し、/ sysfsの下で対応するクラスを探してデバイスノードを作成します。
2.6の以前のカーネルバージョンでは、device_create(...)関数名が異なり、class_device_create(...)であるため、新しいカーネルで前のモジュールプログラムをコンパイルするとエラーが発生する場合があることに注意してください。関数名が異なり、内部のパラメータ設定に変更があるためです。
struct classとdevice_create(...)およびdevice_create(...)は、どちらも/include/linux/device.hで定義されています。このヘッダーファイルを使用するときはインクルードする必要があります。インクルードしないと、コンパイラーがエラーを報告します。 。
2.6.26.6カーネルバージョンでは、structクラスはヘッダーファイルinclude / linux /device.hで定義されています。
/ *

  • デバイスクラス
    * /
    構造体クラス{
    const char * name
    構造体モジュール オーナー
    nbspstruct kset subsys
    structlist_headデバイス
    structlist_headインターフェース
    struct kset class_dirs
    struct semaphore sem /
    子、デバイス、インターフェイスをロックします* /
    struct class_attribute * class_attrs
    struct device_attribute * dev_attrs
    int(* dev_uevent)(struct device * dev、struct kobj_uevent_env * env)
    void(* class_release)(struct class * class)
    void(* dev_release)(struct device * dev)
    int(* suspend)(struct device * dev、pm_message_t state)
    int(* resume)(struct device * dev)
    }
    class_create(...)は/drivers/base/class.cに実装されています:

    struct class * class_create(struct module * owner、const char * name)
    {{
    構造体クラス* cls
    int retval
    cls = kzalloc(sizeof(* cls)、GFP_KERNEL)
    if(!cls){
    retval = -ENOMEM
    gotoエラー
    }
    cls-> name = name
    cls-> owner =所有者
    cls-> class_release = class_create_release
    retval = class_register(cls)
    if(retval)
    gotoエラー
    clsを返す
    エラー:
    kfree(cls)
    ERR_PTR(retval)を返します
    }
    最初のパラメーターはクラスの所有者がどのモジュールであるかを指定し、2番目のパラメーターはクラス名を指定します。
    class.cでは、モジュールがアンロードされたときにクラスを削除するために、class_destroy(...)関数も定義されています。
    device_create(...)関数は/drivers/base/core.cに実装されています。

    struct device * device_create(struct class * class、struct device * parent、
    dev_t devt、const char * fmt、…)
    {{
    va_list泥棒
    struct device * dev
    va_start(poor、fmt)
    dev = device_create_vargs(class、parent、devt、NULL、fmt、vargs)
    va_end(泥棒)
    開発者を返す
    }
    最初のパラメーターは、作成するデバイスが属するクラスを指定します。 2番目のパラメーターは、デバイスの親デバイスです。そうでない場合は、NULLとして指定され、3番目のパラメーターはデバイス番号です。 4番目のパラメーターはデバイス名で、5番目のパラメーターはスレーブデバイス番号です。
    以下は、これらの機能の使用方法を示す簡単なキャラクターデバイスドライバーです。

#include #include #include #include #include #include MODULE_LICENSE ('GPL') int hello_major = 555 int hello_minor = 0 int number_of_devices = 1 struct cdev cdev dev_t dev = 0 struct file_operations hello_fops = { .owner = THIS_MODULE } static void char_reg_setup_cdev (void) { int error, devno = MKDEV (hello_major, hello_minor) cdev_init (&cdev, &hello_fops) cdev.owner = THIS_MODULE cdev.ops = &hello_fops error = cdev_add (&cdev, devno , 1) if (error) printk (KERN_NOTICE 'Error %d adding char_reg_setup_cdev', error) } struct class *my_class static int __init hello_2_init (void) { int result dev = MKDEV (hello_major, hello_minor) result = register_chrdev_region (dev, number_of_devices, 'hello') if (result<0) { printk (KERN_WARNING 'hello: can't get major number %d/n', hello_major) return result } char_reg_setup_cdev () /* create your own class under /sysfs */ my_class = class_create(THIS_MODULE, 'my_class') if(IS_ERR(my_class)) { printk('Err: failed in creating class./n') return -1 } /* register your own device in sysfs, and this will cause udev to create corresponding device node */ device_create( my_class, NULL, MKDEV(hello_major, 0), 'hello' '%d', 0 ) printk (KERN_INFO 'Registered character driver/n') return 0 } static void __exit hello_2_exit (void) { dev_t devno = MKDEV (hello_major, hello_minor) cdev_del (&cdev) device_destroy(my_class, MKDEV(adc_major, 0)) //delete device node under /dev class_destroy(my_class) //delete class created by us unregister_chrdev_region (devno, number_of_devices) printk (KERN_INFO 'char driver cleaned up/n') } module_init (hello_2_init) module_exit (hello_2_exit)

このようにして、モジュールがロードされた後、デバイスノードhello0は/ devディレクトリにあります。