zoukankan      html  css  js  c++  java
  • 字符驱动框架

    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语言】学习笔记9——结构struct(2)
    WPF dev 获取gridControl筛选后的数据
    WPF DEV dxc:ChartControl 柱状图
    WPF 重写ListBox(透明效果)
    WPF 后台重写 DataTemplate
    WPF 去掉Drag a column header here to group by that column
    c# 对DataTable进行分组group by
    c# ref与out用法
    WPF canvas设置旋转角度和偏移位置
    WPF 流加载
  • 原文地址:https://www.cnblogs.com/MisterXu/p/13407499.html
Copyright © 2011-2022 走看看