• 字符驱动框架


    include <linux/module.h>

    include <linux/kernel.h>

    include <linux/init.h>

    include <linux/fs.h>

    include <linux/slab.h>

    include <linux/uaccess.h>

    include <linux/io.h>

    include <linux/cdev.h>

    include <linux/device.h>

    define NEWCHR_NAME "chrdevbase"

    define NEWCHR_COUNT 1

    /* 字符设备结构体 /
    struct chrdevbase_dev{
    struct cdev cdev; /
    字符设备 /
    dev_t devid; /
    设备号 */
    struct class class; / 类 */
    struct device device; / 设备 /
    int major; /
    主设备号 /
    int minor; /
    次设备号 */

    };

    struct chrdevbase_dev chrdev; /* 字符设备 */

    static int newchrled_open(struct inode *inode, struct file *filp)
    {
    return 0;
    }

    static int newchrled_release(struct inode *inode, struct file *filp)
    {
    return 0;
    }

    static ssize_t newchrled_write(struct file *filp, const char __user *buf,
    size_t count, loff_t *ppos)
    {
    int retvalue;
    unsigned char databuf[1];

    retvalue = copy_from_user(databuf, buf, count);
    if(retvalue < 0) {
        printk("kernel write failed!
    ");
        return -EFAULT;
    }
    
    return 0;
    

    }

    static const struct file_operations chrdev_fops = {
    .owner = THIS_MODULE,
    .write = newchrled_write,
    .open = newchrled_open,
    .release= newchrled_release,
    };

    /*入口 */
    static int __init chrdevbase_init(void)
    {
    int ret = 0;
    unsigned int val = 0;
    printk("newchrled_init ");

    chrdev.major = 0;    /* 设置为0,表示由系统申请设备号 */
    
    /* 2,注册字符设备 */
    if(chrdev.major){    /* 给定主设备号 */
        chrdev.devid = MKDEV(chrdev.major, 0);
        ret = register_chrdev_region(chrdev.devid, NEWCHRLED_COUNT, NEWCHR_NAME);
    } else {                /* 没有给定主设备号 */
        ret = alloc_chrdev_region(&chrdev.devid, 0, NEWCHRLED_COUNT, NEWCHR_NAME);
        chrdev.major = MAJOR(chrdev.devid);
        chrdev.minor = MINOR(chrdev.devid);
    }
    if(ret < 0) {
        printk("chrdev chrdev_region err!
    ");
        goto fail_devid;
    }
    printk("chrdev major=%d, minor=%d
    ", chrdev.major, chrdev.minor);
    
    /* 3,注册字符设备 */
    chrdev.cdev.owner = THIS_MODULE;
    cdev_init(&chrdev.cdev, &chrdev_fops);
    ret = cdev_add(&chrdev.cdev, chrdev.devid, NEWCHRLED_COUNT);
    if(ret < 0) {
        goto fail_cdev;
    }
    
    /* 4,自动创建设备节点 */
    chrdev.class = class_create(THIS_MODULE, NEWCHR_NAME);
    if (IS_ERR(chrdev.class)) {
        ret = PTR_ERR(chrdev.class);
    	goto fail_class;
    }
    
    chrdev.device = device_create(chrdev.class, NULL,
    		     chrdev.devid, NULL, NEWCHR_NAME);
    if (IS_ERR(chrdev.device)) {
        ret = PTR_ERR(chrdev.device);
        goto fail_device;
    }
    	
    return 0;
    

    fail_device:
    class_destroy(chrdev.class);
    fail_class:
    cdev_del(&chrdev.cdev);
    fail_cdev:
    unregister_chrdev_region(chrdev.devid, NEWCHRLED_COUNT);
    fail_devid:
    return ret;
    }

    /* 出口 */
    static void __exit chrdevbase_exit(void)
    {

    unsigned int val = 0;
    printk("chrdevbase_exit
    ");
    
    /* 1,删除字符设备 */
    cdev_del(&chrdev.cdev);
    
    /* 2,注销设备号 */
    unregister_chrdev_region(chrdev.devid, NEWCHRLED_COUNT);
    
    /* 3,摧毁设备 */
    device_destroy(chrdev.class, chrdev.devid);
    
    /* 4,摧毁类 */
    class_destroy(chrdev.class);
    

    }

    /* 注册和卸载驱动 */
    module_init(chrdevbase_init);
    module_exit(chrdevbase_exit);
    MODULE_LICENSE("GPL");
    MODULE_AUTHOR("Harold.xu");

  • 相关阅读:
    C#分割字符串
    Android中this、super的区别
    Android activity跳转方式
    Android中的各种单位
    Android布局方式_RelativeLayout
    Parallelism , Partitioner
    编译hadoop,spark遇到的问题总结
    scala,spark练习题提高
    元组复杂例子
    sparksql 操作hive
  • 原文地址:https://www.cnblogs.com/MisterXu/p/13407499.html
Copyright © 2020-2023  润新知