
互斥体字符设备Demo
#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;
if(ret<0)
{
printk("ret =%d \n",ret);
return ret;
}
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);
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");
发布日期:2021-05-07 13:26:41
浏览次数:23
分类:原创文章
本文共 3056 字,大约阅读时间需要 10 分钟。
#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");
发表评论
最新留言
感谢大佬
[***.8.128.20]2025年04月12日 03时37分52秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
网络编程系列索引 -- Linux 网络编程索引
2019-03-04
网络编程系列索引 -- JAVA 网络编程系列
2019-03-04
【JDK源码分析系列】ArrayBlockingQueue源码分析
2019-03-04
【网络通信 -- 直播】音视频常见封装格式 -- MEPG2 TS
2019-03-04
【网络通信 -- 直播】音视频常见封装格式 -- FLV
2019-03-04
【C/C++基础进阶系列】C/C++ 对象模型 -- 类基础知识总结(三)
2019-03-04
【C/C++基础进阶系列】C/C++ 对象模型 -- 对象语义
2019-03-04
基于FPGA的HDMI信号采样原理
2019-03-04
Spring 与使用STOMP消息
2019-03-04
AngularJS ng-class、ng-style
2019-03-04
Linux 查看系统语言
2019-03-04
十 一、C语言创建桌面程序:单选按钮、复选框和分组框控件
2019-03-04
Java格式化字符串
2019-03-04
Java Swing JList:列表框组件
2019-03-04
AngularJS $q
2019-03-04
jQuery中的动画
2019-03-04
Linux host命令
2019-03-04
MySql 内容聚合
2019-03-04
MongoDB 查询分析
2019-03-04