OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4782|回复: 4

新字符设备驱动,设备号自动申请失败

[复制链接]

6

主题

11

帖子

0

精华

新手上路

积分
37
金钱
37
注册时间
2020-6-13
在线时间
5 小时
发表于 2020-8-3 22:57:52 | 显示全部楼层 |阅读模式
7金钱
自己根据视频编写了蜂鸣器的驱动,先用depmod,后modprobe加载驱动,设备号自动申请失败,求大神帮忙看看哪里出问题了,源码如下
#define BEEPDEV_CNT                 1
#define BEEPDEV_NAME                "beep"
#define BEEP_ON                     1
#define BEEP_OFF                    0

struct mybeep_dev {
    dev_t devid;
    int major;
    int minor;
    struct cdev cdev;
    struct class *class;
    struct device *device;
    struct device_node *nd;
    int beep_gpio;
};

struct mybeep_dev mybeep;

static int mybeep_open(struct inode *inode, struct file *filp)
{
    filp->private_data = &mybeep;
    return 0;
}

static ssize_t mybeep_write(struct file *filp, const char __user *buf, size_t cnt, loff_t *offt)
{
    int ret = 0;
    struct mybeep_dev *dev = (struct mybeep_dev *)filp->private_data;
    unsigned char databuff[1];
    unsigned char beep_status;

    ret = copy_from_user(databuff, buf, cnt);
        if(ret < 0) {
                printk("kernel write failed!\r\n");
                return -EFAULT;
        }

    beep_status = databuff[0];

    if(beep_status == BEEP_OFF) {
        gpio_set_value(dev->beep_gpio, 0);
    } else if (beep_status == BEEP_ON) {
        gpio_set_value(dev->beep_gpio, 1);
    }

    return 0;
}

static int mybeep_release(struct inode *inode, struct file *filp)
{

    return 0;
}

static const struct file_operations mybeep_filp = {
    .owner = THIS_MODULE,
    .open = mybeep_open,
    .write = mybeep_write,
    .release = mybeep_release,
};

static int __init mybeep_init(void)
{
    int ret = 0;

    /* init devid */
    if (mybeep.major) {
        mybeep.devid = MKDEV(mybeep.major, 0);
        register_chrdev_region(mybeep.devid, BEEPDEV_CNT, BEEPDEV_NAME);
    } else {
        ret = alloc_chrdev_region(&mybeep.devid, 0, BEEPDEV_CNT, BEEPDEV_NAME);
        if (ret < 0) {
            goto fail_devid;
        }
        mybeep.major = MAJOR(mybeep.devid);
        mybeep.minor = MINOR(mybeep.devid);
        printk("beep major = %d minor = %d\n", mybeep.major, mybeep.minor);
    }

    /* init cdev */
    mybeep.cdev.owner = THIS_MODULE;
    cdev_init(&mybeep.cdev, &mybeep_filp);
    ret = cdev_add(&mybeep.cdev, mybeep.devid, BEEPDEV_CNT);
    if (ret < 0) {
        goto fail_cdev;
    }

    /* create class */
    mybeep.class = class_create(THIS_MODULE, BEEPDEV_NAME);
    if (IS_ERR(mybeep.class)) {
        goto fail_class;
    }

    /* create device */
    mybeep.device = device_create(mybeep.class, NULL, mybeep.devid, NULL, BEEPDEV_NAME);
    if (IS_ERR(mybeep.device)) {
        goto fail_device;
    }


    mybeep.nd = of_find_node_by_path("/beep");
    if (mybeep.nd == NULL) {
        ret = -EINVAL;
        goto fail_findnd;
    }

    mybeep.beep_gpio = of_get_named_gpio(mybeep.nd, "beep-gpio", 0);
    if (mybeep.beep_gpio < 0) {
        ret = -EINVAL;
        goto fail_getgpio;
    }

    ret = gpio_request(mybeep.beep_gpio, "beepgpio");
    if (ret < 0) {
        goto fail_reqgpio;
    }

    ret = gpio_direction_output(mybeep.beep_gpio, 1);
    if (ret < 0) {
        goto fail_setdirevtion;
    }


fail_devid:
    printk("alloc devid failed\r\n");
    unregister_chrdev_region(mybeep.devid, BEEPDEV_CNT);
    return ret;
fail_cdev:
    printk("add cdev failed\r\n");
    unregister_chrdev_region(mybeep.devid, BEEPDEV_CNT);
    return ret;
fail_class:
    printk("create class failed\r\n");
    cdev_del(&mybeep.cdev);
    return PTR_ERR(mybeep.class);
fail_device:
    printk("create device failed\r\n");
    class_destroy(mybeep.class);
    return PTR_ERR(mybeep.device);
fail_findnd:
    printk("not find beep node\r\n");
    device_destroy(mybeep.class, mybeep.devid);
    return ret;
fail_getgpio:
    printk("cant get beep gpio number\r\n");
    return ret;
fail_reqgpio:
    printk("cant request gpio\r\n");
    gpio_free(mybeep.beep_gpio);
    return ret;
fail_setdirevtion:
    printk("set gpio direction failed\r\n");
    return ret;
    return 0;
}

static void __exit mybeep_exit(void)
{
    unregister_chrdev_region(mybeep.devid, BEEPDEV_CNT);
    cdev_del(&mybeep.cdev);
    class_destroy(mybeep.class);
    device_destroy(mybeep.class, mybeep.devid);
    gpio_free(mybeep.beep_gpio);
}

module_init(mybeep_init);
module_exit(mybeep_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("chuixue");

最佳答案

查看完整内容[请看2#楼]

每次都是,后来发现是某个函数传参给错了
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

6

主题

11

帖子

0

精华

新手上路

积分
37
金钱
37
注册时间
2020-6-13
在线时间
5 小时
 楼主| 发表于 2020-8-3 22:57:53 | 显示全部楼层
无忧花开 发表于 2020-8-6 19:33
你每次测试都是这样的情况?只是想知道随机的还是偶然的

每次都是,后来发现是某个函数传参给错了
回复

使用道具 举报

6

主题

11

帖子

0

精华

新手上路

积分
37
金钱
37
注册时间
2020-6-13
在线时间
5 小时
 楼主| 发表于 2020-8-4 20:03:20 | 显示全部楼层
是cdev_add失败,用两次modprobe就可以加载成功,然后调用app可以执行成功,为什么第一次不行第二次可以呢
/lib/modules/4.1.15/0_mytest/3_beep # modprobe mybeep.ko
beep major = 249 minor = 0
add cdev failed
/lib/modules/4.1.15/0_mytest/3_beep # modprobe mybeep.ko
/lib/modules/4.1.15/0_mytest/3_beep # ./beepApp /dev/mybeep 1
/lib/modules/4.1.15/0_mytest/3_beep # ./beepApp /dev/mybeep 0
/lib/modules/4.1.15/0_mytest/3_beep # ./beepApp /dev/mybeep 1
回复

使用道具 举报

0

主题

134

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
301
金钱
301
注册时间
2020-5-8
在线时间
20 小时
发表于 2020-8-6 19:33:51 | 显示全部楼层
你每次测试都是这样的情况?只是想知道随机的还是偶然的
回复

使用道具 举报

0

主题

134

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
301
金钱
301
注册时间
2020-5-8
在线时间
20 小时
发表于 2020-8-14 20:21:13 | 显示全部楼层
吹雪123 发表于 2020-8-13 21:21
每次都是,后来发现是某个函数传参给错了

你可以贴图出来给我看看么
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-24 08:24

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表