27.1 前言
字符设备是一种以字节流来存取的设备,查看正在使用的设备驱动可用命令:cat /proc/devices;字符设备文件第一个为c开头,可使用命令:ls –l /dev/* 如下图示:
在老版的Linux内核中,注册一个Linux字符设备需要调用多个函数完成,如下图示:先申请设备号,然后分配字符设备空间,初始化完毕后就添加以完成注册。
在后来内核中,可以直接调用register_chrdev()一个函数,传入对应的参数便可完成字符设备的添加,极大方便了驱动人员的开发编程。
在编写字符设备驱动的时候,一开始我们学习的是,要手动的进行mknod去创建设备节点文件着实会有点小麻烦。在Linux中是有一组函数在驱动代码中直接创建/dev目录下的设备节点的,但要支持这个必须要求系统支持udev,udev名称为用户层的设备管理器,主要用来管理/dev目录下的设备节点,具有热插拔的属性。
自动创建设备文件函数组为:class_create(),device_create(),device_destroy(),class_destroy(),调用上述四个函数便可,完成设备节点的自动创建。
27.2 相关函数说明
register_chrdev(major,devName,fops)
注册字符设备,主设备号填0时,系统自动分别设备号,设备名及fops
unregister_chrdev(major,devName)
注销字符设备
class_create(owner,className)
创建设备类,owner指定所属谁一般为:THIS_MODULE,className类名,返回指向一个类的指针
device_create(*class,parentClass,evID,drvData,*devName)
类指针,NULL,设备ID,驱动私有数据,驱动名
unregister_chrdev(mayjor,devName)
注销字符设备;设备号;设备名
device_destroy(*class,mayjor)
删除class下的设备;major为设备号
class_destroy(*class)
删除class;要删除的class指针
27.3 驱动实例
#include
#include
#include
#include
#include //class_create
#define I_DEVICE_NAME"iTestDev"
static int major;
static struct class *iTest_class;
static struct device *iTest_device;
static int iRead(struct file * file, const char __user * buffer, size_t count, loff_t * ppos)
{
return -1;
}
static const struct file_operations stfops = {
.owner= THIS_MODULE,
.read = iRead,
};
static int __init iTest_Init(void)
{
/* 主设备号设置为0表示由系统自动分配主设备号 */
major = register_chrdev(0, I_DEVICE_NAME, &stfops);
/* 创建iTest_class类 */
iTest_class = class_create(THIS_MODULE, "iTestClass");
/* 在iTest_class类下创建设备,并在/dev/目录下创建iTestDevice节点*/
iTest_device = device_create(iTest_class, NULL, MKDEV(major, 0), NULL, "iTestDevice");
return 0;
}
static void __exit iTest_Exit(void)
{
unregister_chrdev(major, I_DEVICE_NAME);
device_unregister(iTest_device);
class_destroy(iTest_class);
}
module_init(iTest_Init);
module_exit(iTest_Exit);
MODULE_LICENSE("GPL");
Insmod 驱动模块之后,便可以在/dev/目录下看到设备文件节点:/dev/iTestDevice