zoukankan      html  css  js  c++  java
  • 字符设备模板2

    源代码:

    #include <linux/kernel.h>
    #include <linux/init.h>
    #include <linux/types.h>
    #include <linux/spinlock.h>
    #include <linux/blkdev.h>
    #include <linux/module.h>  
    #include <linux/fs.h>  
    #include <linux/errno.h>  
    #include <linux/mm.h>  
    #include <linux/cdev.h>  
    
    //module_param(mem_major, int, S_IRUGO);  
    
    #define MEMDEV_MAJOR        260     /*预设的mem的主设备号*/  
    #define MEMDEV_NR_DEVS      2       /*设备数*/  
    #define MEMDEV_SIZE         4096  
    #define CHAR_DEV_NAME       "memdev"
      
    static int mem_major = 0; //MEMDEV_MAJOR;  
    
    struct class *pclass = NULL;  
      
    struct cdev my_dev;   
      
    int mem_open(struct inode *inode, struct file *filp)  
    {  
        return 0;   
    }  
      
    int mem_release(struct inode *inode, struct file *filp)  
    {  
        return 0;  
    }  
    
    /*
    'k'为幻数,要按照Linux内核的约定方法为驱动程序选择ioctl编号,
    应该首先看看include/asm/ioctl.h和Documentation/ioctl-number.txt这两个文件.
    
    对幻数的编号千万不能重复定义,如ioctl-number.txt已经说明‘k'的编号已经被占用的范围为:
    'k'    00-0F    linux/spi/spidev.h    conflict!
    'k'    00-05    video/kyro.h        conflict!
    所以我们在这里分别编号为0x1a和0x1b
    */
    #define CMD_MAGIC   'k'
    #define MEM_CMD1    _IO(CMD_MAGIC, 0x1a)
    #define MEM_CMD2    _IO(CMD_MAGIC, 0x1b)
    
    int temp_data = 0;
    
    static int mem_ioctl( struct file *file, unsigned int cmd, unsigned long arg)
    {    
        switch(cmd)
        {
            case MEM_CMD1:
                if(copy_from_user(&temp_data,  (int *)arg, sizeof(int))) 
                    return -EFAULT;
                break;
            
            case MEM_CMD2:
                if(copy_to_user( (int *)arg, &temp_data, sizeof(int))) 
                    return -EFAULT;
                break;
        }
        
        //printk(KERN_NOTICE"ioctl CMD%d done!
    ",temp);    
        return 0;
    }
    
    static const struct file_operations mem_fops =  
    {  
        .owner = THIS_MODULE,  
        .unlocked_ioctl = mem_ioctl,
        .open = mem_open,  
        .release = mem_release,  
    };  
    
    static int memdev_init(void)  
    {  
        int result;  
        int i;  
    
        dev_t devno = MKDEV(mem_major, 0);  
    
        if (mem_major) { /* 静态申请设备号*/  
            result = register_chrdev_region(devno, 2, CHAR_DEV_NAME);  
        } else { /* 动态分配设备号 */  
            result = alloc_chrdev_region(&devno, 0, 2, CHAR_DEV_NAME);  
            mem_major = MAJOR(devno);  
        }   
    
        if (result < 0)  
            return result;  
    
        cdev_init(&my_dev, &mem_fops);  
        my_dev.owner = THIS_MODULE;  
        my_dev.ops = &mem_fops;  
        cdev_add(&my_dev, MKDEV(mem_major, 0), MEMDEV_NR_DEVS);  
    
        pclass = class_create(THIS_MODULE, CHAR_DEV_NAME);  
        if (IS_ERR(pclass))  
        {  
            printk("class_create failed!/n");  
            goto failed;  
        }  
    
        device_create(pclass, NULL, devno, NULL, CHAR_DEV_NAME);  
        return 0;  
    
    failed:   
        cdev_del(&my_dev);
        unregister_chrdev_region(devno, 1);  
        return result;  
    }  
      
    static void memdev_exit(void)  
    {  
        device_destroy(pclass, MKDEV(mem_major, 0));  
        class_destroy(pclass);
        
        cdev_del(&my_dev);
        unregister_chrdev_region(MKDEV(mem_major, 0), 2); 
    }  
      
    MODULE_AUTHOR("derek yi");  
    MODULE_LICENSE("GPL");  
      
    module_init(memdev_init);  
    module_exit(memdev_exit);  

    makefile:

    ifneq ($(KERNELRELEASE),)
    
    obj-m:=memdev.o
    
    else
    
    KERNELDIR:=/lib/modules/$(shell uname -r)/build
    PWD:=$(shell pwd)
    
    default:
        $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
    
    clean:
        rm -rf *.o *.mod.c *.mod.o *.ko
    
    endif

    测试代码:

    #include <stdio.h>  
    #include <fcntl.h>  
    #include <stdlib.h>  
    #include <string.h>  
    #include <sys/types.h>  
    #include <sys/stat.h>
    #include <unistd.h>
    #include <sys/ioctl.h>
    
    #define CMD_MAGIC   'k'
    #define MEM_CMD1    _IO(CMD_MAGIC, 0x1a) // write
    #define MEM_CMD2    _IO(CMD_MAGIC, 0x1b) // read
    
    int main()
    {
        int fd;
        int ret;
        int wdata, rdata;
    
        fd = open("/dev/memdev", O_RDWR);
        if( fd < 0 ) {
            printf("open memdev WRONG!
    ");
            return 0;
        }
    
        ret = ioctl(fd, MEM_CMD2, &rdata);
        printf("ioctl: ret=%d rdata=%d
    ", ret, rdata);
    
        wdata = 42;
        ret = ioctl(fd, MEM_CMD1, &wdata);
    
        ret = ioctl(fd, MEM_CMD2, &rdata);
        printf("ioctl: ret=%d rdata=%d
    ", ret, rdata);
        
        close(fd);
        return 0;
    }
  • 相关阅读:
    tp5项目后台比赛界面
    总结7.21 lavarel视图
    总结7.20 laravel自动验证
    java学习day78--JT项目16(CORS跨域/HttpCLient/jt-sso单点登录)
    java学习day77-JT项目15(Ajax跨域访问/JSONP)
    java学习day77-JT项目15(Redis集群算法/spring boot整合redis集群)
    java学习day76-JT项目14(Redis集群搭建)
    java学习day76-JT项目14(Redis分片机制/哨兵机制)
    检查Linux中发现没有IP
    java学习day75-JT项目13(AOP实现redis缓存/Redis缓存)
  • 原文地址:https://www.cnblogs.com/soul-stone/p/6384602.html
Copyright © 2011-2022 走看看