2

ARM プラットフォームで GPIO ピンのドライバーを作成しています。私のドライバーは正しく動作し、デバイス ファイルを手動で mknod することで、今まで問題を回避してきました。

私の初期化コード:

static int __init gpio_init (void) {

    void *ptr_error;
    if (register_chrdev(249, "gpio_device", &fops) < 0){
            printk(KERN_INFO "Registering device failed\n");
            return -EINVAL;
    }

    if ((device_class = class_create(THIS_MODULE, "gpio_device"))
                                                    == NULL){
            unregister_chrdev_region(DEV_T, 1);
            printk(KERN_INFO "Class creation failed\n");
            return -EINVAL;
    }
    ptr_error = device_create(device_class, NULL, DEV_T, NULL, "gpio_device");
    if (IS_ERR(ptr_error)){
            class_destroy(device_class);
            unregister_chrdev_region(DEV_T, 1);
            printk(KERN_INFO "Device creation failed\n");
            return -EINVAL;
    }

    cdev_init(&c_dev, &fops);

    if (cdev_add(&c_dev, DEV_T, 1)){
            device_destroy(device_class, DEV_T);
            class_destroy(device_class);
            unregister_chrdev_region(DEV_T, 1);
            printk(KERN_INFO "Cdev add failed\n");
            return -EINVAL;
    }
    printk(KERN_INFO "Guten tag, GPIO driver initialized\n");
    return SUCCESS;

}

ファイル「gpio_device」が /dev に作成されないことを除いて、これはエラーなしで実行されます。

ARM 用にカーネル 2.6.39.4 にクロス コンパイルしています。(arm-linux-gcc を使用)

私が理解しているように、device_createは/dev ファイルを作成する必要があります。

4

2 に答える 2

3

私はあなたのコードを実行しようとしましたが、いくつかの間違いを見つけました:

  • に登録したらregister_chrdev()、 で登録を解除する必要がありますunregister_chrdev()。またはunregister_chrdev_region()で行われた登録を登録解除するために使用されます。alloc_chrdev_region()register_chrdev_region()

  • 指定されたメジャーのマイナー番号 0 ~ 255をregister_chrdev()登録し、それぞれのデフォルト構造をセットアップするため、 &cdevを処理する必要はありません。cdev_init()cdev_add()

  • IS_ERR& PTR_ERRfor class_create()&device_create()を使用してエラーをチェックする必要がありますPTR_ERR。これは、リターン ポインターをエラー コードにキャストするためです。

詳細については、Char Device Registrationを参照してください。

私が言及した変更を適用した後、 はなし/dev/gpio_deviceで作成されmknodます:

int init_module(void)
{   
    void *ptr_error;
    struct cdev* c_dev;
    int result=0;

    /* register_chrdev */
    result=register_chrdev(my_major, "gpio_device", &fops);
    if (result < 0)
    {
    printk(KERN_INFO "Registering device failed\n");
    return result;
    }

    DEV_T = MKDEV(my_major, my_minor);

    /* class_create */
    device_class = class_create(THIS_MODULE, "gpio_device");
    if (IS_ERR(device_class))
    {
    unregister_chrdev(my_major, "gpio_device");
    printk(KERN_INFO "Class creation failed\n");
    return PTR_ERR(device_class);
    }

    /* device_create */
    ptr_error = device_create(device_class, NULL, DEV_T, NULL, "gpio_device");
    if (IS_ERR(ptr_error))
    {
    class_destroy(device_class);
    unregister_chrdev(my_major, "gpio_device");
    printk(KERN_INFO "Device creation failed\n");
    return PTR_ERR(ptr_error);
    }

    /* //removed
    cdev_init(&c_dev, &fops);
    if (cdev_add(&c_dev, DEV_T, 1)){
    device_destroy(device_class, DEV_T);
    class_destroy(device_class);
    unregister_chrdev_region(DEV_T, 1);
    printk(KERN_INFO "Cdev add failed\n");
    return -EINVAL;
    }*/

    printk(KERN_INFO "Guten tag, GPIO driver initialized\n");
    return SUCCESS;
}
于 2012-08-02T06:49:06.750 に答える
1

私はここで何が起こっているのかを理解しました。BuildRoot を使用してカスタム Linux を作成していますが、udev デバイス ファイル管理システムをコンパイルしたことがわかりました。

だからこそ、これは機能しません。

于 2012-09-13T18:16:44.780 に答える