平台总线设备驱动模型——基础知识
来源:互联网 发布:seo推广学院招聘 编辑:程序博客网 时间:2024/06/13 12:47
平台总线设备驱动程序采用了分层分离的机制,我们先简述一下其大体上的原理,然后在从具体代码出发进行分析。
大体原理:在内核中存在平台设备总线,我们要把设备挂载到总线设备列表中,同时也要把驱动挂在到总线驱动列表中,但是相匹配的设备和驱动的名字要保持一致,因为总线会根据设备和驱动的名字是否一致,来决定他们是否匹配,一旦设备和驱动匹配起来,就会调用驱动程序里的probe函数进行处理。
代码分析,以/dirvers/mtd/nand/s3c2410.c为例来分析:
platform_driver_register(&s3c2410_nand_driver);//驱动名为s3c2410-nand drv->driver.bus = &platform_bus_type;//platform_bus_type里存在match函数,待会会分析 driver_register(&drv->driver); bus_add_driver(drv);//将驱动添加到平台总线驱动列表中我们搜索名“s3c2410-nand”的设备,最终在/arch/arm/plat-s3c24xx/devs.c中发现了线索: struct platform_device s3c_device_nand = { .name = "s3c2410-nand", .id = -1, .num_resources = ARRAY_SIZE(s3c_nand_resource), .resource = s3c_nand_resource, };那么这个设备是如何添加到总线上的呢? .init_machine = osiris_init, platform_add_devices(osiris_devices, ARRAY_SIZE(osiris_devices));//关于osiris_devices的定义见注释1 platform_device_register(devs[i]); platform_device_add(pdev); device_add(&pdev->dev);//将设备添加到总线
这样设备和驱动都注册到了总线上面,那么总线要做什么呢?
我们还记得注册驱动的时候有这么一句吧:
drv->driver.bus = &platform_bus_type;
我们来看看platform_bus_type的定义:
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, };
这里面有match函数,总线就是根据这个函数来判断设备和驱动是否匹配的,我们来看一下代码:
static int platform_match(struct device * dev, struct device_driver * drv) { struct platform_device *pdev = container_of(dev, struct platform_device, dev); return (strncmp(pdev->name, drv->name, BUS_ID_SIZE) == 0); }
我们看到了,确实是根据驱动和设备的名字是否一致,来判断是否匹配的。
一旦匹配就会调用probe函数。
注释1:
static struct platform_device *osiris_devices[] __initdata = { &s3c_device_i2c, &s3c_device_wdt, &s3c_device_nand, &osiris_pcmcia, };
疑问?
我水比较差,只能分析到这个地步了,下面是我的几点疑问,希望大家帮我一下好吗:
(1)我搜遍了代码也没有发现有谁调用了match函数,那么这个函数怎么被执行呢?
(2)为什么match成功后会调用probe函数呢?它也没有在哪个函数里面被调用啊!
(3)
int platform_driver_register(struct platform_driver *drv){drv->driver.bus = &platform_bus_type;if (drv->probe)drv->driver.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);}
为什么一旦设置了 drv->probe就要自动设置drv->driver.probe = platform_drv_probe;?drv.probe和drv->driver.probe两个probe有什么区别啊?
(4)
MACHINE_START(OSIRIS, "Simtec-OSIRIS")/* Maintainer: Ben Dooks <ben@simtec.co.uk> */.phys_io= S3C2410_PA_UART,.io_pg_offst= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,.boot_params= S3C2410_SDRAM_PA + 0x100,.map_io= osiris_map_io,.init_machine= osiris_init,.init_irq= s3c24xx_init_irq,.init_machine= osiris_init,.timer= &s3c24xx_timer,MACHINE_END
这之间的代码何时被执行?
- 平台总线设备驱动模型——基础知识
- 平台总线设备驱动模型——基础知识
- 平台总线设备驱动模型——代码分析
- 平台总线设备驱动模型——代码分析
- Linux设备驱动模型4——平台总线实践
- 平台总线设备驱动模型—代码分析
- linux设备驱动模型——总线、设备、设备驱动
- 13.总线设备驱动模型(2)-平台总线设备设计
- Linux平台总线驱动设备模型
- Linux平台总线驱动设备模型
- Linux平台总线驱动设备模型
- Linux平台总线驱动设备模型
- Linux平台总线驱动设备模型
- Linux平台总线驱动设备模型
- Linux平台总线驱动设备模型
- Linux平台总线驱动设备模型
- Linux平台总线驱动设备模型
- Linux平台总线驱动设备模型
- Box2D 使用setTarget 函数拖动body (结合cocos2d-x 2.0版)
- 调试.NET Web应用程序High Memory - Part 1
- 对于通过视频学习编程的建议
- POJ 3989 A hard Aoshu Problem 简单模拟
- 纪念918(81年过去了)
- 平台总线设备驱动模型——基础知识
- 平台总线设备驱动模型——代码分析
- Configuring Apache HTTP Server
- 总线平台驱动程序总结(修改版)
- csdn上怎么没有测试呢
- ipad2 升级ios6 3194 1604错误
- Delphi对象的方法能定义- 静态(static)、虚拟(virtual)、动态(dynamic)或消息处理(message)
- Error starting static Resources
- Use Microsoft SharePoint Designer 2010 to customize the list view 3---Parameter and Filter