Skip to content

Latest commit

 

History

History
211 lines (175 loc) · 4.17 KB

3.1-驱动模块之字符设备.md

File metadata and controls

211 lines (175 loc) · 4.17 KB

驱动模块之字符设备 3 一步一步写驱动模块 3.2 驱动模块之cmos » 驱动模块之字符设备

#include <linux/init.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/cdev.h>

dev_t	scull_dev_num;
struct 	cdev * p_scull_dev;

static int scull_open(struct inode * node ,struct file *filp)
{
	printk(KERN_ALERT"scull open!\n");
	return 0;
}

static ssize_t scull_read(struct file * filp ,char __user * buf,size_t count,loff_t *f_pos)
{
	printk(KERN_ALERT"scull read !\n");
	return 0;
}

static ssize_t scull_write(struct file *filp ,const char __user * buf,size_t count,loff_t * f_pos)
{
	printk(KERN_ALERT "scull write!\n");
	return 0;
}

static int scull_release(struct inode *node ,struct file *filp)
{
	printk(KERN_ALERT"scull release !\n");
	return 0;
}

static const struct file_operations scull_fops =
{
	.owner = THIS_MODULE,
	.open	= scull_open,
	.read	= scull_read,
	.write =  scull_write,
	.release = scull_release,
};

static int __init scull_init(void)
{
	int ret;
	printk(KERN_ALERT "in scull driver \n");
	ret = alloc_chrdev_region(&scull_dev_num,0,1,"scull");

	if(ret < 0)
	{
		printk(KERN_ALERT "alloc_chrdev_region error!\n");
	}

	p_scull_dev = cdev_alloc();
	p_scull_dev->owner = THIS_MODULE;
	p_scull_dev->ops =&scull_fops;
	cdev_add(p_scull_dev,scull_dev_num,1);

	return 0;
}

static void __exit scull_exit(void)
{
	printk(KERN_ALERT"goodbye scull driver\n");
	unregister_chrdev_region(scull_dev_num,1);
	cdev_del(p_scull_dev);
	return ;
}

MODULE_LICENSE("GPL");

module_init(scull_init);
module_exit(scull_exit);
$ ./mmake chardrv.c 
$ sudo insmod chardrv.ko
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(int argc, char * argv[])
{
	int fd;
	fd = open("/dev/scull",O_RDWR);
		
	if(fd < 0)
	{
		perror("open error");
	}

	return EXIT_SUCCESS;
}
$make main
$ cat /proc/devices |grep "scull"
$ sudo mknod /dev/scull c 250 0 
$ sudo ./main
$ dmesg

效果: TODO:效果

在上文中,驱动不能为我们自动的创建设备结点,那么我们能不能让驱动自动的为我们创建设备结点呢? 当然是可以的? 那么在上面的程序的基础上我们作修必:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/device.h>

dev_t	scull_dev_num;
struct 	cdev * p_scull_dev;
struct 	class *p_scull_class;

static int scull_open(struct inode * node ,struct file *filp)
{
	printk(KERN_ALERT"scull open!\n");
	return 0;
}

static ssize_t scull_read(struct file * filp ,char __user * buf,size_t count,loff_t *f_pos)
{
	printk(KERN_ALERT"scull read !\n");
	return 0;
}

static ssize_t scull_write(struct file *filp ,const char __user * buf,size_t count,loff_t * f_pos)
{
	printk(KERN_ALERT "scull write!\n");
	return 0;
}

static int scull_release(struct inode *node ,struct file *filp)
{
	printk(KERN_ALERT"scull release !\n");
	return 0;
}

static const struct file_operations scull_fops =
{
	.owner = THIS_MODULE,
	.open	= scull_open,
	.read	= scull_read,
	.write =  scull_write,
	.release = scull_release,
};

static int __init scull_init(void)
{
	int ret;
	printk(KERN_ALERT "in scull driver \n");
	ret = alloc_chrdev_region(&scull_dev_num,0,1,"scull");

	if(ret < 0)
	{
		printk(KERN_ALERT "alloc_chrdev_region error!\n");
	}

	p_scull_dev = cdev_alloc();
	p_scull_dev->owner = THIS_MODULE;
	p_scull_dev->ops =&scull_fops;
	cdev_add(p_scull_dev,scull_dev_num,1);
	p_scull_class = class_create(THIS_MODULE,"scull_class");

	if(IS_ERR(p_scull_class))
	{
		printk(KERN_ALERT"class create error!\n");
		return -1;
	}

	device_create(p_scull_class,NULL,scull_dev_num,NULL,"scull");
	printk(KERN_ALERT "create device node!\n");
	return 0;

	return 0;
}

static void __exit scull_exit(void)
{
	printk(KERN_ALERT"goodbye scull driver\n");
	unregister_chrdev_region(scull_dev_num,1);
	cdev_del(p_scull_dev);
	device_destroy(p_scull_class,scull_dev_num);
	class_destroy(p_scull_class);
	return ;
}

MODULE_LICENSE("GPL");

module_init(scull_init);
module_exit(scull_exit);
$./mmake chardrv.c
$ sudo insmod chardrv.ko
$./main
$dmesg

效果如下: TODO:

3 一步一步写驱动模块 3.2 驱动模块之cmos