LINUX驱动之platform驱动模型

本文主要介绍了Linux 2.6版本引入的platform驱动模型,它是一种虚拟总线,用于连接平台设备和驱动。平台设备(platform_device)和平台驱动(platform_driver)通过总线进行绑定。在初始化时,platform_bus_init函数注册了总线,并在用户空间生成对应的文件结构。设备和驱动通过name匹配,probe函数负责设备探测、初始化和资源分配。platform_device_register和platform_driver_register分别用于注册设备和驱动,通过比较设备和驱动的name字段进行匹配。在设备注册过程中,涉及设备资源的描述和管理,当设备和驱动匹配成功后,调用probe函数进行设备操作。
摘要由CSDN通过智能技术生成

1.前言

从Linux2.6开始linux加入一套驱动管理和注册机制-—platform平台总线驱动模型,platform平台总线是一条虚拟总线,platform_device为相应的设备,platform_driver为相应的驱动,在这种设备模型中,需关心总线,设备和驱动这3个实体,总线将设备和驱动绑定.在系统每注册一个设备的时候,会寻找与之匹配的驱动,相反的,在系统每注册一个驱动的时候,会寻找与之匹配的设备,而匹配由总线完成,所谓的platform_device并不是与字符设备,块设备和网络设备并列的概念,而是Linux系统提供的一种附加手段,这样的好处就是开发者可以将相对稳定不变的驱动driver独立起来,可以通过总线bus来桥接与之匹配的设备device.设备device只需要提供与硬件相关的底层硬件的配置,如io,中断等(也就是分离思想,而输入子系统是分层思想),如果设备的参数变了,或者更改了同类的设备,那么只需要修改数据,二不需要修改代码,就能驱动设备了.
设备驱动模型的框架如下图所示
在这里插入图片描述
bus:
总线作为主机和外设的连接通道,有些总线是比较规范的,形成了很多协议.如PCI,USB,1394,IIC等.任何设备都可以选择合适的总线连接到主机.当然主机也可能就是CPU本身.
driver:
驱动程序是在CPU运行时,提供操作的软件接口.所有的设备必须有与之配套驱动程序才能正常工作.一个驱动程序可以驱动多个类似或者完全不同的设备,driver部分的代码是比较稳定的代码
device:
设备就是连接在总线上的物理实体.设备是有功能之分的.具有相同功能的设备被归到一个类(CLASS中).如音频设备(和声音相关的都算),输入设备(鼠标,键盘,游戏杆等),device部分的代码是与硬件相关的代码

2.深入分析

2.1platform模块初始化

struct bus_type platform_bus_type = {
   
	.name		= "platform",
	.dev_attrs	= platform_dev_attrs,
	.match		= platform_match,
	.uevent		= platform_uevent,
	.suspend	= platform_suspend,
	.suspend_late	= platform_suspend_late,
	.resume_early	= platform_resume_early,
	.resume		= platform_resume,
};

int __init platform_bus_init(void)
{
   
	int error;

	error = device_register(&platform_bus);
	if (error)
		return error;
	error =  bus_register(&platform_bus_type);
	if (error)
		device_unregister(&platform_bus);
	return error;
}

platform模板的初始化由platform_bus_init函数完成的,该函数在内核启动阶段被调用,可以看出该函数在启动阶段就注册了总线(platform_bus_type), bus_register函数调用后,就会在用户空间生成platform相关文件(拓扑结构),sys/bus/platform/devices里用来存放的是platform设备,/sys/bus/platform/drivers里用来存放的是platform驱动.我们先关注下bus_register总线注册函数传入的参数的数据结构,往下看

struct bus_type {
     
    const char      *name;;/*总线类型名称*/  
    struct bus_attribute    *bus_attrs;/*总线属性*/  
    struct device_attribute *dev_attrs;/*该总线上所有设备的默认属性*/  
    struct driver_attribute *drv_attrs;/*该总线上所有驱动的默认属性*/  
    int (*match)(struct device *dev, struct device_driver *drv);//驱动匹配函数  
    int (*uevent)(struct device *dev, struct kobj_uevent_env *env);// 添加环境变量  
    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 dev_pm_ops *pm;// 设备电源管理  
    struct bus_type_private *p;//私有数据。完全由驱动核心初始化并使用。  
};  

由此可见bus_register(&platform_bus_type)注册了名字为"platform"的总线,设置了总线属性,添加环境变量等等…我们重点关注下platform_match和platform_probe,platform_match是驱动匹配函数,判定设备和驱动是否匹配,是总线体系相关的.驱动核心通过match来完成匹配,每当有设备添加到总线时,驱动核心遍历总线上的驱动链表查找设备驱动,每当有驱动添加到总线时,驱动核心遍历总线上的设备链表查找驱动可操控的设备,当前,match一般只执行总线特定的匹配处理,而在probe中,probe执行设备相关的匹配探测、设备初始化、资源分配等,对于一次遍历匹配而言,如果match和probe均成功,则结束匹配成功,如果match成功而probe失配,继续遍历查找匹配,如果遍历结束而没有找到成功的匹配,对于驱动而言表示没有可操控设备,对于设备而言表示没有适当的驱动.
在这里插入图片描述
往下看

static int 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值