互斥体字符设备Demo

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/ioctl.h>
#include <linux/mm.h>
#include <asm/uaccess.h>
#include <linux/blkdev.h>
 
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/kdev_t.h>
#include <linux/slab.h>
#include <linux/string.h>


#include <linux/major.h>
#include <linux/errno.h>
#include <linux/module.h>
#include <linux/seq_file.h>


#include <linux/kobject.h>
#include <linux/kobj_map.h>
#include <linux/cdev.h>
#include <linux/mutex.h>
#include <linux/backing-dev.h>
#include <linux/tty.h> 
 
int CDRIVER_MAJOR=0;
int CDRIVER_MINOR=0;
int count=1;
#define CDRIVER_NAME "simple_chrdev"
struct cdev *simple_cdev;
dev_t simple_dev;
static struct device *dev;
static struct class *simple_class;
 
struct Data_buffer{
struct mutex mutex;
int data;
};


struct Data_buffer *databuffer;


static ssize_t mac_read(struct file *filp, char *buffer, size_t count, loff_t *ppos)
{
    int ret;
    databuffer->data = 0xdc;  

//获取互斥体

mutex_lock(&databuffer->mutex);

//会引起阻塞的拷贝操作

    ret=copy_to_user(buffer, (char *)&databuffer->data, sizeof(databuffer->data)); 
    if(ret<0)
    {
        printk("ret =%d \n",ret);
        return ret;
    }

//释放互斥体

mutex_unlock(&databuffer->mutex);

   return 0;
}


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


 
struct file_operations simple_fops=
{
 .owner=THIS_MODULE,
 .open=mac_open,
 .read=mac_read,
};


 
/* 本代码自动生成了/dev/simple */
static int init_module(void)
{
    int ret;
    printk( KERN_DEBUG "Module skeleton init\n" );
    /*register major and minor*/
    if(CDRIVER_MAJOR!=0)
    {
        simple_dev=MKDEV(CDRIVER_MAJOR,CDRIVER_MINOR);
        ret=register_chrdev_region(simple_dev,count,CDRIVER_NAME);
    }
    else
    {
        /*dynamic assign major*/
        ret=alloc_chrdev_region(&simple_dev,CDRIVER_MINOR,count,CDRIVER_NAME);
        CDRIVER_MAJOR=MAJOR(simple_dev);
    }
    if(ret<0)
    {
        printk(KERN_ERR"cannot get major %d \n",CDRIVER_MAJOR);
        return -1;
    }
    /*register character device driver*/
    simple_cdev=cdev_alloc();
    if(simple_cdev!=NULL)
    {
        cdev_init(simple_cdev,&simple_fops);
        simple_cdev->ops=&simple_fops;
        simple_cdev->owner=THIS_MODULE;
        if(cdev_add(simple_cdev,simple_dev,count)!=0)
        {
            printk(KERN_NOTICE "something wrong when adding simple_cdev!\n");
        }
        else
        {
            printk("success adding simple_cdev!\n");
        }
    }
    else
    {
        printk(KERN_ERR "register simple_dev error!\n");
        return -1;
    }
    simple_class = class_create(THIS_MODULE, "simple");
     
    if (IS_ERR(simple_class))
    {
        printk( KERN_DEBUG "class_create error\n" );
        return -1;
    }
    printk(KERN_ERR "devno is %d \n",simple_dev);


         dev=device_create(simple_class, NULL, simple_dev,NULL,"simple");
 
databuffer = kzalloc(sizeof(struct Data_buffer), GFP_KERNEL);


//初始化一个互斥体

mutex_init(&databuffer->mutex);
    return 0;
}
 
 
static void exit_module(void)
{
    printk( KERN_DEBUG "Module skeleton exit\n" );
    device_destroy(simple_class, simple_dev);
    class_destroy(simple_class);
 
    cdev_del(simple_cdev);
    unregister_chrdev_region(simple_dev,count);
}
 
module_init(init_module);
module_exit(exit_module);


MODULE_DESCRIPTION("a test of char device driver");
MODULE_AUTHOR("Jerry");
MODULE_LICENSE("GPL");

猜你喜欢

转载自blog.csdn.net/linuxarmbiggod/article/details/78902819