字符設備驅動框架編寫流程如下:
(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);