ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

Linux下的platform总线概述(草稿)

2021-07-20 21:05:19  阅读:197  来源: 互联网

标签:struct bus 总线 platform Linux device 设备


platform总线的设计目的

platform总线是一种虚拟总线,叫做平台总线。设计这种平台总线的目的,是为了统一管理和注册驱动,它可以把物理上不存在总线的一类设备,用一种平台总线统一把它们管理起来。

常见的总线如USB,SPI,UART,PCI,I2S等总线,是在物理上实实在在存在的总线。Linux系统需要为这种物理上存在的总线设计一种统一管理它们的方法,同时为了不去详细区分某种设备是否有总线,Linux内核设计者就设计了platform总线,它把绝大部分的物理上没有总线的设备,统一用platform总线管理起来。

这样做的好处是,设备(device)端代码的编写者只关心具体的硬件部分,设备共性的部分(稳定不变的部分)被内核设计者完成了,这样降低了驱动编写的难度。

platform平台总线相关定义

platform平台总线相关的定义在文件 drivers/base/platform.c中。这个文件中实现了平台总线架构方面的内容。

两个重要的数据结构体

  • platform_device
    它内嵌一个device结构体。

  • platform_driver
    它内嵌一个device_driver 结构体,

  • 平台总线的驱动结构体:

struct 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; //设备ID表
};
  • 平台总线的设备结构体:
struct platform_device 
{
	const char	* name;      //平台总线中设备的名字,在平台总线下有多个设备,每个设备都有自己的名称
	int		id;              //设备的排序
	struct device	dev;     //所有设备通用的属性
	u32		num_resources;    //设备资源,如IO等一些外设等的个数
	struct resource	* resource; //设备资源的首地址,和上面的个数num_resources一起构成一个数组来表示这个资源
	const struct platform_device_id	*id_entry;  //设备ID表,表示同一种类型的几个设备的ID号,数组表示。
	struct pdev_archdata	archdata; /* arch specific additions *///用户自定义数据,扩展数据
};

注册平台总线驱动的函数:

int platform_driver_register(struct platform_driver *drv)

注册平台总线设备的函数:

int platform_device_register(struct platform_device *pdev)

platform 平台总线工作流程

platform在系统中的注册

系统启动时,在bus中注册platform总线,platform总线是bus总线中的一种总线。如下所示:


[root@li bus]# pwd
/sys/bus
[root@li bus]# ls
hid       mmc       scsi      serio     usb
i2c       platform  sdio      spi
[root@li bus]# 

platform总线的注册函数是 int __init platform_bus_init(void),它是在系统启动时在bus总线中被注册了。

int __init platform_bus_init(void)
{
	int error;
	early_platform_cleanup();
	error = device_register(&platform_bus); //这个函数的注册就会在 /sys/bus目录下出现plarform目录
	if (error)
		return error;
	error =  bus_register(&platform_bus_type); //bus中注册platform总线
	if (error)
		device_unregister(&platform_bus);
	return error;
}

下面的结构体被device_register(&platform_bus)使用用,在/sys/bus中注册platform目录。

struct  device  platform_bus = {.init_name = "platform",};  

下面的结构体被 bus_register(&platform_bus_type)使用,这个结构体中的 .match函数就是用来把驱动和设备进行匹配的函数。

struct  bus_type  platform_bus_type = 
{
	.name		= "platform",
	.dev_attrs	= platform_dev_attrs,
	.match		= platform_match,  //
	.uevent		= platform_uevent, //
	.pm		    = &platform_dev_pm_ops,
};

platform总线是管理着所有platform上的驱动和设备,它的mach函数时刻在检测着驱动和设备的匹配情况,一旦匹配上了,就执行probe函数完成设备的探测。

下面就是 .match函数的实体:

static int platform_match(struct device *dev, struct device_driver *drv)
{
	struct platform_device *pdev = to_platform_device(dev);//由结构体中某个元素的指针,反向推出整个结构体的指针
	struct platform_device *pdrv = to_platform_driver(drv);
	/* match against the id table first */
	if (pdrv->id_table)
		  return platform_match_id(pdrv->id_table, pdev) != NULL; //从ID数组中逐个比较进行匹配设备。
	return (strcmp(pdev->name, drv->name) == 0); /* fall-back to driver name match */
}

platform_match函数的参数本来应该是 platform_device 和 platform_device ,但是为了统一使用 device 和 device_driver 参数,整个函数中就使用了to_platform_device宏进行反向推出 platform_device 和 platform_device 。

bus_type结构体中的 int (*match)(struct device *dev, struct device_driver *drv);是通用的总线探测函数,所以不能确定具体的总线类型(即是USB或者是platform总线等)。所以才用了上面的宏定义进行反向推断出具体的总线类型。

========续待

标签:struct,bus,总线,platform,Linux,device,设备
来源: https://blog.csdn.net/lihuiwen34/article/details/118901100

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有