linux设备模型:扩展篇

Linux设备模型组件:总线 
一、定义:
总线是不同IC器件之间相互通讯的通道;在计算机中,一个总线就是处理器与一个或多个不同外设之间的通讯通道;为了设备模型的目的,所有的设备都通过总线相互连接,甚至当它是一个内部的虚拟总线(如,platform总线);例如,设备模型表示在总线和它们控制的设备之间的实际连接;
常见的总线有:PCI、ISA、EISA、VESA、USB、IIC、IIS、SPI、SCI、CAN、RS-232-C、RS-485、IEEE-488,等等;
Linux设备模型中,一个总线由内核结构体struct bus_type描述;其结构定义如下:
struct bus_type
{
const char*        name;           //总线类型的名称
struct subsystem     subsys;         //该总线所属的子系统subsystem,代表自身---kset
struct kset         drivers;        //该总线所使用的驱动程序的集合
struct kset        devices;        //挂接在该总线上的所有设备的集合
struct klist            klist_devices;  //挂接在该总线上的所有设备所组成的链表
struct klist            klist_drivers;  //该总线所使用的驱动程序所组成的链表
struct bus_attribute*     bus_attrs;      //总线属性
struct device_attribute*  dev_attrs;      //设备属性
struct driver_attribute*  drv_attrs;      //驱动程序属性
//设备驱动程序匹配函数
int  (*match)(struct device* dev, struct device_driver* drv);
//热插拔、即插即用、电源管理,等等事件的处理函数
int  (*uevent)(struct device* dev, char** envp, int num_envp, char* buffer, int buffer_size);
int  (*probe)(struct device* dev);
int  (*remove)(struct device* dev);
void (*shutdown)(struct device* dev);
int  (*suspend)(struct device* dev, pm_message_t state);
int  (*resume)(struct device* dev);
};
每个bus_type对象都对应/sys/bus目录下的一个子目录,如,PCI总线对应于/sys/bus/pci目录;在每个这样的子目录下存在两个子目录:devices和drivers,分别对应于bus_type结构中的devices和drivers成员,其中,devices子目录描述的是连接在该总线上的所有设备,drivers子目录描述的是该总线所使用的所有驱动程序;/sys/bus目录下的所有子目录都类似;
二、相关函数:
1、int bus_register(struct bus_type* bus); //注册函数
2、void bus_unregister(struct bus_type* bus); //注销函数
3、void bus_rescan_devices(struct bus_type* bus); //扫描函数
4、int bus_for_each_dev(struct bus_type* bus, struct device* start, void* data, int (*fn)(struct device*, void*));
   //该函数用于遍历指定总线上的已知设备;
5、int bus_for_each_drv(struct bus_type* bus, struct device_driver* start, void* data, int (*fn)(struct device_driver*, void*));
   //该函数用于遍历指定总线上已知的驱动程序;
6、struct device* bus_find_device(struct bus_type* bus, struct device* start, void* data, int (*match)(struct device*, void*));
   //该函数用于在指定总线上查找指定设备,并返回该设备的指针;
三、总线属性:
Linux设备模型中,几乎每一层都提供一个添加属性的接口,总线层也不例外;
总线层的属性类型定义如下:
struct bus_attribute
{
     struct attribute attr;
     ssize_t (*show)(struct bus_type* bus, char* buf);
     ssize_t (*store)(struct bus_type* bus, const char* buf, size_t count);
};
int bus_create_file(struct bus_type* bus, struct bus_attribute* attr):为指定总线添加属性;
void bus_remove_file(struct bus_type* bus, struct bus_attribute* attr):删除指定总线上的指定属性;
备注:struct bus_type、struct bus_attribute结构均定义在/usr/src/kernels/2.6.18-8.el5-i686/include/linux/device.h文件中;

Linux设备模型组件:设备 
一、定义:
Linux设备模型中,在系统的最底层,每一个设备都由一个struct device对象来描述;struct device结构用于描述设备自身的信息、与其它设备之间的关系、与总线和驱动之间的关系;其定义如下:
struct device
{
struct klist        klist_children;       //设备列表中的子列表
struct klist_node     knode_parent;     //兄弟节点
struct klist_node     knode_driver;         //驱动程序节点
struct klist_node     knode_bus;            //总线节点
struct device*        parent;        //父设备节点,即,当前设备所附着到的设备
struct kobject        kobj;                 //代表当前设备,并连接它到层次中的kobject
char                     bus_id[BUS_ID_SIZE]; //唯一确定这个总线上的设备的字符串,即,总线上设备的位置
struct device_attribute   uevent_attr;
struct device_attribute*  devt_attr;
struct semaphore     sem;      //信号量
struct bus_type*      bus;      //总线类型,即,哪种总线
struct device_driver*   driver;     //这个设备所使用的驱动程序
void*           driver_data;  //一个可能被设备驱动程序所使用的私有数据
void*           platform_data; /* Platform specific data, device core doesn't touch it */
void*           firmware_data;  /* Firmware specific data (e.g. ACPI, BIOS data),reserved for device core*/
struct dev_pm_info    power;
u64*           dma_mask;      /* dma mask (if dma'able device) */
u64            coherent_dma_mask;
struct list_head     dma_pools;     /* dma pools (if dma'ble) */
struct dma_coherent_mem* dma_mem;       /* internal for coherent mem override */
struct list_head     node;        /* class_device migration path */
struct class*       class;       /* optional */
dev_t           devt;        /* dev_t, creates the sysfs "dev" */
void (*release)(struct device* dev);          //释放设备的函数
};
二、相关函数:
int device_register(struct device* dev):设备注册;
void device_unregister(struct device* dev):设备注销;
void device_initialize(struct device* dev):设备初始化;
int device_add(struct device* dev):添加设备到设备模型的层次结构中;
void device_del(struct device* dev):设备模型的层次结构中删除设备;
int device_for_each_child(struct device*, void*, int (*fn)(struct device*, void*)):遍历设备的子列表;
void device_bind_driver(struct device* dev):给设备绑定一个驱动程序;
void device_release_driver(struct device* dev):去掉设备上的驱动程序,即,删除设备与驱动程序之间的绑定关系;
struct device* device_create(struct class* cls, struct device* parent, dev_t devt, char* fmt, ...):创建一个设备;
void device_destroy(struct class* cls, dev_t devt):销毁一个设备;
struct device* get_device(struct device* dev):增加设备的引用计数;
void put_device(struct device* dev):减少设备的引用计数;
三、设备属性:
struct device_attribute
{
     struct attribute attr;
     ssize_t (*show)(struct device* dev, struct device_attribute* attr, char* buf);
     ssize_t (*store)(struct device* dev, struct device_attribute* attr, const char* buf, size_t count);
};
int device_create_file(struct device* dev, struct device_attribute* attr):为指定设备添加属性;
void device_remove_file(struct device* dev, struct device_attribute* attr):删除指定设备上的指定属性;
备注:struct device、struct device_attribute结构均定义在/usr/src/kernels/2.6.18-8.el5-i686/include/linux/device.h文件中;

Linux设备模型组件:驱动 
一、定义:
系统中的每一个硬件设备都由一个驱动程序来管理;内核中使用struct device_driver结构对象来描述一个设备的驱动程序;定义如下:
struct device_driver
{
const char*        name;           //设备驱动程序的名字
struct bus_type*   bus;            //所属的总线
struct completion  unloaded;
struct kobject   kobj;           //内嵌的kobject对象,代表自身
struct klist     klist_devices;  //使用该驱动程序的设备列表,即,该驱动程序所管理的所有设备
struct klist_node  knode_bus;
struct module*     owner;          //所属模块
int (*probe)(struct device* dev);  //设备探测函数
int (*remove)(struct device* dev); //设备移除函数
void (*shutdown)(struct device* dev);
int (*suspend)(struct device* dev, pm_message_t state);
int (*resume)(struct device* dev);
};
二、相关函数:
int driver_register(struct device_driver* drv):驱动程序注册;
void driver_unregister(struct device_driver* drv):驱动程序注销;
struct device_driver* get_driver(struct device_driver* drv):增加驱动程序引用计数;
void put_driver(struct device_driver* drv):减少驱动程序引用计数;
struct device_driver* driver_find(const char* name, struct bus_type* bus):在指定总线上查找指定名字的驱动程序;
三、驱动程序属性:
struct driver_attribute
{
     struct attribute attr;
    ssize_t (*show)(struct device_driver* drv, char* buf);
     ssize_t (*store)(struct device_driver* drv, const char* buf, size_t count);
};
int driver_create_file(struct device_driver* drv, struct driver_attribute* attr); //为指定驱动程序添加属性;
void driver_remove_file(struct device_driver* drv, struct driver_attribute* attr); //删除指定驱动程序上的指定属性;
int driver_for_each_device(struct device_driver* drv, struct device* start, void* data, int (*fn)(struct device*, void*));
//遍历驱动程序所管理的所有设备;
struct device* driver_find_device(struct device_driver* drv, struct device* start, void* data, int (*match)(struct device*, void*));
//查找驱动程序所使用的设备;
备注:struct device_driver、struct driver_attribute结构均定义在/usr/src/kernels/2.6.18-8.el5-i686/include/linux/device.h文件中。

Linux设备模型组件:设备类 
一、定义:
系统中的设备所属的类有结构体struct class对象来描述,用于表示某一类设备,它是一组具有共同属性和功能的设备的抽象体,类似于面向对象中的类的概念;所有的class对象都属于class_subsys子系统,对应于/sys/class目录;
其结构定义如下:
struct class
{
const char*               name;       //类名
struct module*            owner;      //所属模块
struct subsystem          subsys;     //所属子系统subsystem
struct list_head          children;   //属于该class类型的所有子类组成的链表;
struct list_head          devices;  //属于该class类型的所有设备class_device组成的链表;
struct list_head              interfaces;    //类接口class_interface链表
struct semaphore              sem;             /* locks both the children and interfaces lists */
struct class_attribute*        class_attrs;     //类属性
struct class_device_attribute* class_dev_attrs; //类设备属性
int (*uevent)(struct class_device* dev, char** envp, int num_envp, char* buffer, int buffer_size);
void (*release)(struct class_device* dev);
void (*class_release)(struct class* class);
};

int class_register(struct class *cls); //类注册;
void class_unregister(struct class *cls); //类注销;
二、设备类属性:
struct class_attribute
{
     struct attribute attr;
     ssize_t (*show)(struct class* cls, char* buf);
     ssize_t (*store)(struct class*, const char* buf, size_t count);
};
int class_create_file(struct class* cls, const struct class_attribute* attr); //为指定设备类增加指定属性;
void class_remove_file(struct class* cls, const struct class_attribute* attr); //删除指定设备类上的指定属性;
备注:struct class、struct class_attribute结构均定义在/usr/src/kernels/2.6.18-8.el5-i686/include/linux/device.h文件中;

Linux设备模型组件:类设备 
一、定义:
一个设备类struct class的真正目的是作为一个该类具体实例(设备)的容器使用;一个设备类的具体实例由struct class_device结构来描述;也可以这样理解:struct class类型相当于面向对象系统中的类的概念,而struct class_device类型相当于面向对象系统中的实例对象的概念;只有在应用具体实例对象的时候,它的类才有意义;
类设备struct class_device结构定义如下:
struct class_device
{
struct list_head              node;
struct kobject               kobj;        //内嵌的kobject对象
struct class*                  class;       //所属的设备类class
dev_t                        devt;      //设备编号
struct class_device_attribute* devt_attr;   //类设备属性
struct class_device_attribute  uevent_attr; //类设备事件属性
struct device*                 dev;        //如果存在,则创建到/sys/devices目录下相应入口的符号链接
void*                          class_data; //类私有数据
struct class_device*           parent;     //父设备,即,当前设备所附着到的设备
struct attribute_group**       groups;     /* optional groups */
void (*release)(struct class_device* dev);
int (*uevent)(struct class_device* dev, char** envp, int num_envp, char* buffer, int buffer_size);
char   class_id[BUS_ID_SIZE];               //类唯一标识
};
二、类设备相关函数
int class_device_register(struct class_device* cd); //类设备注册;
void class_device_unregister(struct class_device* cd); //类设备注销;
int class_device_rename(struct class_device* cd, char* new_name); //类设备重命名;
void class_device_initialize(struct class_device* cd); //类设备初始化;
int class_device_add(struct class_device* cd); //把类设备对象加入到设备模型的层次结构中;
void class_device_del(struct class_device* cd); //把类设备对象从设备模型的层次结构中删除;
struct class_device * class_device_get(struct class_device* cd); //给类设备对象增加引用计数;
void class_device_put(struct class_device* cd); //给类设备对象减少引用计数;
备注:每一个设备类class对象都包含一个类设备class_device对象的链表,而每一个类设备class_device对象又表示一个逻辑设备,并通过类设备struct class_device结构中的dev成员(一个指向struce device的指针)关联到一个物理设备上;这样,一个逻辑设备总是对应于一个物理设备;但是,一个物理设备却可能对应多个逻辑设备。
三、类设备属性:
struct class_device_attribute
{
     struct attribute attr;
     ssize_t (*show)(struct class_device* cls, char* buf);
     ssize_t (*store)(struct class_device* cls, const char* buf, size_t count);
};
int class_device_create_file(struct class_device* cd, const struct class_device_attribute* attr); //为指定类设备增加指定属性;
void class_device_remove_file(struct class_device* cd, const struct class_device_attribute* attr); //删除指定类设备上的指定属性;
int class_device_create_bin_file(struct class_device* cd, struct bin_attribute* attr);
void class_device_remove_bin_file(struct class_device* cd, struct bin_attribute* attr);
四、类接口:
当设备加入或离开类时,将引发class_interface中的成员函数被调用;
struct class_interface
{
     struct list_head node;
     struct class*     class; //对应的设备类class
     int (*add)(struct class_device* cd, struct class_interface* ci);     //设备加入时触发
     void (*remove)(struct class_device* cd, struct class_interface* ci); //设备移除时触发
};
int class_interface_register(struct class_interface* ci); //类接口注册;
void class_interface_unregister(struct class_interface* ci); //类接口注销;
struct class* class_create(struct module* owner, char* name); //创建类;
void class_destroy(struct class* cls); //销毁类;
struct class_device *class_device_create(struct class *cls, struct class_device *parent, dev_t devt, struct device *device, char *fmt, ...); //创建类设备
void class_device_destroy(struct class *cls, dev_t devt);//销毁类设备
备注:struct class_device、struct class_device_attribute、struct class_interface结构均定义在/usr/src/kernels/2.6.18-8.el5-i686/include/linux/device.h文件中。

示例代码下载链接:http://download.csdn.net/detail/klcf0220/5865769

Input子系统分析 下载链接:http://download.csdn.net/detail/klcf0220/5874587

posted @ 2013-08-03 23:08  不止所见  阅读(401)  评论(0编辑  收藏  举报