linux platform驱动模型详解

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Байду номын сангаас
(2)platform 总线结构 structbus_typeplatform_bus_type={ .name="platform", .dev_attrs=platform_dev_attrs, .match=platform_match, .uevent=platform_uevent, .pm=&platform_dev_pm_ops, }; platform_dev_attrs设备属性 platform_matchmatch 函数,这个函数在当属于 platform 的设备或者驱动注册 到内核时就会调用,完成设备与驱动的匹配工作。 platform_uevent热插拔操作函数 三。platform设备 1.platform_device结构 structplatform_device{ constchar*name; intid; structdevicedev; u32num_resources; structresource*resource; structplatform_device_id*id_entry; /*archspecificadditions*/ structpdev_archdataarchdata; }; (1)platform_device 结构体中有一个 structresource 结构,是设备占用系统的资源, 在ioport.h 中定义如下: structresource{ resource_size_tstart; resource_size_tend; constchar*name; unsignedlongflags; structresource*parent,*sibling,*child; }; (2)num_resources占用系统资源的数目,一般设备都占用两种资源,io 内存和中断信 号线。这个为两种资源的总和。 2.设备注册函数platform_device_register intplatform_device_register(structplatform_device*pdev) {
} } //上面主要是遍历设备所占用的资源,找到对应的父资源,如果没有定义,那么根据资 源的类型,分别赋予 iomem_resource 和 ioport_resource,然后调用 insert_resource 插入资源。 //这样系统的资源就形成了一个树形的数据结构,便于系统的管理 pr_debug("Registeringplatformdevice'%s'.Parentat%s\n", dev_name(&pdev->dev),dev_name(pdev->dev.parent)); ret=device_add(&pdev->dev); //注册到设备模型中 if(ret==0) returnret; failed: while(--i>=0){ structresource*r=&pdev->resource[i]; unsignedlongtype=resource_type(r); if(type==IORESOURCE_MEM||type==IORESOURCE_IO) release_resource(r); } returnret; } 3.mini2440 内核注册 platform 设备过程 因为一种 soc 确定之后,其外设模块就已经确定了,所以注册 platform 设备就由板级 初始化代码来完成,在 mini2440 中是 mach-mini2440.c 的 mini2440_machine_init 函 数中调用 platform_add_devices(mini2440_devices,ARRAY_SIZE (mini2440_devices))来完成注册。这个函数完成 mini2440 的所有 platform 设备的 注册: (1)platform_add_devices 函数是 platform_device_register 的简单封装,它向内 核注册一组 platform 设备 (2)mini2440_devices 是一个 platform_device 指针数组,定义如下: staticstructplatform_device*mini2440_devices[]__initdata={ &s3c_device_usb, &s3c_device_rtc, &s3c_device_lcd, &s3c_device_wdt, &s3c_device_i2c0, &s3c_device_iis, &mini2440_device_eth,
device_initialize(&pdev->dev); returnplatform_device_add(pdev); } 这个函数首先初始化了 platform_device 的 device 结构,然后调用 platform_device_add,这个是注册函数的关键,下面分析 platform_device_add: intplatform_device_add(structplatform_device*pdev) { inti,ret=0; if(!pdev) return-EINVAL; if(!pdev->dev.parent) pdev->dev.parent=&platform_bus; //可以看出,platform 设备的父设备一般都是 platform_bus,所以注册后的 platform 设备都出现在/sys/devices/platform_bus 下 pdev->dev.bus=&platform_bus_type; //挂到 platform 总线上 if(pdev->id!=-1) dev_set_name(&pdev->dev,"%s.%d",pdev->name,pdev->id); else dev_set_name(&pdev->dev,"%s",pdev->name); //设置设备名字,这个名字与/sys/devices/platform_bus 下的名字对应 for(i=0;i<pdev->num_resources;i++){//下面操作设备所占用的系统资源 structresource*p,*r=&pdev->resource[i]; if(r->name==NULL) r->name=dev_name(&pdev->dev); p=r->parent; if(!p){ if(resource_type(r)==IORESOURCE_MEM) p=&iomem_resource; elseif(resource_type(r)==IORESOURCE_IO) p=&ioport_resource; } if(p&&insert_resource(p,r)){ printk(KERN_ERR "%s:failedtoclaimresource%d\n", dev_name(&pdev->dev),i); ret=-EBUSY; gotofailed;
以 s3c2440 为例分析 Linuxplatform 驱动模型 一。概述 platform 设备和驱动与 linux 设备模型密切相关。platform 在 linux 设备模型中,其实 就是一种虚拟总线没有对应的硬件结构。它的主要作用就是管理系统的外设资源,比如 io 内存,中断信号线。现在大多数处理器芯片都是 soc,如 s3c2440,它包括处理器内核 (arm920t)和系统的外设(lcd 接口,nandflash 接口等)。linux 在引入了 platform 机制之后,内核假设所有的这些外设都挂载在 platform 虚拟总线上,以便进行统一管理。 二。platform总线 1.在系统中 platform 对应的文件 drivers/base/platform.c,它不是作为一个模块注册到 内核的,关键的注册总线的函数由系统初始化部分,对应/init/main.c 中的 do_basic_setup 函数间接调用。这里可以看出 platform 非常重要,要在系统其他驱动加 载之前注册。下面分析 platform 总线注册函数 int__initplatform_bus_init(void) { interror; early_platform_cleanup(); error=device_register(&platform_bus); //总线也是设备,所以也要进行设备的注册 if(error) returnerror; error=bus_register(&platform_bus_type); //注册 platform_bus_type 总线到内核 if(error) device_unregister(&platform_bus); returnerror; } 这个函数向内核注册了一种总线。他首先由/drivers/base/init.c 中的 driver_init 函数调 用,driver_init 函数由/init/main.c 中的 do_basic_setup 函数调用,do_basic_setup 这 个函数由 kernel_init 调用,所以 platform 总线是在内核初始化的时候就注册进了内核。 2.platform_bus_type总线结构与设备结构 (1)platform 总线设备结构 structdeviceplatform_bus={ .init_name="platform", }; platform 总线也是一种设备,这里初始化一个 device 结构,设备名称是"platform", 因为没有指定父设备,所以注册后将会在/sys/device/下出现 platform 目录。
相关文档
最新文档