实现流程:
①注册驱动,register_chrdev()可以生成设备号,给创建的设备文件
②利用class_create()创建设备类(向上提交目录信息),通过申请struct class对象并初始化,在/sys/class/下创建一个以这个类名命名的目录,用来存放设备信息
API:
struct class * class_create(struct module *owner,const char *name );
功能:申请一个设备类并初始化,向上提交目录信息
参数:
owner:指向当前内核模块自身的一个模块指针,填写THIS_MODULE
name:向上提交的目录名
返回值:成功返回申请的struct class对象空间首地址,失败返回错误码指针
在内核空间最顶层会预留4K空间,当struct class函数调用失败后函数会返回一个指向这4K空间的指针
bool __must_check IS_ERR(__force const void *ptr)
功能:判断指针是否指向4K预留空间
参数:要判断的指针
返回值:如果指着指向4K预留空间返回逻辑真,否则返回逻辑假
long __must_check PTR_ERR(__force const void *ptr)
功能:通过错误码指针得到错误码
③利用device_create()创建该类设备中的一个设备(向上提交设备节点信息),通过申请struct class对象并初始化,在/sys/class/类名/下创建设备节点信息文件
API:
struct device *device_create(struct class *class, struct device *parent,dev_t devt, void *drvdata, const char *fmt, ...)
功能:创建一个设备对象,向上提交设备节点信息
参数:
cls:向上提交目录时得到的类对象指针
parent:当前申请的对象前一个节点的地址,不知道就填 NULL
devt:设备号 主设备号<<20|次设备号
MKDEV(主设备号,次设备号):根据主设备号和次设备号得到设备号
MAJOR(dev):根据设备号获取主设备号
MINOR(dev):根据设备号获取次设备号
dridata:申请的device对象的私有数据,填写NULL
fmt:向上提交的设备节点名
...:不定长参数
返回值:成功返回申请到的device对象首地址,失败返回错误码指针,指向4K预留空间
④两者都完成后,内核自动产生hotplug事件,hotplug会通知udev进程,然后udev进程就会通过提交的目录信息和设备节点信息,在/dev目录下创建设备节点