zoukankan      html  css  js  c++  java
  • 简单字符驱动程序mycdev_globalmem.c

    [root@bogon 桌面]# gedit mycdev_globalmem.c

    #include
    #include
    #include
    #include
    #include
    #include

    MODULE_AUTHOR("Me");
    MODULE_LICENSE("GPL");

    #define GLOBALMEM_SIZE 0x1000
    #define GLOBALMEM_MAJOR 256

    static int globalmem_major = GLOBALMEM_MAJOR;

    struct globalmem_dev
    {
        struct cdev cdev; /*cdev 结构体*/
        unsigned char mem[255]; /*全局内存*/
    };

    struct globalmem_dev *globalmem_devp;    /*定义设备变量*/


    /*文件打开函数*/
    static int globalmem_open(struct inode *inode, struct file *filp)
    {
        /*将设备结构体指针赋值给文件私有数据指针*/
        filp->private_data = globalmem_devp;
        return 0;
    }

    /*globalmem设备驱动的读函数*/
    static ssize_t globalmem_read(struct file *filp, char __user *buf, size_t size,loff_t *ppos)
    {
        unsigned long p = *ppos;
        unsigned int count = size;
        int ret = 0;
        struct globalmem_dev *dev = filp->private_data; /*获得设备结构体指针*/

        /*分析获取有效的写长度*/
        if (p >= GLOBALMEM_SIZE)
            return count ? -ENXIO: 0;
        if (count > GLOBALMEM_SIZE - p)
            count = GLOBALMEM_SIZE - p;

        /*从内核空间向用户空间写数据*/
        if (copy_to_user(buf, (void*)(dev->mem + p), count))
        {
            ret = -EFAULT;
        }
        else
        {
            *ppos += count;
            ret = count;

            printk(KERN_INFO "read %u bytes(s) from %u ", count, p);
        }

        return ret;
    }

    static ssize_t globalmem_write(struct file *fp, const char __user *buf, size_t size, loff_t *pos)
    {
        return size;
    }

    static int globalmem_release(struct inode *inode, struct file *fp)
    {
        return 0;
    }

    static const struct file_operations globalmem_fops =
    {
        .owner = THIS_MODULE,
        .read = globalmem_read,
        .write = globalmem_write,
        .open = globalmem_open,
        .release = globalmem_release,
    };

    /*初始化并添加cdev结构体的函数*/
    static void globalmem_setup_cdev(struct globalmem_dev *dev, int index)
    {
        int ret;
        int devno = MKDEV(globalmem_major, index);

        cdev_init(&dev->cdev, &globalmem_fops);
        dev->cdev.owner = THIS_MODULE;
        dev->cdev.ops = &globalmem_fops;
        ret = cdev_add(&dev->cdev, devno, 1);
        if(ret){
            printk("adding globalmem error");
        }
    }

    /*模块初始化函数*/
    int globalmem_init(void)
    {
        int result;
        dev_t devno=MKDEV(globalmem_major,0);

        if(globalmem_major)        /*globalmem_major为给定的全局变量,见后面的程序清单*/
        {
            result=register_chrdev_region(devno,1,"globalmem");
        }
        else
        {
            result=alloc_chrdev_region(&devno,0,1,"globalmem");
            globalmem_major=MAJOR(devno);
        }

        if(result<0){
            printk("register globalmem failed.. ");
            return result;
        }else{
            printk("register globalmem success.. ");
        }

        globalmem_devp=kmalloc(sizeof(struct globalmem_dev),GFP_KERNEL);
        if(!globalmem_devp)
        {
            result=-ENOMEM;
            goto fail_malloc;
        }
        memset(globalmem_devp,0,sizeof(struct globalmem_dev));

        memcpy(globalmem_devp->mem, "This is mycdev_globalmem!", sizeof(struct globalmem_dev));

        globalmem_setup_cdev(globalmem_devp,0);
        return 0;

    fail_malloc:
        unregister_chrdev_region(devno,1);
        return result;
    }

    /*模块退出函数*/
    static void __exit globalmem_exit(void)
    {
        cdev_del(&globalmem_devp->cdev);  /*释放struct cdev*/
        kfree(globalmem_devp);            /*释放分配为给 struct globalmem_dev的内存*/
        unregister_chrdev_region(MKDEV(globalmem_major,0), 1); /*释放devno*/
    }

    module_init(globalmem_init);
    module_exit(globalmem_exit);



    [root@bogon 桌面]# gedit Makefile

    obj-m:=mycdev_globalmem.o
    PWD:=$(shell pwd)
    CUR_PATH:=$(shell uname -r)
    KERNEL_PATH:=/usr/src/kernels/$(CUR_PATH)

    all:
        make -C $(KERNEL_PATH) M=$(PWD) modules
    clean:
        make -C $(KERNEL_PATH) M=$(PWD) clean


    [root@bogon 桌面]# gedit mycdev_globalmem_test.c

    #include
    #include
    #include
    #include
    #include

    #define GLOBALMEM_SIZE     0x1000

    int main()
    {
        int testdev;
        int i, ret;
        char buf[GLOBALMEM_SIZE];

        testdev = open("/dev/mycdev_globalmem", O_RDWR);

        if (-1 == testdev) {
            printf("cannot open file. ");
            exit(1);
        }

        if (ret = read(testdev, buf, GLOBALMEM_SIZE) <0) {
            printf("read error! ");
            exit(1);
        }

        printf("%s ", buf);

        close(testdev);

        return 0;
    }


    [root@bogon 桌面]# make

    [root@bogon 桌面]# insmod mycdev_globalmem.ko
    [root@bogon 桌面]# cat /proc/devices
    [root@bogon 桌面]# mknod /dev/mycdev_globalmem c 256 0
    [root@bogon 桌面]# chmod 777 /dev/mycdev_globalmem
    [root@bogon 桌面]# gcc mycdev_globalmem_test.c -o mycdev_globalmem_test
    [root@bogon 桌面]# ./mycdev_globalmem_test
    [root@bogon 桌面]# dmesg
    <script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script>
    阅读(1402) | 评论(0) | 转发(14) |
    给主人留下些什么吧!~~
    评论热议
  • 相关阅读:
    jemeter使用笔记
    webtest mobile + Android / Battery Historian / SoloPi
    script / go / golang
    my live house / air conditioning / dajin / dakin / FTXG50JV2CW
    OS + Centos OS 8 Thinkpad TrackPoint
    network router Gpon
    Mybatisplus 自定义sql 使用条件构造器 多表查询分页
    处理fastJson 序列化时间问题
    js 实现轮播图 超级简单 组件已封装
    Webpack-dev-server的proxy用法
  • 原文地址:https://www.cnblogs.com/ztguang/p/12648077.html
Copyright © 2011-2022 走看看