驱动模块之字符设备 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