字符设备驱动框架编写流程如下:
(1)创建并注册设备号
1—创建设备号dev_t
static int hello_major = 250; //主设备号
static int hello_minor = 0; //次设备号
dev_t devno = MKDEV(hello_major, hello_minor);
2—申请设备号
ret = register_chrdev_region(devno, number_of_device, "hello");
if (ret < 0) {
printk("failed from register_chrdev_region\n");
return ret;
}
3—释放设备号
unregister_chrdev_region(devno, 1);
(2)设置操作集合ops
定义file_operations
struct file_operations hello_ops = {
.owner = THIS_MODULE,
};
(3)注册字符设备结构体cdev
1、定义
a、struct cdev cdev; ----推荐
b、struct cdev *cdev;
cdev = cdev_alloc();
2、初始化
cdev_init(&cdev, &hello_ops);
cdev.owner = THIS_MODULES;
3、字符设备注册
cdev_add(&cdev, devno, 1);
4、字符设备的注销
cdev_del(&cdev);
程序如下:
#include < linux/module.h>
#include < linux/kernel.h>
#include < linux/init.h>
#include < linux/fs.h>
#include < linux/cdev.h>
MODULE_LICENSE ("GPL");
int hello_major = 250;
int hello_minor = 0;
int number_of_devices = 1;
struct cdev cdev;
dev_t dev = 0;
struct file_operations hello_fops = {
.owner = THIS_MODULE
};
static void char_reg_setup_cdev (void)
{
int error, devno = MKDEV (hello_major, hello_minor);
cdev_init (&cdev, &hello_fops);
cdev.owner = THIS_MODULE;
cdev.ops = &hello_fops;
error = cdev_add (&cdev, devno , 1);
if (error)
printk (KERN_NOTICE "Error %d adding char_reg_setup_cdev", error);
}
static int __init hello_2_init (void)
{
int result;
dev = MKDEV (hello_major, hello_minor);
result = register_chrdev_region (dev, number_of_devices, "hello");
if (result< 0) {
printk (KERN_WARNING "hello: can't get major number %d\n", hello_major);
return result;
}
char_reg_setup_cdev ();
printk (KERN_INFO "Registered character driver\n");
return 0;
}
static void __exit hello_2_exit (void)
{
dev_t devno = MKDEV (hello_major, hello_minor);
cdev_del (&cdev);
unregister_chrdev_region (devno, number_of_devices);
printk (KERN_INFO "char driver cleaned up\n");
}
module_init (hello_2_init);
module_exit (hello_2_exit);