platform_bus,platform_driver,platform_bus

Linux的platform设备驱动框架 前面我们讲了设备驱动的分离,并且引出了总线(bus)、驱动(driver)和设备(device)模型,比如 I2C、SPI、USB 等总线。但是在 SOC 中有些外设是没有总线这个概念的,但是又要使用总线、驱动和设备模型该怎么办呢?为了解决此问题,Linux 提出了 platform 这个虚拟总线,相应的就有 platform_driver 和 platform_device。这里的设备和驱动要怎么理解呢?设备是硬件设备的抽象表示。每个设备都有一个设备名称和一组功能。 阅读详情

一、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控制器添加到系统中。








 

platform 与bus device driver模型的关系 学习Linux时相信大家都有听说过如下概念: 字符设备,块设备,网络设备。我已经无法明确界定是什么时候linux开始引入这些设备模型,总之从开始接触2.4 kernel时已经有这些基本类型了。 在Linux2.6内核引入了bus_type、device_driver、device分别描述总线,驱动和设备,这就是所谓的“总线设备驱动模型”。总线是三者联系起来的基础,通过一种总线类型,将设备和驱动 阅读详情

相关推荐

Python实战:5分钟搞定N-CMAPSS航空发动机数据集解析(附完整代码)

本文提供了一份针对N-CMAPSS航空发动机数据集的快速解析实战指南。通过Python的h5py和Pandas库,详细演示了如何高效读取HDF5格式文件、理解数据结构、提取关键特征(如传感器数据与剩余使用寿命RUL),并整合为可用于预测性维护分析的DataFrame,帮助研究者和工程师快速上手这一重要的工业时序数据集。

weixin_29083373的博客 279

platform_bus、device及driver 注册及介绍

在目前常用的bus, driver, device 框架中,这三者的关系及注册是怎么样的呢?让我们一探究竟

保持一颗永远好奇、勇于探索的心 1238

虚拟机扩容——非LVM分区

虚拟机扩容——非LVM分区

ytraister的博客 3905

设备树和Platform架构--4--platform bus概述及其初始化

1 概述 1.1 platform(平台)总线出现背景 Platform总线是Linux设备驱动模型为了保持设备驱动的统一性而虚拟出来的总线。因为对于usb设备、i2c设备、pci设备、spi设备等等,他们与cpu的通信都是直接挂在相应的总线下面与cpu进行数据交互的,但是在嵌入式系统当中,并不是所有的设备都能够归属于这些常见的总线,在嵌入式系统里面,SoC系统中集成的独立的外设控制器...

huofengfeihu的博客 4330

Unity3D Pico VR 手势交互实战:基于MRTK3实现抓握与射线控制

本文针对Pico VR原生手势交互功能不足的问题,提供了基于MRTK3实现高级手势交互的实战解决方案。通过将MRTK3成熟的交互框架与Pico的手势追踪能力相结合,详细讲解了从环境配置、SDK导入、核心适配到真机调试的全流程,帮助开发者高效实现抓握与射线控制等复杂交互,有效提升Pico VR应用的开发效率与体验。

weixin_29011667的博客 391

CAD的.dwg文件导入 ArcGIS:高程分析、坡度分析、坡向分析

CAD的.dwg文件导入 ArcGIS,再进行高程分析、坡度分析、坡向分析。

My_Echo_yM的博客 7237

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之间的联系;平台总线的匹配规则。

caiji0169的博客 2413

深度学习驱动的股票波动率预测:LSTM和Transformer模型的实战解析

股票市场的波动率一直是金融领域关注的焦点之一。波动率预测对于风险管理、期权定价和资产配置至关重要。深度学习模型,如长短时记忆网络(LSTM)和Transformer,已经在时间序列数据分析领域取得了显著的成就。本博客将向您展示如何使用这两种深度学习模型来进行股票波动率预测,提供清晰的思路和相应的Python代码,以帮助您理解和应用这一重要任务。

斌擎科技 974

linux驱动学习-----平台总线(platform bus)

平台总线是一种虚拟总线,相对于SPI,IIC,USB等实际物理总线,平台总线为其他没有标准总线的设备挂载提供了条件,另外平台总线的引入也在当驱动更换平台时提供了方便(只需要修改对应的平台的设备资源配置即可)。 两个重要的结构体:platform_device,platform_driver 驱动编写流程: 1.注册设备(修改平台文件kconfig并配置进内核,测试时可手动注册设备,通过查看 /s...

ms1003的博客 443

基于simulink的自动紧急制动系统(AEB)的功能验证

本文手把手指导使用Simulink构建自动紧急制动系统(AEB)模型,通过五个关键步骤完成功能验证:1)搭建车辆动力学模型;2)设计雷达传感器模型;3)开发基于碰撞时间(TTC)的决策逻辑;4)设计标准化测试场景;5)进行仿真分析。重点讲解了AEB的多级触发机制(预警、辅助制动、自动制动)和核心指标验证方法,包括制动时机判断、减速度性能等。通过典型场景仿真,展示了AEB如何在2.5秒TTC触发预警,1.2秒TTC启动自动制动,有效避免碰撞。文章还展望了行人AEB、传感器融合等进阶研究方向,为自动驾驶安全系统

amy_mhd的博客 267

【乐鑫】唤醒词修改方法

乐鑫科技的语音识别模块(如ESP-SR)支持自定义唤醒词,但需通过官方工具链完成。

以实战经验介绍行业知识 827

platform device/platform driver/platform bus解释整理

Platform Device and Drivers从我们可以了解Platform bus上面的驱动模型接口:platform_device,platform_driver。和PCI和USB这些大结构的总线不同,虚拟总线Platform bus使用最小结构来

lihaoweiV的专栏 1980

如何在 R 中使用 Gamma 分布(附示例)

在统计学中,伽马分布通常用于模拟与等待时间相关的概率。我们可以使用以下函数来处理 R 中的 gamma 分布:dgamma(x, shape, rate) – 找到具有特定形状和速率参数的 gamma 分布的密度函数值。 pgamma(q, shape, rate) – 找到具有特定形状和速率参数的伽马分布的累积密度函数值。 qgamma(p, shape, rate) – 找到具有特定形状和速率参数的 gamma 分布的逆累积密度函数值。 rgamma(n, shape, rate) – 生成 n 个随机

Mrrunsen的博客 4418

Linux驱动之platform_bus、platform_device、platform_driver

概述: 在Linux驱动里面platform通常叫做platform bus,直译过来就是平台总线,实际上,是软件里面虚拟出来的总线,俗称虚拟总线。虚拟总线有什么作用呢?以及怎么用linux虚拟总线子框架?这就是本文要阐述的两个问题。 Platform Bus的作用 简单来说,有以下三个作用: 加载平台资源信息,即将reg(控制器,寄存器地址,memery地址)、interrupts(中断)信...

子木 2807

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

以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

月出皎兮。 佼人僚兮。 舒窈纠兮。 劳心悄兮。 2370

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Platform驱动设备模型:platform_device, bus, platform_driver三者初始化顺序

背景介绍:本文是基于内核4.19.x,不同内核版本略有不同 由于本人才疏学浅有讲的不对的地方请指正,这也算是个人的一个笔记。 本文概况讲一下platform_device, platform bus, platform_driver三者的注册流程。由于内核版本3.x引入devicetree后,所以这里有必需说一下devicetree在什么时候解析,而又在什么时候创建成platform_device。 先上图: ...

1626

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...

StephenZhou 2583

设备模型、设备与驱动关联的全过程分析 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

For Heart 1205

LLVM实站指南:从仓库结构到自定义Pass与后端优化

编译器是现代软件开发的基石,而LLVM作为一套模块化的编译器基础设施,通过前端的语言解析、中间的IR优化以及后端的代码生成,实现了多语言高性能编译的复用机制。其核心设计在于将编译流程拆解为独立阶段,使Rust、Swift等语言都能借助统一的数据结构和算法获得高效的目标代码,同时也为开发者提供了深度定制与二次开发的可能。理解LLVM的工作方式,不仅有助于掌握编译原理在工程中的真实落地,还能在性能调优、工具链构建、领域特定语言开发等场景中发挥实际价值。本文从llvm-project仓库出发,系统梳理了其目录组织

weixin_34391445的博客 332

Samsung_tiny4412(驱动笔记10)----mdev,bus,device,driver,platform

/*********************************************************************************** * * mdev,bus,device,driver,platform * * 声明: * 1. ...

weixin_34190136的博客 154

基于设备树动态创建的 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。

weixin_60725397的博客 886

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()

日常学习记录 364

基于platform的总线、设备、驱动模型分析

如I2C总线,I2C总线是集成在SOC内部的,因此总线是跟着平台走到,不同芯片厂商,所使用的I2C控制器不同,引起其驱动也有所不同,但又一个问题,如果不同芯片厂商与相同的I2C设备进行通讯,使这些外围的I2C设备工作起来,如果不对其解耦,那么每一个SOC平台都需要写一个对应的I2C设备驱动,这样耦合性过高,不方便移植。由 3.4 可知 module_init最终会注册一个设备到对应总线的总线设备链表中,再调用platform_driver_register时,即在总线中找到对应的设备,匹配成功。

jamecer的博客 1158
上一篇: 内核定时器
下一篇: s3c2410时钟信号:FCLK、HCLK和PCLK;clk_get_rate()
xp_super
博客等级 码龄14年 10粉丝 17原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值