Linux设备模型--设备

Bertha 。 2022-03-26 17:28 387阅读 0赞

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)

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

创建属性

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;

  1. /\* 初始化设备 \*/

strncpy(my_dev.bus_id, “my_dev”, BUS_ID_SIZE);

  1. /\*注册设备\*/

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总线设备。

  1. 测试结果:

![Image 1][]

运行程序:
ls /sys/bus/my_bus/device
my_dev

[Image 1]:

发表评论

表情:
评论列表 (有 0 条评论,387人围观)

还没有评论,来说两句吧...

相关阅读