zoukankan      html  css  js  c++  java
  • MY_FIRSH_MODULE

    模块描述

    将30个字节的内存空间模仿成设备文件。每次读写不超过30个字节。

    模块加载成功之后,需建立设备文件

    mknod /dev/mydev c 231 0

    模块代码

    #include <linux/types.h>     //dev_t,MAJOR,MINOR,MKDEV
    #include <linux/fs.h>        //file_operations,struct file,struct indoe,register
                    //unregister_chrdev,register/alloc/unregister_chrdev_regino,
    #include <linux/cdev.h>      //cdev_alloc,cdev_init,cdev_add,cdev_del
    #include <linux/kernel.h>    //container_of
    #include <linux/slab.h>      //kfree,kmalloc
    #include <linux/errno.h>     //error code 
    #include <linux/module.h>    //MODULE_LICENSE,...
    #include <linux/platform_device.h>    //struct platform_device,struct platform_driver
    #include <asm/uaccess.h>     //copy_from_user,copy_to_user
    
    #define MYMAJOR 231        //静态分配设备号
    
    MODULE_LICENSE("GPL");
    MODULE_AUTHOR("WGY");
    MODULE_DESCRIPTION("MY_FIRST_MODULE");
    
    
    unsigned int count=0;   //记录打开设备的次数
    dev_t devn;             //设备号
    
    struct my_cdev
    {
    	char kerbuf[30];  //分配30个字节的内存空间
    	struct cdev  cd;  //如果这里实例化cd为指针,记得使用前为cd分配空间
    };
    
    
    
    struct my_cdev ex_cdev;   //设备结构
    
    int simple_open(struct inode  * inode,struct file * filp)
    {
    	if(count>=1)   //设备已被打开
    	{
    		printk(KERN_ERR "Device is in use.");
    		return -EBUSY;
    	}
    	count++;    //设备初次打开,加一
    	return 0;
    }
    
    int simple_release(struct inode * inode,struct file * filp)
    {
    	count--;   //关闭设备,计数减一
    	return 0;
    }
    
    ssize_t simple_read(struct file * filp,char __user *usrbuf,size_t count,loff_t * f_pos)
    {
    	if(count>30)   //用户要求读出字符总数超过30个字节
    	{
    		printk(KERN_WARNING "Over the max length of the kernel array");
    		return -1;
    	}
    	
    	//拷贝内核空间的数据到用户空间
    	if(copy_to_user(usrbuf,ex_cdev.kerbuf,count))
    	{
    		return -EFAULT;
    	}
    
    	return count;
    }
    
    ssize_t simple_write(struct file * filp,const char  __user *usrbuf,size_t count,loff_t * f_pos)
    {
    	if(count>30)  //用户写入字符总数超过30个字节
    	{
    		printk(KERN_WARNING "over the max length of the kernel array");
    		return -1;
    	}
    
    	//拷贝用户空间的数据到内核空间
    	if(copy_from_user(ex_cdev.kerbuf,usrbuf,count))
    	{
    		return -EFAULT;
    	}
    
    	return 0;
    }
    
    
    struct file_operations simple_ops=
    {
    	.owner=THIS_MODULE,
    	.read=simple_read,
    	.write=simple_write,
    	.open=simple_open,
    	.release=simple_release,
    };
    
    int  __init simple_init_module(void)
    {
    	int ret,result;
    	
    	devn=MKDEV(MYMAJOR,0);   //获取设备号
    
    	ret=register_chrdev_region(devn,1,"/dev/mydev");  //起始设备号,设备个数,设备名
    	if(ret<0)
    	{
    		printk(KERN_WARNING "failed to alloc a dev number");
    		return ret;
    	}
    
    
    	//直接涉及内核的操作
    	cdev_init(&ex_cdev.cd,&simple_ops);  
    	ex_cdev.cd.owner=THIS_MODULE;
    	result = cdev_add (&ex_cdev.cd, devn, 1);
    	if(result)      
    	{          
    		printk(KERN_NOTICE "Error %d adding DEMO
    ", result);      
    	}
    	printk("success ,good!");
    
    	return 0;
    	
    }
    
    void __exit simple_cleanup_module(void)
    {
    	cdev_del(&ex_cdev.cd);
    	unregister_chrdev_region(devn,1);
    	printk("simple_cleanup_module");
    }
    
    module_init(simple_init_module);
    module_exit(simple_cleanup_module);
    

     应用

    #include <fcntl.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <errno.h>
    
    int main()
    {
    	int fd,ret;
    	char buf[30]={''};
    
    	fd=open("/dev/mydev",O_RDWR|O_NONBLOCK|O_NOCTTY);
    	if(fd<0)
    	{
    		printf("fail to open..");
    		exit(1);
    	}
    	
    	
    	ret=write(fd,"hello",5);   //向设备写入5个字符
    	if(ret<0)
    	{
    		printf("fail to write.. ");
    		exit(1);
    	}
    
    	ret=read(fd,buf,5);     //从设备读入5个字符
    	if(ret<0)
    	{
    		printf("fail to read..");
    		exit(1);
    	}
    
    	printf("string=%s
    ",buf);     //打印从设备读到的字符
    	close(fd);                 //关闭打开的文件
    	return 0;
    	
    }
    
    学习记录,方便复习
  • 相关阅读:
    逆序对的相关问题:bzoj1831,bzoj2431
    bzoj3211,bzoj3038
    hdu 1179最大匹配
    hdu 3038带权并查集
    poj 1733离散化(map)+并查集
    codeforces 369B
    poj 1456
    POJ 1988相对偏移
    poj 1986tarjan模板题
    poj 1330lca模板题离线算法
  • 原文地址:https://www.cnblogs.com/jingjingdidunhe/p/4603284.html
Copyright © 2011-2022 走看看