Linux字符型设备驱动模板,简化开发工作

Posted 太阳德生

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux字符型设备驱动模板,简化开发工作相关的知识,希望对你有一定的参考价值。

       写linux驱动,无法也就那么几类,字符型,块设备型,网络设备型,管道流型等,为了便捷开发,平时积累一些模块确实大有裨益!首先可以先把程序框架给跑起来了,如何就是想办法往里面添东西,这样慢慢做加法,总比一股脑的写出来再慢慢调试编译错误做减法来得实际一些。

        下面就写一个常见的字符型设备驱动,套用一下模板,事半功倍,效率喜人。

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>      /* For platform devices */
#include <linux/cdev.h>
#include <linux/fs.h>

static unsigned int major; /* major number for device */
static struct class *chardev_class;
static struct cdev chardev_cdev;

int chardev_open(struct inode * inode, struct file * filp)
{
    printk("LI  tried to open me\\n");
    return 0;
}

int chardev_release(struct inode * inode, struct file * filp)
{
    printk("LIclosed me\\n");
    return 0;
}

ssize_t chardev_read (struct file *filp, char __user * buf, size_t count,
                                loff_t * offset)
{
    printk("Nothing to read guy\\n");
    return 0;
}

ssize_t chardev_write(struct file * filp, const char __user * buf, size_t count,
                                loff_t * offset)
{
    printk("Can't accept any data !!!\\n");
    return count;
}

struct file_operations chardev_fops = {
    open:       chardev_open,
    release:    chardev_release,
    read:       chardev_read,
    write:      chardev_write,
};

static int my_pdrv_probe (struct platform_device *pdev)
{
        struct device *chardev_device;
    int error;
    dev_t devt = 0;

    /* Get a range of minor numbers (starting with 0) to work with */
    error = alloc_chrdev_region(&devt, 0, 1, "chardev_char");
    if (error < 0) {
        printk("Can't get major number!!!\\n");
        return error;
    }
    major = MAJOR(devt);
    printk("chardev_char major number = %d\\n",major);

    /* Create device class, visible in /sys/class */
    chardev_class = class_create(THIS_MODULE, "chardev_char_class");
    if (IS_ERR(chardev_class)) {
        printk("Error creating sdma test module class!!!\\n");
        unregister_chrdev_region(MKDEV(major, 0), 1);
        return PTR_ERR(chardev_class);
    }

    /* Initialize the char device and tie a file_operations to it */
    cdev_init(&chardev_cdev, &chardev_fops);
    chardev_cdev.owner = THIS_MODULE;
    /* Now make the device live for the users to access */
    cdev_add(&chardev_cdev, devt, 1);

    chardev_device = device_create(chardev_class,
                                &pdev->dev,   /* no parent device */
                                devt,    /* associated dev_t */
                                NULL,   /* no additional data */
                                "chardev_char");  /* device name */

    if (IS_ERR(chardev_device)) {
        printk("Error creating sdma test class device.\\n");
        class_destroy(chardev_class);
        unregister_chrdev_region(devt, 1);
        return -1;
    }

    pr_info("chardev char module loaded!!!\\n");
    return 0;
}

static int my_pdrv_remove(struct platform_device *pdev)
{
    unregister_chrdev_region(MKDEV(major, 0), 1);
    device_destroy(chardev_class, MKDEV(major, 0));
    cdev_del(&chardev_cdev);
    class_destroy(chardev_class);

    pr_info("chardev char module Unloaded\\n");
    return 0;
}

static struct platform_driver mypdrv = {
    .probe      = my_pdrv_probe,
    .remove     = my_pdrv_remove,
    .driver     = {
        .name     = "platform-chardev-char",
        .owner    = THIS_MODULE,
    },
};
module_platform_driver(mypdrv);
MODULE_AUTHOR("Desheng <89660958@qq.com>");
MODULE_LICENSE("GPL");

跟平台挂钩,初始化和退出代码部分module_init(),module_exit(), :

#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/types.h>

static struct platform_device *pdev;

static int __init platform_chardev_char_add(void)
{
    int inst_id = 0; /* instance unique ID: base address would be a good choice */
    pdev = platform_device_alloc("platform-chardev-char", inst_id);
    platform_device_add(pdev);
    printk("platform-chardev-char device added\\n");
    return 0;
}

static void __exit fplatform_chardev_char_put(void)
{
    pr_info("platform-chardev-char device removed\\n");
    platform_device_put(pdev);
}

module_init(platform_chardev_char_add);
module_exit(fplatform_chardev_char_put);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Desheng <89660958@qq.com>");

以上是关于Linux字符型设备驱动模板,简化开发工作的主要内容,如果未能解决你的问题,请参考以下文章

i.MX6ULL驱动开发1——字符设备开发模板

Linux驱动开发MISC

2.字符设备模板

2.字符设备模板

字符设备模板2

2.字符设备模板