Bus--device--driver驱动模型源码分析

既然说到了bus device driver驱动模型那当然就要分析一下这三个对应的结构体

BUS结构体

<pre name="code" class="cpp">struct bus_type {
	const char		* name;
	struct module		* owner;
	
	int		(*match)(struct device * dev, struct device_driver * drv);//Bus提供的match函数,无论是device注册还是driver注册都会调用这个函数进行匹配
	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 (*suspend_late)(struct device * dev, pm_message_t state);
	int (*resume_early)(struct device * dev);
	int (*resume)(struct device * dev);

	unsigned int drivers_autoprobe:1;//为什么要用位域,不是说位域同台通用性很差么?
};


 

plantform_device结构体

struct platform_device {
	const char	* name;//这个名字是Bus结构体里面match函数用来将和driver比较的
	u32		id;
	struct device	dev;//device注册过程使用的是这个结构体
	u32		num_resources;//device包含的资源数目
	struct resource	* resource;<span style="font-family: Arial, Helvetica, sans-serif;">//device包含的资源这些完全与硬件相关</span>
};
plantform_device用到的 resource结构体
struct resource {
	resource_size_t start;
	resource_size_t end;
	const char *name;
	unsigned long flags;//系统依靠这个标志位来寻找对应的资源
	struct resource *parent, *sibling, *child;
};

我们可以用下面的方法获取资源结构体中的资源

struct resource		*res;
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);//这里可以依据IORESOURCE_IRQ这个标志找到对应的资源数组

plantform_device提到的device结构体

struct device {
	struct bus_type	* bus;		/* type of bus device is on */
	struct device		*parent;
	struct device_driver *driver;	/* which driver has allocated this device */
};

plantform_driver结构体
struct platform_driver {
	int (*probe)(struct platform_device *);//device和driver被注册时都会调用这个函数
	int (*remove)(struct platform_device *);
	void (*shutdown)(struct platform_device *);
	int (*suspend)(struct platform_device *, pm_message_t state);
	int (*suspend_late)(struct platform_device *, pm_message_t state);
	int (*resume_early)(struct platform_device *);
	int (*resume)(struct platform_device *);
	struct device_driver driver;//这个是driver注册时真正被使用的结构体
};
device_driver结构体
struct device_driver {
	struct bus_type		* bus;
	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);
};

上面的两个重要结构体plantform_driver和plantform_device在注册的时候只是填充了device_driver和device结构体然后向内核注册的

下面分析plantform_driver在内核中的注册流程

platform_driver_register(&<span style="font-family: Arial, Helvetica, sans-serif;">platform_driver </span><span style="font-family: Arial, Helvetica, sans-serif;">);</span>
platform_driver_register(struct platform_driver *drv)
	/*下面填充platform_driver结构体中的device_driver结构体*/
	drv->driver.bus = &platform_bus_type;//这里面有match函数可以按照name来找到对应的device,由此可见bus里面的match是<span style="font-family: Arial, Helvetica, sans-serif;">platform_bus_type统一提供的</span>
	if (drv->probe) //用platform_driver中的probe函数来填充device_driver结构体,后面会依次填充resume,remove等函数
		drv->driver.probe = drv->probe(device *_dev);
	driver_register(&drv->driver);//现在拿填充好的device_driver来注册,后面的工作就交给device_driver来做了
	driver_register(struct device_driver * drv)
		bus_add_driver(drv);
		bus_add_driver(struct device_driver *drv)
			 driver_attach(drv);
				bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);//遍历整个device链表
				bus_for_each_dev(struct bus_type * bus, struct device * start, void * data, int (*fn)(struct device *, void *))
					 struct device * dev;
					 dev = next_device(&i)//把所有的device找出来依次调用fn函数
					 fn(dev, data);///也就是调用了__driver_attach函数
					 __driver_attach(struct device * dev, void * data)
						driver_probe_device(drv, dev);
						driver_probe_device(struct device_driver * drv, struct device * dev)
							if (drv->bus->match && !drv->bus->match(dev, drv))//调用总线上的match函数,对比device和device_driver的名字
								goto done//如果比较成功返回1,失败返回0,也就是说成功后会执行really_probe函数
							really_probe(dev, drv);
							really_probe(struct device *dev, struct device_driver *drv)
								dev->driver = drv;//将device和device_driver放到device结构体中
								driver_sysfs_add(dev)//在系统中将device和device_driver建立一个链接,属于内核文件系统部分?
								drv->probe(dev);//这时就调用到了platform_driver定义的probe函数,哈哈

下面分析plantform_device在内核中的注册流程

platform_device_register(&led_dev);
platform_device_register(struct platform_device * pdev)
	platform_device_add(pdev);
	platform_device_add(struct platform_device *pdev)
		strlcpy(pdev->dev.bus_id, pdev->name, BUS_ID_SIZE);//把name赋值给bus_id
		device_add(&pdev->dev);
		device_add(struct device *dev)
			 device_create_file(dev, &dev->uevent_attr);
			 device_create_file(dev, attr);		//这些都是文件管理部分的细节,貌似会建立什么,不懂
			 sysfs_create_link(&dev->kobj, &dev->class->subsys.kobj,"subsystem");
			 bus_attach_device(dev);
				device_attach(dev);
					 bus_for_each_drv(dev->bus, NULL, dev, __device_attach);
					 bus_for_each_drv(struct bus_type * bus, struct device_driver * start, void * data, int (*fn)(struct device_driver *, void *))
						struct device_driver * drv;
						drv = next_driver(&i)//取出每一个driver,然后调用fn
						  fn(drv, data);//其实也就是调用了下面这个函数
						 __device_attach(struct device_driver * drv, void * data)
							struct device * dev = data;
							driver_probe_device(drv, dev);
								drv->bus->match(dev, drv)//调用总线上的match函数
							really_probe(dev, drv);//适配成功后就调用这个函数
								dev->driver = drv;//将device和device_driver放到device结构体中
								driver_sysfs_add(dev)//在系统中将device和device_driver建立一个链接
								drv->probe(dev);//这时就调用到了plantform_driver定义的probe函数,碰头
		




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值