/************************************************************************************html
*本文为我的学习记录,若有错误,欢迎指正。node
* http://www.cnblogs.com/chen-farsight/p/6154941.html网络
* http://www.javashuo.com/article/p-krtbudse-m.html数据结构
************************************************************************************/函数
(1)手动建立:mknod命令学习
在驱动程序insmod成功以后,经过mknod命令手动建立设备文件至/dev目录下:mknod /dev/xxx c 主设备号 次设备号。("c"表示字符设备、"b"表示块设备、"p"表示网络设备)spa
(2)自动建立设备文件:mdev.net
在设备驱动注册到系统后,调用class_create为该设备在/sys/class目录下建立一个设备类,再调用device_create函数为每一个设备建立对应的设备,并经过uevent机制调用mdev(嵌入式linux由busybox提供)来调用mknod建立设备文件至/dev目录下。指针
struct class和struct device则经过sysfs向用户层提供信息。
class_private是class的私有结构,class经过class_private注册到系统中;device_private是device的私有结构,device经过device_private注册到系统中。注册到系统中也是将相应的数据结构加入到系统已经存在的链表中,可是这些连接的细节并不但愿暴露给用户,也没有必要暴露出来,因此才有private的结构。
//所在文件/kernel/include/linux/device.h //设备类 struct class { const char *name; //设备类名称 struct module *owner;//建立设备类的module struct class_attribute *class_attrs;//设备类属性 struct device_attribute *dev_attrs;//设备属性 struct kobject *dev_kobj;//kobject再sysfs中表明一个目录 ..................... struct class_private *p;//设备类得以注册到系统的链接件 }; //drivers/base/base.h struct class_private { struct klist class_devices;//设备类包含的设备(kobject) .................................. struct class *class;//指向设备类数据结构,即要建立的本级目录信息 };
//所在文件/kernel/include/linux/device.h struct device { struct device *parent; //sysfs/devices/中的父设备 struct device_private *p; //设备得以注册到系统的链接件 struct kobject kobj; //设备目录 const char *init_name; //设备名称 struct bus_type *bus; //设备所属总线 struct device_driver *driver; //设备使用的驱动 struct klist_node knode_class;//链接到设备类的klist struct class *class; //所属设备类 ..................... }; //所在文件/kernel/drivers/base/base.h struct device_private { struct klist klist_children; //链接子设备 struct klist_node knode_parent; //加入到父设备链表 struct klist_node knode_driver; //加入到驱动的设备链表 struct klist_node knode_bus; //加入到总线的链表 struct device *device; //对应设备结构 };
step1:调用class_create函数在/sys/class目录下建立一个设备类。
/* 功能:在/sys/class目录下建立一个目录,目录名是name指定的 参数: struct module *owner - THIS_MODULE const char *name - 设备名 返回值: 成功:class指针 失败: - bool IS_ERR(const void *ptr) 判断是否出错 long PTR_ERR(const void *ptr) 转换错误码 */ struct class *class_create(struct module *owner, const char *name);
step2:调用device_create函数在step1建立的设备类目录下建立具体的设备目录和设备属性文件。
/* 功能: 在class指针指向的目录下再建立一个目录,目录名由const char *fmt, ...指出、并导出设备信息(dev_t) 参数: struct class *cls - class指针 struct device *parent - 父对象,NULL dev_t devt - 设备号 void *drvdata - 驱动私有数据 const char *fmt, ... - fmt是目录名字符串格式,...就是不定参数 返回值: 成功 - device指针 失败 - bool IS_ERR(const void *ptr) 判断是否出错 long PTR_ERR(const void *ptr) 转换错误码 */ struct device *device_create(struct class *cls, struct device *parent, dev_t devt, void *drvdata, const char *fmt, ...);
step3:在/dev建立设备文件(系统自动进行)
step一、step2都是在sysfs文件系统中建立目录或者文件,而应用程序访问的设备文件则须要建立在/dev/目录下。该项工做由mdev完成(需保证根文件系统支持mdev,由busybox配置)。
step1:删除设备类目录下的设备
/* 功能:删除device_create建立的目录 参数: struct class *cls - class指针 dev_t devt - 设备号 */ void device_destroy(struct class *cls, dev_t devt);
step2:删除/sys/class目录下的设备类
/* 功能:删除class指针指向的目录 参数: struct class *cls - class指针 */ void class_destroy(struct class *cls);