互斥体字符设备Demo

本文介绍了一个简单的Linux字符设备驱动程序的实现过程。该驱动通过注册字符设备和创建设备文件来提供用户空间接口,并实现了基本的读取功能。此外,还介绍了如何使用互斥锁保护共享数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#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");
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Linux老A

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值