平台总线驱动
来源:互联网 发布:知乎公司地址 编辑:程序博客网 时间:2024/05/16 02:53
Linux提出了platform bus(平台总线)的概念,即使用虚拟总线将设备信息和驱动程序进行分离,设备树的提出就是进一步深化这种思想,将设备信息进行更好的整理。
设备被注册到总线上,总线会根据其名字搜索对应的驱动,如果找到将设备信息导入驱动程序并执行驱动;当一个驱动被注册到平台总线的时候,总线也会搜索设备。
设备信息--硬件信息/软件信息
硬件:地址资源,中断资源 struct resource
软件:网卡设备中的MAC地址等,这些信息需要私有数据的形式封装设备对象(一个设备的设备信息是一个对象,一个设备的驱动方法也是一个对象),需要我们自定义结构进行封装。
struct platform_device
id 表示这个platform_device对象表征了几个设备,当多个设备有共用资源的时候(MFD),里面填充相应的设备数量,如果只是一个,填-1
dev 父类对象,我们通常关心里面的platform_data和release,前者是用来存储私有设备信息的,后者是供当这个设备的最后引用被删除时被内核回调
定义好了platform_device 结构体后就可以调用函数 platform_add_devices 或platform_device_register向系统中注册设备,前者可以一次性注册多个平台设备。要注意的是,这里的 platform_device 设备的注册过程必须在相应设备驱动加载之前被调用,即执行注册之前。因为驱动注册时需要匹配内核中所以已注册的设备名。
设备被注册到总线上,总线会根据其名字搜索对应的驱动,如果找到将设备信息导入驱动程序并执行驱动;当一个驱动被注册到平台总线的时候,总线也会搜索设备。
//linux-3.4\include\linux\device.hstruct but_type{ const char *name; const char *dev_name; struct device *dev_root; ... int (*match)(struct device *dev, struct device_driver *drv); int (*probe)(struct device *dev); int (*remove)(struct device *dev); void (*shutdown)(struct device *dev); ... const struct dev_pm_ops *pm;}
//linux-3.4\drivers\base\platform.cstruct bus_type platform_bus_type = {.name= "platform",.dev_attrs= platform_dev_attrs,.match= platform_match,.uevent= platform_uevent,.pm= &platform_dev_pm_ops,};/** * platform_driver_register - register a driver for platform-level devices * @drv: platform driver structure */int platform_driver_register(struct platform_driver *drv){drv->driver.bus = &platform_bus_type;if (drv->probe)drv->driver.probe = platform_drv_probe;if (drv->remove)drv->driver.remove = platform_drv_remove;if (drv->shutdown)drv->driver.shutdown = platform_drv_shutdown;return driver_register(&drv->driver);}
设备信息--硬件信息/软件信息
硬件:地址资源,中断资源 struct resource
软件:网卡设备中的MAC地址等,这些信息需要私有数据的形式封装设备对象(一个设备的设备信息是一个对象,一个设备的驱动方法也是一个对象),需要我们自定义结构进行封装。
struct platform_device
id 表示这个platform_device对象表征了几个设备,当多个设备有共用资源的时候(MFD),里面填充相应的设备数量,如果只是一个,填-1
dev 父类对象,我们通常关心里面的platform_data和release,前者是用来存储私有设备信息的,后者是供当这个设备的最后引用被删除时被内核回调
定义好了platform_device 结构体后就可以调用函数 platform_add_devices 或platform_device_register向系统中注册设备,前者可以一次性注册多个平台设备。要注意的是,这里的 platform_device 设备的注册过程必须在相应设备驱动加载之前被调用,即执行注册之前。因为驱动注册时需要匹配内核中所以已注册的设备名。
在内核初始化时do_basic_setup()->driver_init()->platform_bus_init()初始化platform bus(虚拟总线),设备注册的时候platform_device_register()->platform_device_add()内核把设备挂在虚拟的platform bus下,驱动注册的时候 platform_driver_register()->driver_register()->bus_add_driver()->driver_attach()->bus_for_each_dev() 对每个挂在虚拟的platform bus的设备作 __driver_attach()->driver_match_device()
{return drv->bus->match ? drv->bus->match(dev, drv) : 1;}
driver_probe_device()->really_probe(),如果相符就调用ret = drv->probe(dev);,如果probe成功则绑定该设备到该驱动。
platform_device.hstruct platform_device {const char* name;intid;struct devicedev;u32num_resources;struct resource* resource;const struct platform_device_id*id_entry;/* MFD cell pointer */struct mfd_cell *mfd_cell;/* arch specific additions */struct pdev_archdataarchdata;};ioport.hstruct resource {resource_size_t start;resource_size_t end;const char *name;unsigned long flags;struct resource *parent, *sibling, *child;};device.hstruct device {struct device*parent;struct device_private*p;struct kobject kobj;const char*init_name; /* initial name of the device */const struct device_type *type;struct mutexmutex;/* mutex to synchronize calls to * its driver. */struct bus_type*bus;/* type of bus device is on */struct device_driver *driver;/* which driver has allocated this device */void*platform_data;/* Platform specific data, device core doesn't touch it */struct dev_pm_infopower;struct dev_pm_domain*pm_domain;#ifdef CONFIG_NUMAintnuma_node;/* NUMA node this device is close to */#endifu64*dma_mask;/* dma mask (if dma'able device) */u64coherent_dma_mask;/* Like dma_mask, but for alloc_coherent mappings as not all hardware supports 64 bit addresses for consistent allocations such descriptors. */struct device_dma_parameters *dma_parms;struct list_headdma_pools;/* dma pools (if dma'ble) */struct dma_coherent_mem*dma_mem; /* internal for coherent mem override *//* arch specific additions */struct dev_archdataarchdata;struct device_node*of_node; /* associated device tree node */dev_tdevt;/* dev_t, creates the sysfs "dev" */u32id;/* device instance */spinlock_tdevres_lock;struct list_headdevres_head;struct klist_nodeknode_class;struct class*class;const struct attribute_group **groups;/* optional groups */void(*release)(struct device *dev);};platform_device.hstruct platform_driver {int (*probe)(struct platform_device *);int (*remove)(struct platform_device *);void (*shutdown)(struct platform_device *);int (*suspend)(struct platform_device *, pm_message_t state);int (*resume)(struct platform_device *);struct device_driver driver;const struct platform_device_id *id_table;};device.hstruct device_driver {const char*name;struct bus_type*bus;struct module*owner;const char*mod_name;/* used for built-in modules */bool suppress_bind_attrs;/* disables bind/unbind via sysfs */const struct of_device_id*of_match_table;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);const struct attribute_group **groups;const struct dev_pm_ops *pm;struct driver_private *p;};
阅读全文
0 0
- platform平台总线驱动
- 平台总线驱动模型
- 平台总线驱动设计
- 平台总线设备驱动
- 平台总线驱动
- imx28 leds 平台总线驱动
- 平台总线设备驱动详解
- linux驱动之--平台总线
- 平台总线设备驱动设计
- 4412驱动-平台总线驱动 9th_led_bus_drv_dev
- Linux平台总线驱动设备模型
- Linux平台总线驱动设备模型
- Linux平台总线驱动设备模型
- linux驱动platform平台设备总线
- Linux平台总线驱动设备模型
- Linux平台总线驱动设备模型
- Linux平台总线驱动设备模型
- 平台总线、设备、驱动的学习
- Java实现-跳跃游戏2
- 15款值得推荐的思维导图(心智图 )工具
- InnoDB引擎的索引和存储结构
- 华为的提倡大家学雷锋,绝不让雷锋吃亏
- CS:APP二进制炸弹开篇
- 平台总线驱动
- MySql 模糊查询
- 高通功耗问题分析手段
- Java 静态块 、构造块、构造函数执行顺序
- 多github帐号的SSH key切换
- 一分钟教你知道乐观锁和悲观锁的区别(张高伟)
- 编写时钟 Applet 程序
- difference between clear data and clear cache ? Android
- PCA的数学原理