Linux 总线bus、设备device、驱动device_driver三者之间的关系

本文详细探讨了Linux系统中总线bus、设备device及设备驱动driver三者的关系。总线在Linux中扮演连接设备和驱动的角色,如platform总线服务于没有特定协议的设备。设备device包含基本信息,并与驱动进行匹配。设备驱动driver包含设备操作接口,通过内核提供的函数与设备交互。总结了结构体、匹配和探测函数,阐述了三者如何协同工作。
摘要由CSDN通过智能技术生成

以下内容都为自己理解:

1.总线bus

通常所说的总线都是cpu与设备之间通信的协议,就像两个地方,一个地方住着cpu,一个地方住着设备,总线就相当于CPU通过什么方式到达设备。(就像你要通过一个墓道,就要按照墓主人设计的方式过去,要不就会被暗器杀掉,永远也到达不了)。
但是,Linux里面的总线,我的理解就是连接设备和驱动,不是常规意义上的总线,最简单就是platform总线,它不是一个协议,它就是为了那些没有广义上协议(usb、spi、iic)的设备服务的。
bus的结构体如下所示:

struct bus_type {
   
	const char		*name;            //总线的名字
	const char		*dev_name;
	struct device		*dev_root;
	struct device_attribute	*dev_attrs;	/* use dev_groups instead */
	const struct attribute_group **bus_groups;
	const struct attribute_group **dev_groups;
	const struct attribute_group **drv_groups;

	int (*match)(struct device *dev, struct device_driver *drv);     //匹配设备和驱动的函数
	int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
	int (*probe)(struct device *dev);								//如果设备和驱动匹配成功,则会调用此函数,这个函数由
																	//struct device_driver里面的probe函数实现,bus里面
																	//probe最后会调用device_driver里面的probe函数。
																	//这个函数用来初始化设备。这个函数Linux内核里面已经实现
	int (*remove)(struct device *dev);
	void (*shutdown)(struct device *dev);

	int (*online)(struct device *dev);
	int (*offline)(struct device *dev);

	int (*suspend)(struct device *dev, pm_message_t state);
	int (*resume)(struct device *dev);

	const struct dev_pm_ops *pm;

	const struct iommu_ops *iommu_ops;

	struct subsys_private *p;
	struct lock_class_key lock_key;
};

下面以platform总线为例,讲解总线的注册。

int __init platform_bus_init(void)
{
   
	int error;

	early_platform_cleanup();

	error = device_register(&platform_bus);
	if (error)
		return error;
	error =  bus_register(&platform_bus_type); //这里调用总线的注册函数。
	if (error)
		device_unregister(&platform_bus);
	of_platform_register_reconfig_notifier();
	return error;
}

主要看platform_bus_type结构体

struct bus_type platform_bus_type = {
   
	.name		= "platform",      //总线的名字
	.dev_groups	= platform_dev_groups,
	.match		= platform_match,  //总线的匹配函数
	.uevent		= platform_uevent,	
	.pm		= &platform_dev_pm_ops,
};

platform_match函数原型如下:

static int platform_match(struct device *dev, struct device_driver *drv)
{
   
	------------只看具体的实现-------------
	return (strcmp(pdev->name, drv->name) == 0);
}

从上面可以看出,platform总线是通过设备和驱动的名字来实现匹配的。
内核实现的probe函数如下:

int driver_probe_device(struct device_driver *drv, struct device *dev)
{
   
	int ret = 0;

	if (!device_is_registered(dev))
		return -ENODEV;

	pr_debug("bus: '%s': %s: matched device %s with driver %s\n",
		 drv->bus->name, __func__, dev_name(dev), drv->name);

	pm_runtime_get_suppliers(dev);
	if (dev->parent)
		
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值