2

我正在为 ARM 平台上的 GPIO 引脚编写驱动程序。我的驱动程序工作正常,直到现在我通过手动 mknod'ing 设备文件来避免这个问题。

我的初始化代码:

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;

}

除了在 /dev 中没有创建文件“gpio_device”外,这运行没有错误。

我正在将 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()

  • 调用register_chrdev()为给定的主要注册次要编号 0-255,并为每个设置一个默认cdev结构,因此,您不需要处理cdev_init()& cdev_add()

  • 您应该使用IS_ERR& PTR_ERRfor class_create()&检查错误,device_create()因为PTR_ERR将返回指针转换为带有强制转换的错误代码。

您可以在此处阅读更多内容:字符设备注册

应用我提到的修改后,/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 回答