详解Linux26内核中基于platform机制的驱动模型Word文件下载.docx

上传人:b****3 文档编号:18474829 上传时间:2022-12-17 格式:DOCX 页数:28 大小:36.06KB
下载 相关 举报
详解Linux26内核中基于platform机制的驱动模型Word文件下载.docx_第1页
第1页 / 共28页
详解Linux26内核中基于platform机制的驱动模型Word文件下载.docx_第2页
第2页 / 共28页
详解Linux26内核中基于platform机制的驱动模型Word文件下载.docx_第3页
第3页 / 共28页
详解Linux26内核中基于platform机制的驱动模型Word文件下载.docx_第4页
第4页 / 共28页
详解Linux26内核中基于platform机制的驱动模型Word文件下载.docx_第5页
第5页 / 共28页
点击查看更多>>
下载资源
资源描述

详解Linux26内核中基于platform机制的驱动模型Word文件下载.docx

《详解Linux26内核中基于platform机制的驱动模型Word文件下载.docx》由会员分享,可在线阅读,更多相关《详解Linux26内核中基于platform机制的驱动模型Word文件下载.docx(28页珍藏版)》请在冰豆网上搜索。

详解Linux26内核中基于platform机制的驱动模型Word文件下载.docx

注册platform_driver 

29

8.6 

操作设备 

32

Linux系统中许多部分对设备是如何链接的并不感兴趣,但是他们需要知道哪些类型的设备是可以使用的。

设备模型提供了一种机制来对设备进行分类,在更高的功能层面上描述这些设备,并使得这些设备对用户空间可见。

因此从2.6内核开始引入了设备模型。

总线是处理器和一个或多个设备之间的通道,在设备模型中,所有的设备都通过总线相连。

总线可以相互插入。

设备模型展示了总线和它们所控制的设备之间的实际连接。

Platform总线是2.6kernel中最近引入的一种虚拟总线,主要用来管理CPU的片上资源,具有更好的移植性,因此在2.6kernel中,很多驱动都用platform改写了。

platform_bus_type的定义如下:

http:

//lxr.linux.no/#linux+v2.6.25/drivers/base/platform.c#L609

609structbus_typeplatform_bus_type={

610 

.name 

="

platform"

611 

.dev_attrs 

=platform_dev_attrs,

612 

.match 

=platform_match,

613 

.uevent 

=platform_uevent,

614 

.suspend 

=platform_suspend,

615 

.suspend_late 

=platform_suspend_late,

616 

.resume_early 

=platform_resume_early,

617 

.resume 

=platform_resume,

618};

619EXPORT_SYMBOL_GPL(platform_bus_type);

//lxr.linux.no/#linux+v2.6.25/include/linux/device.h#L55

55structbus_type{

56 

constchar 

*name;

57 

structbus_attribute 

*bus_attrs;

58 

structdevice_attribute*dev_attrs;

59 

structdriver_attribute*drv_attrs;

60

61 

int(*match)(structdevice*dev,structdevice_driver*drv);

62 

int(*uevent)(structdevice*dev,structkobj_uevent_env*env);

63 

int(*probe)(structdevice*dev);

64 

int(*remove)(structdevice*dev);

65 

void(*shutdown)(structdevice*dev);

66

67 

int(*suspend)(structdevice*dev,pm_message_tstate);

68 

int(*suspend_late)(structdevice*dev,pm_message_tstate);

69 

int(*resume_early)(structdevice*dev);

70 

int(*resume)(structdevice*dev);

71

72 

structbus_type_private*p;

73};

总线名称是"

,其只是bus_type的一种,定义了总线的属性,同时platform_bus_type还有相关操作方法,如挂起、中止、匹配及hotplug事件等。

总线bus是联系driver和device的中间枢纽。

Device通过所属的bus找到driver,由match操作方法进行匹配。

Bus、driver及devices的连接关系

device和platform_device

Plarformdevice会有一个名字用于driverbinding(在注册driver的时候会查找driver的目标设备的bus位置,这个过程称为driverbinding),另外IRQ以及地址空间等资源也要给出。

platform_device结构体用来描述设备的名称、资源信息等。

该结构被定义在http:

//lxr.linux.no/#linux+v2.6.25/include/linux/platform_device.h#L16中,定义原型如下:

16structplatform_device{

17 

*name;

//定义平台设备的名称,此处设备的命名应和相应驱动程序命名一致

18 

int 

id;

19 

structdevice 

dev;

20 

u32 

num_resources;

21 

structresource*resource;

//定义平台设备的资源

22};

在这个结构里封装了structdevice及structresource。

可知:

platform_device由device派生而来,是一种特殊的device。

下面来看一下platform_device结构体中最重要的一个成员structresource*resource。

structresource被定义在http:

//lxr.linux.no/#linux+v2.6.25/include/linux/ioport.h#L18中,定义原型如下:

14/*

15*Resourcesaretree-like,allowing

16*nestingetc..

17*/

18structresource{

resource_size_tstart;

//定义资源的起始地址

resource_size_tend;

//定义资源的结束地址

constchar*name;

//定义资源的名称

22 

unsignedlongflags;

定义资源的类型,比如MEM,IO,IRQ,DMA类型

23 

structresource*parent,*sibling,*child;

24};

这个结构表示设备所拥有的资源,即I/O端口、I/O映射内存、中断及DMA等。

这里的地址指的是物理地址。

另外还需要注意platform_device中的device结构,它详细描述了设备的情况,其为所有设备的基类,定义如下:

//lxr.linux.no/#linux+v2.6.25/include/linux/device.h#L422

422structdevice{

423 

structklist 

klist_children;

424 

structklist_node 

knode_parent;

/*nodeinsiblinglist*/

425 

knode_driver;

426 

knode_bus;

427 

*parent;

428

429 

structkobjectkobj;

430 

char 

bus_id[BUS_ID_SIZE];

/*positiononparentbus*/

431 

structdevice_type 

*type;

432 

unsigned 

is_registered:

1;

433 

uevent_suppress:

434

435 

structsemaphore 

sem;

/*semaphoretosynchronizecallsto

436 

*itsdriver.

437 

*/

438

439 

structbus_type*bus;

/*typeofbusdeviceison*/

440 

structdevice_driver*driver;

/*whichdriverhasallocatedthis

441 

device*/

442 

void 

*driver_data;

/*dataprivatetothedriver*/

443 

*platform_data;

/*Platformspecificdata,device

444 

coredoesn'

'

ttouchit*/

445 

structdev_pm_info 

power;

446

447#ifdefCONFIG_NUMA

448 

numa_node;

/*NUMAnodethisdeviceiscloseto*/

449#endif

450 

u64 

*dma_mask;

/*dmamask(ifdma'

abledevice)*/

451 

coherent_dma_mask;

/*Likedma_mask,butfor

452 

alloc_coherentmappingsas

453 

notallhardwaresupports

454 

64bitaddressesforconsistent

455 

allocationssuchdescriptors.*/

456

457 

structdevice_dma_parameters*dma_parms;

458

459 

structlist_head 

dma_pools;

/*dmapools(ifdma'

ble)*/

460

461 

structdma_coherent_mem*dma_mem;

/*internalforcoherentmem

462 

override*/

463 

/*archspecificadditions*/

464 

structdev_archdata 

archdata;

465

466 

spinlock_t 

devres_lock;

467 

devres_head;

468

469 

/*class_devicemigrationpath*/

470 

node;

471 

structclass 

*class;

472 

dev_t 

devt;

/*dev_t,createsthesysfs"

dev"

473 

structattribute_group 

**groups;

/*optionalgroups*/

474

475 

(*release)(structdevice*dev);

476};

477

device_register和platform_device_register

//lxr.linux.no/#linux+v2.6.25/drivers/base/core.c#L881

870/**

871*device_register-registeradevicewiththesystem.

872*@dev:

pointertothedevicestructure

873*

874*Thishappensintwocleansteps-initializethedevice

875*andaddittothesystem.Thetwostepscanbecalled

876*separately,butthisistheeasiestandmostcommon.

877*I.e.youshouldonlycallthetwohelpersseparatelyif

878*haveaclearlydefinedneedtouseandrefcountthedevice

879*beforeitisaddedtothehierarchy.

880*/

881intdevice_register(structdevice*dev)

882{

883 

device_initialize(dev);

884 

returndevice_add(dev);

885}

初始化一个设备,然后加入到系统中。

//lxr.linux.no/#linux+v2.6.25/drivers/base/platform.c#L325

316/**

317*platform_device_register-addaplatform-leveldevice

318*@pdev:

platformdevicewe'

readding

319*/

320intplatform_device_register(structplatform_device*pdev)

321{

322 

device_initialize(&

pdev->

dev);

323 

returnplatform_device_add(pdev);

324}

325EXPORT_SYMBOL_GPL(platform_device_register);

我们看到注册一个platformdevice分为了两部分,初始化这个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总线上。

229/**

230*platform_device_add-addaplatformdevicetodevicehierarchy

231*@pdev:

232*

233*Thisispart2ofplatform_device_register(),thoughmaybecalled

234*separately_iff_pdevwasallocatedbyplatform_device_alloc().

235*/

236intplatform_device_add(structplatform_device*pdev)

237{

238 

inti,ret=0;

239

240 

if(!

pdev)

241 

return-EINVAL;

242

初始化设备的parent为platform_bus,初始化驱备的总线为platform_bus_type。

243 

dev.parent)

244 

pdev->

dev.parent=&

platform_bus;

245

246 

dev.bus=&

platform_bus_type;

247

/*++++++++++++++

Theplatform_device.dev.bus_idisthecanonicalnameforthedevices.

It'

sbuiltfromtwocomponents:

*platform_device.name...whichisalsousedtofordrivermatching.

*platform_device.id...thedeviceinstancenumber,orelse"

-1"

toindicatethere'

sonlyone.

Theseareconcatenated,soname/id"

serial"

/0indicatesbus_id"

serial.0"

and

"

serial/3"

indicatesbus_id"

serial.3"

;

bothwouldusetheplatform_driver

named"

.While"

my_rtc"

/-1wouldbebus_id"

(noinstanceid)

andusetheplatform_drivercalled"

.

++++++++++++++*/

248 

if(pdev->

id!

=-1)

249 

snprintf(pdev->

dev.bus_id,BUS_ID_SIZE,"

%s.%d"

pdev->

name,

250 

id);

251 

else

252 

strlcpy(pdev->

dev.bus_id,pdev->

name,BUS_ID_SIZE);

253

设置设备structdevice的bus_id成员,留心这个地方,在以后还需要用到这个的。

254 

for(i=0;

i<

num_resources;

i++){

255 

structresource*p,*r=&

resource[i];

256

257 

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1