一、platform_bus
总线是处理器和一个或多个设备之间的通道,在设备模型中, 所有的设备都通过总线相连。总线可以相互插入。设备模型展示了总线和它们所控制的设备之间的实际连接。Platform总线是2.6 kernel中最近引入的一种虚拟总线,主要用来管理CPU的片上资源,具有更好的移植性,因此在2.6 kernel中,很多驱动都用platform改写了。
/linux/device.h
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 (*suspend_late)(struct device *dev, pm_message_t state);
int (*resume_early)(struct device *dev);
int (*resume)(struct device *dev);
struct bus_type_private *p;
};
/drivers/base/platform.c
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,
};
总线名称是"platform",其只是bus_type的一种,定义了总线的属性,同时platform_bus_type还有相关操作方法,如挂起、中止、匹配及hotplug事件等。总线bus是联系driver和device的中间枢纽。Device通过所属的bus找到driver,由match操作方法进行匹配。
二、platform_device和device
Plarform device会有一个名字用于driver binding(在注册driver的时候会查找driver的目标设备的bus位置,这个过程称为driver binding),另外IRQ以及地址空间等资源也要给出 。platform_device结构体用来描述设备的名称、资源信息等。
/linux/platform_device.h
struct platform_device {
const char * name; //定义平台设备的名称,此处设备的命名应和相应驱动程序命名一致
int id;
struct device dev;
u32 num_resources;
struct resource * resource; //定义平台设备的资源
};
在这个结构里封装了struct device及struct resource。可知:platform_device由device派生而来,是一种特殊的device.下面来看一下platform_device结构体中最重要的一个成员struct resource * resource。struct resource被定义在
/include/linux /ioport.h中,定义原型如下:
struct resource {
resource_size_t start; //定义资源的起始地址
resource_size_t end; //定义资源的结束地址
const char *name; //定义资源的名称
unsigned long flags; 定义资源的类型,比如MEM,IO,IRQ,DMA类型
struct resource *parent, *sibling, *child;
};
这个结构表示设备所拥有的资源,即I/O端口、I/O映射内存、中断及DMA等。这里的地址指的是物理地址。另外还需要注意platform_device中的device结构,它详细描述了设备的情况,其为所有设备的基类:在/include/linux/device.h中定义了struct device结构。其中包含有所属总线,对应的驱动指针等信息。用于匹配总线上的驱动。
三、device_register和platform_device_register
/drivers/base/core.c
int device_register(struct device *dev)
{
device_initialize(dev);
return device_add(dev);
}
初始化一个设备,然后加入到总线中。
/drivers/base/platform.c
int platform_device_register(struct platform_device *pdev)
{
device_initialize(&pdev->dev);
return platform_device_add(pdev);
}
int platform_device_add(struct platform_device *pdev)
{
int i, ret = 0;
//初始化设备的parent为platform_bus,初始化设备的总线为platform_bus_type。
if (!pdev->dev.parent)
pdev->dev.parent = &platform_bus;
pdev->dev.bus = &platform_bus_type;
if (pdev->id != -1)
snprintf(pdev->dev.bus_id, BUS_ID_SIZE, "%s.%d", pdev->name,
pdev->id);
else
strlcpy(pdev->dev.bus_id, pdev->name, BUS_ID_SIZE);
//设置设备struct device 的bus_id成员,留心这个地方,在以后还需要用到这个的。
for (i = 0; i < pdev->num_resources; i++) {
struct resource *p, *r = &pdev->resource[i];
if (r->name == NULL)
r->name = pdev->dev.bus_id;
p = r->parent;
if (!p) {
if (r->flags & IORESOURCE_MEM)
p = &iomem_resource;
else if (r->flags & IORESOURCE_IO)
p = &ioport_resource;
}
//resources分为两种IORESOURCE_MEM和IORESOURCE_IO
//CPU对外设IO端口物理地址的编址方式有两种:I/O映射方式和内存映射方式
if (p && insert_resource(p, r)) {
printk(KERN_ERR
"%s: failed to claim resource %d/n",
pdev->dev.bus_id, i);
ret = -EBUSY;
goto failed;
}
}
ret = device_add(&pdev->dev);
}
我们看到注册一个platform device分为了两部分,初始化这个platform_device,然后将此platform_device添加到platform总线中。输入参数platform_device可以是静态的全局设备。另外一种机制就是动态申请platform_device_alloc一个platform_device设备,然后通过platform_device_add_resources及platform_device_add_data等添加相关资源和属性。无论哪一种platform_device,最终都将通过platform_device_add注册到platform总线上。
由platform_device_register和platform_device_add的实现可知,device_register()和platform_device_register()都会首先初始化设备,区别在于第二步:其实platform_device_add()包括device_add(),不过要先注册resources,然后将设备挂接到特定的platform总
四、device_driver和platform driver
platform driver是与platform_device对应的驱动模型,驱动编写人员只要将注册必须的数据结构化并调用注册驱动的系统函数就可以了。
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 (*suspend_late)(struct platform_device *, pm_message_t state);
int (*resume_early)(struct platform_device *);
int (*resume)(struct platform_device *);
struct device_driver driver;
};
platform_driver中包含了一个device_driver结构,可见device_driver是platform_driver的基类。
/include/linux/device.h
struct device_driver {
const char *name;
struct bus_type *bus;
struct module *owner;
const char *mod_name; /* used for built-in modules */
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);
struct attribute_group **groups;
struct driver_private *p;
};
device_driver提供了一些操作接口,但其并没有实现,相当于一些虚函数,由派生类platform_driver进行重载,无论何种类型driver都是基于device_driver派生而来的,具体的各种操作都是基于统一的基类接口的,这样就实现了面向对象的设计。需要注意这两个变量:name和owner。其作用主要是为了和相关的platform_device关联起来,owner的作用是说明模块的所有者,驱动程序中一般初始化为THIS_MODULE。device_driver结构中还有一个name变量。platform_driver从字面上来看就知道是设备驱动。内核正是通过这个一致性来为驱动程序找到资源,即
platform_device中的resource。
五、driver_register和platform_driver_register。
int platform_driver_register(struct platform_driver *drv)
{
drv->driver.bus = &platform_bus_type;
/*设置成platform_bus_type这个很重要,因为driver和device是通过bus联系在一起的,具体在本例中是通过 platform_bus_type中注册的回调例程和属性来是实现的, driver与device的匹配就是通过 platform_bus_type注册的回调例程platform_match ()来完成的。*/
if (drv->probe)
drv->driver.probe = platform_drv_probe;
//在really_probe函数中,回调了platform_drv_probe函数
if (drv->remove)
drv->driver.remove = platform_drv_remove;
if (drv->shutdown)
drv->driver.shutdown = platform_drv_shutdown;
if (drv->suspend)
drv->driver.suspend = platform_drv_suspend;
if (drv->resume)
drv->driver.resume = platform_drv_resume;
return driver_register(&drv->driver);
}
不要被上面的platform_drv_XXX吓倒了,它们其实很简单,就是将struct device转换为struct platform_device和struct platform_driver,然后调用platform_driver中的相应接口函数。那为什么不直接调用platform_drv_XXX等接口呢?这就是Linux内核中面向对象的设计思想。
device_driver提供了一些操作接口,但其并没有实现,相当于一些虚函数,由派生类platform_driver进行重载,无论何种类型的 driver都是基于device_driver派生而来的,device_driver中具体的各种操作都是基于统一的基类接口的,这样就实现了面向对象的设计。
/drivers/base/driver.c
driver_register(struct device_driver *drv)调用
bus_add_driver(drv)
将驱动挂接到总线上,通过总线来驱动设备。
如果总线上的driver是自动probe的话,则调用
driver_attach()
将该总线上的driver和device绑定起来
int driver_attach(struct device_driver *drv)
{
return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
}
遍历该总线上的每一个设备,将当前driver和总线上的设备进行match,如果匹配成功,则将设备和driver绑定起来。
这一过程的具体函数调用实现为:
driver_attach->__driver_attach->driver_probe_device(drv, dev)
driver_probe_device函数调用了
driver->bus->match,具体实现为platform_match中简单的进行字符串匹配,这也是我们强调platform_device和platform_driver中的name属性需要一致的原因。
还调用了really_probe函数,在该函数中有如下一段代码
if (dev->bus->probe) {
ret = dev->bus->probe(dev);
if (ret)
goto probe_failed;
} else if (drv->probe) {
ret = drv->probe(dev);
if (ret)
goto probe_failed;
}
如果bus和driver同时具备probe方法,则优先调用总线的probe函数。否则调用device_driver的probe函数,此probe 函数是经过各种类型的driver重载的函数,这就实现了利用基类的统一方法来实现不同的功能。对于platform_driver来说,其就是
static int platform_drv_probe(struct device *_dev)
{
struct platform_driver *drv = to_platform_driver(_dev->driver);
struct platform_device *dev = to_platform_device(_dev);
return drv->probe(dev);
}
然后调用特定platform_driver所定义的操作方法,这个是在定义某个platform_driver时静态指定的操作接口。至此,platform_driver成功挂接到platform bus上了,并与特定的设备实现了绑定,并对设备进行了probe处理。
platform_driver_register在经过match匹配设备和驱动后最终调用了自定义的platform_driver中的probe函数,在该函数中一般会初始化一些资源。
六、bus、device及driver三者之间的关系
在数据结构设计上,总线、设备及驱动三者相互关联。platform device包含device,根据device可以获得相应的bus及driver。
设备添加到总线上后形成一个双向循环链表,根据总线可以获得其上挂接的所有device,进而获得了 platform device。根据device也可以获得驱动该总线上所有设备的相关driver。
platform driver包含driver,根据driver可以获得相应的bus,进而获得bus上所有的device,进一步获得platform device,根据name对driver与platform device进行匹配,匹配成功后将device与相应的driver关联起来,即实现了platform device和platform driver的关联。
匹配成功后调用driver的probe进而调用platform driver的probe,在probe里实现驱动特定的功能。
七、适用于plarform的驱动
platform机制将设备本身的资源注册进内核,由内核统一管理,在驱动程序中使用这些资源时通过platform device提供的标准接口进行申请并使用。这样提高了驱动和资源管理的独立性,这样拥有更好的可移植性。platform机制的本身使用并不复杂,由两部分组成:platform_device和platfrom_driver。Platform driver通过platform bus获取platform_device。通常情况下只要和内核本身运行依赖性不大的外围设备,相对独立的,拥有各自独立的资源(地址总线和IRQs),都可以用
platform_driver来管理,而timer,irq等小系统之内的设备则最好不用platfrom_driver机制。platform_device最大的特定是CPU直接寻址设备的寄存器空间,即使对于其他总线设备,设备本身的寄存器无法通过CPU总线访问,但总线的controller仍然需要通过platform bus来管理。
总之,platfrom_driver的根本目的是为了统一管理系统的外设资源,为驱动程序提供统一的接口来访问系统资源,将驱动和资源分离,提高程序的可移植性。
八、基于platform总线的驱动开发流程
基于Platform总线的驱动开发流程如下:
定义初始化platform bus
定义各种platform devices
注册各种platform devices
定义相关platform driver
注册相关platform driver
操作相关设备 file_operations
九、platform_bus必须在系统注册任何platform driver和platform device之前初始化,那么这是如何实现的呢?
/init/main.c
执行顺序:start_kernel-> rest_init-> kernel_init->do_basic_setup->driver_init->platform_bus_init
void __init driver_init(void)
{
/* These are the core pieces */
devices_init();
buses_init();
classes_init();
firmware_init();
hypervisor_init();
/* These are also core pieces, but must come after the
* core core pieces.
*/
platform_bus_init();
system_bus_init();
cpu_dev_init();
memory_dev_init();
}
static void __init do_basic_setup(void)
{
/* drivers will send hotplug events */
init_workqueues();
usermodehelper_init();
driver_init();
init_irq_proc();
do_initcalls();
}
可以看出platform_bus是在driver_init中初始化的,而所有的平台设备和平台驱动的注册都是在do_initcalls中,滞后于platform_bus的初始化。platform_bus的初始化发生在
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;
}
struct device platform_bus = {
.bus_id = "platform",
};
该函数创建了一个名为 “platform”的设备,后续platform的设备都会以此为parent。在sysfs中表示为:所有platform类型的设备都会添加在 platform_bus所代表的目录下,即 /sys/devices/platform下面。
十、平台设备在linux系统下的实现过程
/arch/arm/plat-s5p/devs.c
/arch/arm/plat-s3c24xx/devs.c
中定义了系统的资源,是一个高度可移植的文件,大部分板级资源都在这里集中定义
/arch/arm/plat-s3c24xx/devs.c
static struct resource s3c_i2c_resource[] = {
[0] = {
.start = S3C24XX_PA_IIC,
.end = S3C24XX_PA_IIC + S3C24XX_SZ_IIC - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_IIC,
.end = IRQ_IIC,
.flags = IORESOURCE_IRQ,
}
};
struct platform_device s3c_device_i2c = {
.name = "s3c2410-i2c",
.id = -1,
.num_resources = ARRAY_SIZE(s3c_i2c_resource),
.resource = s3c_i2c_resource,
};
设备名称为s3c2410-i2c,“-1”只有一个i2c设备,两个资源s3c_i2c_resource,分别为i2c控制器的寄存器空间和中断信息。
注册platform_device
定义了platform_device后,需要添加到系统中,就可以调用函数platform_add_devices。
/arch/arm/mach-s3c2440/mach-smdk2440.c smdk2440_devices将系统资源组织起来,统一注册进内核。
static struct platform_device *smdk2440_devices[] __initdata = {
&s3c_device_usb,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c,
&s3c_device_iis,
};
static void __init smdk2440_machine_init(void)
{
s3c24xx_fb_set_platdata(&smdk2440_fb_info);
platform_add_devices(smdk2440_devices, ARRAY_SIZE(smdk2440_devices));
smdk_machine_init();
}
platform_add_devices(smdk2440_devices, ARRAY_SIZE(smdk2440_devices));将系统所有资源注册进系统,在此之前platform bus需要初始化成功,否则无法将platform devices挂接到platform bus上。为了保证platform driver初始化时,相关platform资源已经注册进系统,smdk2440_machine_init需要很早执行,而其作为平台初始化 init_machine 时,将优先于系统所有驱动的初始化。
其调用顺序如下:
1.平台资源的初始化
smdk2440_machine_init
2.平台总线的初始化
driver_init->platform_bus_init
3.平台设备和平台驱动的总线挂载。
do_initcalls 驱动程序的module_init加载过程在该函数中运行。这里还是以ht9032c_uart.c为例
一般情况下,当进入probe函数后,需要获取设备的资源信息,常用获取资源的函数主要是:
struct resource * platform_get_resource(struct platform_device *dev, unsigned int type, unsigned int num);
根据参数type所指定类型,例如IORESOURCE_MEM,来获取指定的资源。
struct int platform_get_irq(struct platform_device *dev, unsigned int num);
获取资源中的中断号。
struct resource * platform_get_resource_byname(struct platform_device *dev, unsigned int type, char *name);
根据参数name所指定的名称,来获取指定的资源。
int platform_get_irq_byname(struct platform_device *dev, char *name);
根据参数name所指定的名称,来获取资源中的中断号。
此probe函数获取物理IO空间,通过request_mem_region和ioremap等操作物理地址转换成内核中的虚拟地址,初始化I2C控制器,通过platform_get_irq或platform_get_resource得到设备的中断号以后,就可以调用request_irq函数来向系统注册中断,并将此I2C控制器添加到系统中。
相关推荐
LangFuse部署与实践
LangFuse的原理主要是基于可观察性和分析技术来监控和优化低延迟消息(LLM)应用。它提供了一套完整的解决方案,通过收集、处理和分析LLM应用在运行过程中产生的各种数据,来生成实时的、深入的、可操作的见解。通过提供实时的、深入的见解和可视化的跟踪功能,LangFuse使得识别和解决应用性能问题变得更加简单和高效。总的来说,LangFuse的原理是通过综合运用可观察性和分析技术,来提供对LLM应用的全面监控和优化能力。这使得开发者和运维团队能够更加高效地管理和维护他们的应用,从而提升用户体验和业务效益。
platform_bus、device及driver 注册及介绍
在目前常用的bus, driver, device 框架中,这三者的关系及注册是怎么样的呢?让我们一探究竟
AI驱动视频剪辑自动化:cutcli命令行工具重塑工作流
视频剪辑自动化是提升内容生产效率的关键技术,其核心原理在于通过程序化指令替代手动操作,将创意执行过程代码化。这项技术的价值在于能够将创作者从重复性劳动中解放,实现批量化、标准化的视频内容生产,尤其适用于社交媒体运营、产品宣传等高频产出场景。通过封装专业软件(如剪映/CapCut)的底层草稿格式,自动化工具在保证工业级渲染质量的同时,提供了可编辑的中间态,为AI智能体(Agent)与生产工具的结合提供了清晰接口。本文以cutcli为例,深入探讨了如何通过命令行工具和AI助手,构建从自然语言指令到可编辑视频草稿
设备树和Platform架构--4--platform bus概述及其初始化
1 概述 1.1 platform(平台)总线出现背景 Platform总线是Linux设备驱动模型为了保持设备驱动的统一性而虚拟出来的总线。因为对于usb设备、i2c设备、pci设备、spi设备等等,他们与cpu的通信都是直接挂在相应的总线下面与cpu进行数据交互的,但是在嵌入式系统当中,并不是所有的设备都能够归属于这些常见的总线,在嵌入式系统里面,SoC系统中集成的独立的外设控制器...
一个开源的AI数据分析工具,与数据对话,一键生成SQL、图表、表格、报告和智能商业分析。
Wren AI是一个开源的AI智能代理,让用户能够跟数据对话,实现从文本到SQL的转换,还能生成图表、电子表格、报告以及商业智能分析。它支持多种语言,能深入挖掘数据价值,提供智能数据探索功能,通过语义索引和精心设计的界面,让用户无需写代码即可获取洞察。Wren AI采用独特的架构,包含Wren UI、Wren AI Service和Wren Engine三大核心服务,可部署在本地或云端,助力团队高效、安全地解锁数据潜力。
Anaconda详细安装及使用教程(带图文)
Anacond的介绍 Anaconda指的是一个开源的Python发行版本,其包含了conda、Python等180多个科学包及其依赖项。因为包含了大量的科学包,Anaconda的下载文件比较大(约531 MB),如果只需要某些包,或者需要节省带宽或存储空间,也可以使用Miniconda这个较小的发行版(仅包含conda和Python)。 Conda是一个开源的包、环境管理器,可以用于...
platform bus平台总线详解
讲解平台总线(plaform bus)的相关知识:platform_device、platform_driver结构体;驱动编写时的相关API(platform_device_register、platform_get_resource、platform_get_irq、platform_add_devices等);平台设备和驱动是怎么注册进bus中的,以及平台设备的probe是怎么被调用的;platform、bus、deivce/driver之间的联系;平台总线的匹配规则。
LLaMA Factory多卡微调的实战教程(持续更新)
本文主要介绍了LLaMA Factory多卡微调的实战教程(持续更新),希望对学习大语言模型的同学们有所帮助。 文章目录 1. 前言 2. 配置环境 2.1 安装虚拟环境 2.2 安装依赖库 2.3 模型选型与下载 2.4 配置多卡环境 3. 运行代码 3.1 构建训练数据 3.2 修改配置文件 3.3 微调 3.3.1 zero3微调 3.3.2 启动API 3.3.3 模型测试
linux驱动学习-----平台总线(platform bus)
平台总线是一种虚拟总线,相对于SPI,IIC,USB等实际物理总线,平台总线为其他没有标准总线的设备挂载提供了条件,另外平台总线的引入也在当驱动更换平台时提供了方便(只需要修改对应的平台的设备资源配置即可)。 两个重要的结构体:platform_device,platform_driver 驱动编写流程: 1.注册设备(修改平台文件kconfig并配置进内核,测试时可手动注册设备,通过查看 /s...
一个 ABAP 工具,能打印系统里某个用户对 BSP 应用的浏览历史记录
只要一个用户在 SAP ABAP 系统里浏览过 BSP 页面,会留下浏览历史记录。本工具会解析出这些记录,打印出该用户浏览的历史事件,和浏览过的页面名称。
1个PID回路如何连接2个执行器(算法和代码)
我们先看下位置型PID的控制框图:2、PID是基于error的控制 所以反馈信号跳动、干扰非常大的话,对PID的闭环控制影响是非常大的,所以对于反馈信号、一定要抗干扰和滤波处理。3、下图是增量型PID的控制框图:4、一个PID输出回路如何连接2个执行器?(有些系统会设置热阀和冷阀才能满足控制要求)。
platform device/platform driver/platform bus解释整理
Platform Device and Drivers从我们可以了解Platform bus上面的驱动模型接口:platform_device,platform_driver。和PCI和USB这些大结构的总线不同,虚拟总线Platform bus使用最小结构来
02 HCM CPI SF集成-组织集成(一)
将员工主数据和组织数据从SAP Successfactors Employee CentraI复制到SAPERP或SAP S/4HANA,SAP SF CPI HCM集成
Linux驱动之platform_bus、platform_device、platform_driver
概述: 在Linux驱动里面platform通常叫做platform bus,直译过来就是平台总线,实际上,是软件里面虚拟出来的总线,俗称虚拟总线。虚拟总线有什么作用呢?以及怎么用linux虚拟总线子框架?这就是本文要阐述的两个问题。 Platform Bus的作用 简单来说,有以下三个作用: 加载平台资源信息,即将reg(控制器,寄存器地址,memery地址)、interrupts(中断)信...
win10 跳过U8环境检测的IE WebControls.rar
win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。
NTscan扫描工具
ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。
以RTC为例分析linux platform_bus platform_device和platform_driver注册过程
说明:内核版本为linux-2.6.37.1;只分析注册过程,未分析注销过程;水平、篇幅 均有限,部分地方未作深入全面分析;分析过程只保留了与注册相关的代码;分析 顺序依照各部分在内核中的注册顺序platform_bus,paltform_device,platform_driver 进行。 1.platform_bus注册过程 platform_bus相关数据结构: /drive
ET2012新版免狗免安装绿色软件
ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,
Platform驱动设备模型:platform_device, bus, platform_driver三者初始化顺序
背景介绍:本文是基于内核4.19.x,不同内核版本略有不同 由于本人才疏学浅有讲的不对的地方请指正,这也算是个人的一个笔记。 本文概况讲一下platform_device, platform bus, platform_driver三者的注册流程。由于内核版本3.x引入devicetree后,所以这里有必需说一下devicetree在什么时候解析,而又在什么时候创建成platform_device。 先上图: ...
Camera2Demo
在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作
Linux设备模型(5) — platform bus/device/driver
本文有部分借鉴 wowo tech ,感谢作者的无私分享 目录 1、简介 2、Platform 软件架构 3、Platform 模块向其它模块提供的 APIs 3.1、数据结构 3.1.1、platform_device 3.1.2、platform_driver 3.2、APIs 3.2.1、Platform Device 提供的 APIs 3.2.2、Platform...
设备模型、设备与驱动关联的全过程分析 platform_device platform_driver driver bus关系
[cpp] view plaincopy 1. 平台驱动注册过程 具体的目录如下: 关于设备模型、设备与驱动关联的全过程分析。... 1 1.1 at91_i2c_init()函数... 1 1.2 platform_driver_register()函数... 2 1.3 dr
LLVM实站指南:从仓库结构到自定义Pass与后端优化
编译器是现代软件开发的基石,而LLVM作为一套模块化的编译器基础设施,通过前端的语言解析、中间的IR优化以及后端的代码生成,实现了多语言高性能编译的复用机制。其核心设计在于将编译流程拆解为独立阶段,使Rust、Swift等语言都能借助统一的数据结构和算法获得高效的目标代码,同时也为开发者提供了深度定制与二次开发的可能。理解LLVM的工作方式,不仅有助于掌握编译原理在工程中的真实落地,还能在性能调优、工具链构建、领域特定语言开发等场景中发挥实际价值。本文从llvm-project仓库出发,系统梳理了其目录组织
Samsung_tiny4412(驱动笔记10)----mdev,bus,device,driver,platform
/*********************************************************************************** * * mdev,bus,device,driver,platform * * 声明: * 1. ...
基于设备树动态创建的 platform_device和platform_driver 的平台总线(platform bus)匹配机制
对于设备树节点的标准属性,内核把属性放在struct resource和总线设备驱动框架下的platform_device一致,仍可通过platform_get_resource()获取。of_match_table指针指向驱动可支持的设备,将 const struct of_device_id *of_match_table;其中的 compatile="ohhh";其中:内核对device_node(设备树中的节点)→platform_device的处理只是针对满足条件的device_node。
Linux platform 设备驱动匹配机制
Linux 中的总线由...这里最关键的是match()和probe()。match()决定一个 device 和一个 driver 是否匹配。PCI bus 根据 vendor/device id 匹配;USB bus 根据 USB id table 匹配;platform bus 可以根据 Device Tree compatible、ACPI id、platform id table、名字匹配;probe()则是匹配成功后的入口。很多 bus 的probe()
基于platform的总线、设备、驱动模型分析
如I2C总线,I2C总线是集成在SOC内部的,因此总线是跟着平台走到,不同芯片厂商,所使用的I2C控制器不同,引起其驱动也有所不同,但又一个问题,如果不同芯片厂商与相同的I2C设备进行通讯,使这些外围的I2C设备工作起来,如果不对其解耦,那么每一个SOC平台都需要写一个对应的I2C设备驱动,这样耦合性过高,不方便移植。由 3.4 可知 module_init最终会注册一个设备到对应总线的总线设备链表中,再调用platform_driver_register时,即在总线中找到对应的设备,匹配成功。
7944



被折叠的 条评论
为什么被折叠?



