Chinaunix首页 | 论坛 | 博客
  • 博客访问: 478562
  • 博文数量: 285
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 629
  • 用 户 组: 普通用户
  • 注册时间: 2013-10-14 17:53
个人简介

相信自己,快乐每一天

文章分类

全部博文(285)

分类: LINUX

2013-10-26 10:51:08

原文地址:Linux设备模型--设备 作者:mutes

linux中每个设备由一个struct device描述:
  1. struct device {  
  2.     struct klist        klist_children;  
  3.     struct klist_node   knode_parent;   /* node in sibling list */  
  4.     struct klist_node   knode_driver;  
  5.     struct klist_node   knode_bus;  
  6.     struct device       *parent;  
  7.     struct kobject kobj;  
  8.     char    bus_id[BUS_ID_SIZE];    /* 在总线上唯一标识该设备的字符串position on parent bus */  
  9.     unsigned        uevent_suppress:1;  
  10.     const char      *init_name; /* initial name of the device */  
  11.     struct device_type  *type;  
  12.     struct semaphore    sem;    /* semaphore to synchronize calls to 
  13.                      * its driver. 
  14.                      */  
  15.     struct bus_type *bus;       /*设备所在总线 type of bus device is on */  
  16.     struct device_driver *driver;   /* 管理该设备的驱动which driver has allocated this 
  17.                        device */  
  18.     void        *driver_data;   /* 该设备驱动使用的私有数据成员data private to the driver */  
  19.     void        *platform_data; /* Platform specific data, device 
  20.                        core doesn't touch it */  
  21.     struct dev_pm_info  power;  
  22. #ifdef CONFIG_NUMA  
  23.     int     numa_node;  /* NUMA node this device is close to */  
  24. #endif  
  25.     u64     *dma_mask;  /* dma mask (if dma'able device) */  
  26.     u64     coherent_dma_mask;/* Like dma_mask, but for 
  27.                          alloc_coherent mappings as 
  28.                          not all hardware supports 
  29.                          64 bit addresses for consistent 
  30.                          allocations such descriptors. */  
  31.     struct device_dma_parameters *dma_parms;  
  32.     struct list_head    dma_pools;  /* dma pools (if dma'ble) */  
  33.     struct dma_coherent_mem *dma_mem; /* internal for coherent mem 
  34.                          override */  
  35.     /* arch specific additions */  
  36.     struct dev_archdata archdata;  
  37.     dev_t           devt;   /* dev_t, creates the sysfs "dev" */  
  38.     spinlock_t      devres_lock;  
  39.     struct list_head    devres_head;  
  40.     struct klist_node   knode_class;  
  41.     struct class        *class;  
  42.     struct attribute_group  **groups;   /* optional groups */  
  43.     void    (*release)(struct device *dev);  
  44. };  
  45. struct device_private {  
  46.     struct klist klist_children;  
  47.     struct klist_node knode_parent;  
  48.     struct klist_node knode_driver;  
  49.     struct klist_node knode_bus;  
  50.     struct device *device;  
  51. };  
    设备属性由
    device_attribute描述
  52. struct device_attribute {  
  53.     struct attribute    attr;  
  54.     ssize_t (*show)(struct device *dev, struct device_attribute *attr,  
  55.             char *buf);  
  56.     ssize_t (*store)(struct device *dev, struct device_attribute *attr,  
  57.              const char *buf, size_t count);  
  58. };  
可以看出device结构体中也包含了一个kobject对象
注册一个设备
int device_register(struct device *dev)
删除一个设备
void  device_unregister(struct device *dev)

注意:一条总线本身也是一个设备,也必须按设备注册,见上篇

创建属性
int device_create_file(struct device *dev,struct device_attribute *attr)
删除属性
int device_remove_file(struct device *dev,struct device_attribute *attr)

添加设备例子,添加到前面创建的my_bus总线上:
#include
#include
#include
#include
#include

MODULE_AUTHOR("David Xie");
MODULE_LICENSE("Dual BSD/GPL");

extern struct device my_bus; 
extern struct bus_type my_bus_type;

/* Why need this ?*/
static void my_dev_release(struct device *dev)
}

struct device my_dev = {
.bus = &my_bus_type,//设备所在总线
.parent = &my_bus,//设备父设备,这里就是my_bus总线
.release = my_dev_release,
};

/*
 * Export a simple attribute.
 */
static ssize_t mydev_show(struct device *dev, char *buf)
{
return sprintf(buf, "%s\n", "This is my device!");
}

static DEVICE_ATTR(dev, S_IRUGO, mydev_show, NULL);

static int __init my_device_init(void)
{
int ret = 0;
        
        /* 初始化设备 */
strncpy(my_dev.bus_id, "my_dev", BUS_ID_SIZE);
        
        /*注册设备*/
device_register(&my_dev);
/*创建属性文件*/
device_create_file(&my_dev, &dev_attr_dev);
return ret;

}

static void my_device_exit(void)
{
device_unregister(&my_dev);
}

module_init(my_device_init);
module_exit(my_device_exit);

注册一个bus_id即名字为my_dev的设备,该设备的bus成员指向上一步创建的my_bus_type总线,parent成员指向上一步创建的my_bus总线设备。

         测试结果:

运行程序:
ls 
/sys/bus/my_bus/device
my_dev
阅读(251) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~