概述
#include
#include
#include
#include
#include
#include
#include
MODULE_LICENSE("GPL");
MODULE_AUTHOR("birdthree");
#define MINIOR_NUM 0
#define DEVICE_SUM 1
#define MAJOR_NUM 254
#define MINOR_NUM 0
#define MEMDEV_SIZE 4096
static int scull_open(struct inode *inode, struct file
*filp);
static int scull_release(struct inode *, struct file
*filp);
static ssize_t scull_read(struct file*, char*, size_t,
loff_t*);
static ssize_t scull_write(struct file*, const char*, size_t,
loff_t*);
static int scull_major = MAJOR_NUM;
static int scull_minor = MINOR_NUM;
struct class *my_class;
struct file_operations scull_fops =
{
.owner = THIS_MODULE,
.open = scull_open,
.release = scull_release,
.read = scull_read,
.write = scull_write,
};
struct mem_dev
{
char *data;
unsigned long size;
};
struct scull_dev
{
struct mem_dev *mem_devp;
struct semaphore sem;
struct cdev cdev;
};
struct scull_dev *dev;
dev_t devt;
int scull_var = 0;
static int __init scull_init(void)
{
int ret = 0;
devt = MKDEV(MAJOR_NUM, MINOR_NUM);
dev = kmalloc(sizeof(struct scull_dev ), GFP_KERNEL);
//space
if(alloc_chrdev_region(&devt, scull_minor,
DEVICE_SUM, "scull"))
{
printk("alloc register failure.n");
return -1;
}
else
{
printk("alloc register successfully.n");
}
my_class = class_create(THIS_MODULE,"scull_class"); //class
name:scullclass
if(IS_ERR(my_class))
{
printk("failed in creating class.n");
return -1;
}
device_create(my_class,NULL,devt,NULL,"scull0");
init_MUTEX(&dev->sem);
cdev_init(&dev->cdev,
&scull_fops); //init
dev->cdev.owner = THIS_MODULE;
dev->cdev.ops = &scull_fops;
//relate file_operations
if ((ret = cdev_add(&dev->cdev,
devt, 1))) //acknowledge kernel
{
printk(KERN_NOTICE "Error %d adding scull.n", ret);
return -1;
}
else
printk("scull register success.n");
dev->mem_devp = kmalloc(sizeof(struct mem_dev),
GFP_KERNEL);
if(!dev->mem_devp)
{
printk("wrong kmalloc mem.n");
}
memset(dev->mem_devp, 0, sizeof(struct
mem_dev)); //clear
dev->mem_devp->size =
MEMDEV_SIZE;
dev->mem_devp->data =
kmalloc(MEMDEV_SIZE,GFP_KERNEL);
memset(dev->mem_devp->data, 0,
MEMDEV_SIZE);
return ret;
}
static void __exit scull_exit(void)
{
cdev_del(&dev->cdev);
device_destroy(my_class,devt); //delete device node
first
class_destroy(my_class); //then delete class
kfree(&dev->cdev);
unregister_chrdev_region(devt, 1);
}
static int scull_open(struct inode *inode, struct file
*filp)
{
int ret = 0;
if(down_interruptible(&dev->sem))
return -EBUSY;
dev = container_of(inode->i_cdev,struct
scull_dev,cdev);
filp->private_data = dev;
printk("open success.n");
return ret;
}
static int scull_release(struct inode *inode, struct file
*filp)
{
up(&dev->sem);
printk("release success.n");
return 0;
}
static ssize_t scull_read(struct file *filp, char *buf, size_t
len, loff_t *off)
{
printk("reading...n");
if(copy_to_user(buf, &scull_var,
sizeof(int)))
{
return -EFAULT;
}
return sizeof(int);
}
static ssize_t scull_write(struct file *filp, const char *buf,
size_t len, loff_t *off)
{
printk("writing...n");
if(copy_from_user(&scull_var, buf,
sizeof(int)))
{
return -EFAULT;
}
return sizeof(int);
}
module_init(scull_init);
module_exit(scull_exit);
最后
以上就是喜悦网络为你收集整理的linux 字符设备 节点,Linux字符设备驱动(自动创建设备节点,互斥信号实现)的全部内容,希望文章能够帮你解决linux 字符设备 节点,Linux字符设备驱动(自动创建设备节点,互斥信号实现)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复