1

プラットフォームデバイスドライバとキャラクタデバイスインタフェースとの間のリンクアップを理解し、デバイス固有のデータ構造にデータを格納することに苦労しています。プラットフォーム固有のデータ構造プラットフォームドライバとキャラクタデバイスインタフェース

私は自分のデバイスに関連するデータの構造体の維持トラックを作成し、その後、プローブ機能でデバイス構造体に追加します。

dev_set_drvdata(dev, data_struct); 

私もdata_structのグローバルコピーを保持します。

私はmmap()にできるようにその他のデバイスを登録し、ioctl()コマンドでデバイスにアクセスします。このデバイスのdata_structにアクセスしたい場合は、現在グローバルコピーでアクセスしています。別の方法は、inodeまたはfileポインターを介してデバイスの構造体に格納されているデータにアクセスするのですか?

私は現在、デバイスのインスタンスを1つだけ許可していますが、同じドライバを使用する複数のデバイスが存在する将来の実装では、これを正しく実装しています。

答えて

2

あなたmiscdeviceが初めてオープンされているときに、miscdeviceフレームワークは、(misc_open()機能ともcomment to misc_register()機能を参照してください)struct miscdevicefile->private_dataを設定します。これに依存して、container_of()マクロを使用して、カスタム構造を得るために、ファイル操作でfile->private_dataを使用することができます。もちろん、カスタム構造にはstruct miscdeviceが含まれている必要があります。これを行うためのきれいで一般的に使用される方法はto_*()というヘルパー関数を作成することです。これはfileポインタによってカスタム構造体を取り出して返します。したがって、カスタム構造体my_structを呼び出した場合は、そのヘルパー関数をto_my_struct()と呼びます。

また、プラットフォームドライバを作成する場合は、dev_set_drvdata()の代わりにplatform_set_drvdata()を使用できます。これはあなたのプラットフォームドライバの機能remove()でカスタム構造を得るために必要です。

$ git grep -l --all-match -e 'misc_register(' -e 'platform_device' -e 'file->private_data' -- drivers/ 
:ところで

struct my_struct { 
    struct platform_device *pdev; 
    struct miscdevice mdev; 
}; 

static inline struct my_struct *to_my_struct(struct file *file) 
{ 
    struct miscdevice *miscdev = file->private_data; 

    return container_of(miscdev, struct my_struct, mdev); 
} 

static ssize_t my_read(struct file *file, char __user *buf, size_t count, 
       loff_t *pos) 
{ 
    struct my_struct *my = to_my_struct(file); 

    return simple_read_from_buffer(buf, count, pos, "my text", 7); 
} 

static const struct file_operations my_fops = { 
    .owner = THIS_MODULE, 
    .read = my_read, 
}; 

static int my_probe(struct platform_device *pdev) 
{ 
    struct my_struct *my; 
    int ret; 

    my = devm_kzalloc(&pdev->dev, sizeof(*my), GFP_KERNEL); 
    if (!my) 
     return -ENOMEM; 

    platform_set_drvdata(pdev, my); 
    my->pdev = pdev; 

    my->mdev.minor = MISC_DYNAMIC_MINOR; 
    my->mdev.name = "my"; 
    my->mdev.fops = &my_fops; 
    my->mdev.parent = NULL; 

    ret = misc_register(&my->mdev); 
    if (ret) { 
     dev_err(&pdev->dev, "Failed to register miscdev\n"); 
     return ret; 
    } 

    dev_info(&pdev->dev, "Registered\n"); 

    return 0; 
} 

static int my_remove(struct platform_device *pdev) 
{ 
    struct my_struct *my = platform_get_drvdata(pdev); 

    misc_deregister(&my->mdev); 
    dev_info(&pdev->dev, "Unregistered\n"); 

    return 0; 
} 

、あなたはこのように、単にキーワードを使用して、カーネルコードの例を探すことができます:ここで

はすべてが上に説明のための例です。

関連する問題