分析框图
1.实现流程
先要在内核空间中,注册一个驱动,然后可以通过设备树文件或者是相关的设备的寄存器映射到内核空间的地址获取相关的设备信息,然后通过调用创建设备类相关的API创建一个设备类,创建设备类的内部现象是,通过申请struct class对象并初始化,在用户空间的/sys/class目录下创建一个以设备类名为名字的目录,用于存放设备节点信息的文件,在通过调用创建一个设备对象相关的API创建一个设备对象,申请struct devices对象并初始化,创建存放设备节点信息的文件,将其放在设备类名目录下,在二者都完成之后,内核就会发起hotplug event事件信号,调用hotplug进程通知udev进程,然后udev进程就会通过提交的目录信息和设备节点信息,在/dev目录下创建设备节点。
2.API分析
1.申请设备类(向上提交目录信息)
函数名:struct class * class_create();
功能:申请一个设备类并初始化,向上提交目录信息
参数:
owner:指向当前内核模块自身的一个模块指针,填写THIS_MOULE(相当于C++中的this指针)
name:向上提交的目录名
返回值:成功返回申请struct class对象空间的首地址,失败返回错误码指针。(在内核空间的最顶层会预留4K空间,如果该函数调用失败则会返回一个指向这个4K空间的指针)
通过IS_ERR()这个函数判断返回的指针是否是指向4K预留空间,PRT_ERR()通过错误码指针的得到对应的错误码。
2.销毁目录
void class_destroy(struct class *cls)
功能:销毁目录信息
参数:cls:指向class对象的指针。
无返回值
3.向上提交节点信息
struct device *device_create(struct class *class,struct device *parent,dev_t dev,void *drvdata,const char *fmt,....)
功能:创建一个设备对象,向上提交设备节点信息
参数1:向上提交目录时的类对象指针
参数2:当前申请的对象前的一个节点的地址,填NULL。
参数3:设备号(包括主设备号和次设备号)可以通过这个函数MKDEV(主设备号,次设备号)获取设备号
参数4:申请的device对象的私有数据,填NULL
fmt:向上提交的设备节点名
...:不定长参数(相当于printf中的格式串)
返回值:成功返回申请到的device对象首地址,失败返回错误码指针,指向4k预留空间
4.销毁设备节点信息
void device_destroy(struct class *class,dev_t devt)
功能:销毁设备节点信息
参数:class:向上提交目录时得到的类对象指针
devt:向上提交的设备节点信息时提交的设备号
返回值无;
在创建和销毁时要注意先后顺序,先提交目录信息在提交设备节点信息,而销毁时要先销毁设备节点信息在销毁相关目录。