Linux设备驱动开发 - 平台设备驱动

发布者:Lihua1314520最新更新时间:2024-09-20 来源: cnblogs关键字:Linux  设备驱动开发 手机看文章 扫描二维码
随时随地手机看文章

Linux2.6的内核中引入了一种新的设备驱动模型-平台(platform)设备驱动,平台设备驱动分为平台设备(platform_device)和平台驱动(platform_driver),平台设备的引入使得Linux设备驱动更加便于移植。


一、平台设备

平台设备结构体:


 1 struct platform_device {

 2     const char    * name;                      /* 设备名 */

 3     int        id;

 4     struct device    dev;                     /* 设备结构体 */

 5     u32        num_resources;                   /* 设备资源数量 */

 6     struct resource    * resource;              /* 设备资源 */

 7 

 8     const struct platform_device_id    *id_entry;

 9 

10     /* arch specific additions */

11     struct pdev_archdata    archdata;

12 };


平台设备主要是提供设备资源和平台数据给平台驱动,resource为设备资源数组,类型有IORESOURCE_IO、IORESOURCE_MEM、IORESOURCE_IRQ、IORESOURCE_DMA、IORESOURCE_DMA。下面是一个网卡芯片DM9000的外设资源:


 1 static struct resource dm9000_resources[] = {

 2     [0] = {

 3         .start        = S3C64XX_PA_DM9000,

 4         .end        = S3C64XX_PA_DM9000 + 3,

 5         .flags        = IORESOURCE_MEM,

 6     },

 7     [1] = {

 8         .start        = S3C64XX_PA_DM9000 + 4,

 9         .end        = S3C64XX_PA_DM9000 + S3C64XX_SZ_DM9000 - 1,

10         .flags        = IORESOURCE_MEM,

11     },

12     [2] = {

13         .start        = IRQ_EINT(7),

14         .end        = IRQ_EINT(7),

15         .flags        = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,

16     },

17 };


dm9000_resources里面有三个设备资源,第一个为IORESOURCE_MEM类型,指明了第一个资源内存的起始地址为S3C64XX_PA_DM9000结束地址为S3C64XX_PA_DM9000 + 3,第二个同样为IORESOURCE_MEM类型,指明了第二个资源内存的起始地址为S3C64XX_PA_DM9000 + 4结束地址为S3C64XX_PA_DM9000 + S3C64XX_SZ_DM9000 - 1,第三个为IORESOURCE_IRQ类型,指明了中断号为IRQ_EINT(7)。


 1 struct device {

 2     struct device        *parent;

 3 

 4     struct device_private    *p;

 5 

 6     struct kobject kobj;

 7     const char        *init_name; /* initial name of the device */

 8     struct device_type    *type;

 9 

10     struct mutex        mutex;    /* mutex to synchronize calls to

11                      * its driver.

12                      */

13 

14     struct bus_type    *bus;        /* type of bus device is on */

15     struct device_driver *driver;    /* which driver has allocated this

16                        device */

17     void        *platform_data;    /* Platform specific data, device

18                        core doesn't touch it */

19     ...

20 };


struct device结构体里面有一个重要成员platform_data,它是平台设备和平台驱动进行数据传递的重要成员。


平台设备注册:


1 int platform_device_register(struct platform_device *pdev);

platform_device_register()会对平台设备进行相应的初始化之后调用platform_device_register()函数把它添加到子系统中。



平台设备注销:


1 void platform_device_unregister(struct platform_device *pdev);

platform_device_unregister()函数释放设备资源之后从子系统中将其移除。


平台设备模板:


 1 static struct resource xxx_resource = 

 2 {

 3     [0] = 

 4     {

 5         .start = ...,

 6         .end = ...,

 7         .flags = ...,

 8     },

 9     [1] = 

10     {

11         ...

12     }

13     ...

14 };

15 

16 static struct xxx_plat_data xxx_data = 

17 {

18     ...

19 };

20 

21 static struct platform_device xxx_platform_device = 

22 {

23     .name = NAME,

24     .num_resources = ARRAY_SIZE(xxx_resource),

25     .resource = xxx_resource,

26     .dev = 

27     {

28         .platform_data = &xxx_data,

29     }

30 };

31 

32 static int __init xxx_device_init(void)

33 {

34     ...

35     /* 注册平台设备 */

36     platform_device_register(&xxx_platform_device);

37     ...

38 }

39 

40 static void __exit xxx_device_exit(void)

41 {

42     ...

43     /* 注销平台设备 */

44     platform_device_unregister(&xxx_platform_device);

45     ...

46 }


二、平台驱动

平台驱动结构体:


1 struct platform_driver {

2     int (*probe)(struct platform_device *);

3     int (*remove)(struct platform_device *);

4     void (*shutdown)(struct platform_device *);

5     int (*suspend)(struct platform_device *, pm_message_t state);

6     int (*resume)(struct platform_device *);

7     struct device_driver driver;

8     const struct platform_device_id *id_table;

9 };


平台驱动结构体driver成员里面的name必须与平台设备结构体里面的name成员一致,在系统注册一个设备的时候,会通过设备结构体里面的name成员和平台驱动driver里面的name成员匹配,当匹配成功则调用平台驱动的probe函数,

通常在probe函数中获取平台设备的资源和私有数据并进行设备的初始化。


获取设备资源:


1 struct resource *platform_get_resource(struct platform_device *dev, unsigned int type, unsigned int num);

platform_get_resource()函数用于获取平台设备的资源,dev为要平台设备,type为平台设备资源类型,num为平台资源号(比如同一个资源有两个则资源号为0,1)。

 


平台驱动注册:


1 int platform_driver_register(struct platform_driver *drv);

platform_driver_register()函数完成平台驱动的注册,在驱动模块加载时调用。


平台驱动注销:


1 void platform_driver_unregister(struct platform_driver *drv);

platform_driver_unregister()函数完成平台驱动的注销,在驱动模块卸载时调用。


平台驱动模板:


 1 static int __devinit xxx_probe(struct platform_device *pdev)

 2 {

 3     struct xxx_plat_data *pdata = pdev->dev.platform_data;    /* 获取私有数据 */

 4     platform_get_resource(pdev,xxx,x);                        /* 获取设备资源 */

 5     ...

 6 }

 7 

 8 static struct platform_driver xxx_platform_driver = 

 9 {

10     .probe = xxx_probe,

11     .remove = __devexit_p(xxx_remove),

12     .driver = 

13     {

14         .name = NAME,    /* 跟平台设备名一致 */

15         ...

16     },

17     ...

18 };

19 

20 static int __init xxx_driver_init(void)

21 {

22     ...

23     /* 驱动注册 */

24     platform_driver_register(&xxx_platform_driver);

25     ...

26 }

27 

28 static void __exit xxx_driver_exit(void)

29 {

30     ...

31     /* 驱动注销 */

32     platform_driver_unregister(&xxx_platform_driver);

33     ...

34 }


关键字:Linux  设备驱动开发 引用地址:Linux设备驱动开发 - 平台设备驱动

上一篇:Linux混杂设备驱动 - 按键设备驱动
下一篇:Linux设备驱动开发 - 混杂设备驱动

推荐阅读最新更新时间:2026-03-07 03:15

Linux Platform devices 平台设备驱动
platform平台设备驱动是基于设备总线驱动模型的,它只不过是将 device 进一步封装成为 platform_device,将 device_driver 进一步封装成为 platform_device_driver,前面已经分析过设备总线驱动模型,关于device 与 device_driver 的注册过程以及它们在sysfs文件系统中的层次关系就不在分析,本文重点分析platform平台设备驱动与设备总线驱动模型相比较新增添的那些东西。 在Linux设备模型的抽象中,存在着一类称作“Platform Device”的设备,内核是这样描述它们的(Documentation/driver-model/platform.t
[单片机]
S3C2440驱动篇—Linux平台设备驱动
在设备驱动程序中经常会见到和platform相关的字段,分布在驱动程序的多个角落,这也是2.6内核中比较重要的一种机制,把它原理弄懂,对以后分析驱动程序很有帮助:在linux2.6设备模型中,关心总线,设备,驱动这三个实体,总线将设备和驱动绑定,在系统每注册一个设备的时候,会寻找与之匹配的驱动。相反,在系统每注册一个驱动的时候,寻找与之匹配的设备,匹配是由总线来完成的。 一个现实的Linux 设备和驱动通常都需要挂接在一种总线上,对于本身依附于PCI、USB、I2C、SPI 等的设备而言,这自然不是问题,但是在嵌入式系统里面,SoC 系统中集成的独立的外设控制器、挂接在SoC 内存空间的外设等确不依附于此类总线。基于这一背景,Li
[单片机]
linux中LCD设备驱动(2)——基于s3c6410平台
上一篇说了framebuffer帧缓冲的有关知识,这一篇具体的说下LCD驱动的实现。 1、LCD设备驱动在linux内核中是作为平台设备存在,所以又要说那些已经说过很多遍的东西。 int __devinit s3cfb_init(void) { return platform_driver_register(&s3cfb_driver); } static void __exit s3cfb_cleanup(void) { platform_driver_unregister(&s3cfb_driver); } module_init(s3cfb_init); module_exit(s3cfb_cleanup); 对
[单片机]
linux中LCD设备驱动(4)——基于s3c6410平台
我们这一篇来说与具体的TFT显示器有关的部分,当遇到具体的显示器是我们应该设置什么参数,怎样设置这些参数。 1、在s3cfb_WXCAT43.c (linux2.6.28driversvideosamsung)文件中是有关具体显示器的设置。我们一段一段来看。 #include linux/wait.h #include linux/fb.h #include linux/delay.h #include linux/platform_device.h #include plat/regs-gpio.h #include plat/regs-lcd.h #include s3cfb.h #define S3C
[单片机]
<font color='red'>linux</font>中LCD<font color='red'>设备驱动</font>(4)——基于s3c6410<font color='red'>平台</font>
手把手教你写Linux设备驱动---中断(三)--workqueue实现(基于友善之臂4412开发板)
上节,我们讲到如何来实现tasklet小任务机制 http://blog.csdn.NET/morixinguan/article/details/69666935 这节,我们来实现一下中断下半部的工作队列: 在写这个demo之前,我们要了解一下工作队列的相关数据结构还有API。 需要包含的头文件: #include Linux/workqueue.h 基本的数据结构: //工作队列结构 struct work_struct { atomic_long_t data; //链表处理 struct list_head entry; //工作处理函数 work_func_t
[单片机]
手把手教你写<font color='red'>Linux</font><font color='red'>设备驱动</font>---中断(三)--workqueue实现(基于友善之臂4412<font color='red'>开发</font>板)
Linux设备驱动开发 - LCD设备驱动分析
一、S3C6410 LCD驱动裸机代码 LCD控制器初始化: 1 unsigned long VideoBuffer = {0}; 2 void lcd_init(void) 3 { 4 /* 1.初始化IO端口为LCD端口 */ 5 /* GPIO configure */ 6 GPICON = 0xAAAAAAAA; 7 GPJCON = 0x00AAAAAA; 8 9 /* 2.使能LCD时钟 */ 10 //HCLK_GATE |= (1 3); //默认打开 11 12 MIFPCON &=~(1 3); 13 14 /* 3.设置I/F类型 *
[单片机]
<font color='red'>Linux</font><font color='red'>设备驱动</font><font color='red'>开发</font> - LCD<font color='red'>设备驱动</font>分析
USB设备驱动移植之开发板做U盘
TQ2440开发板有两个USB端口,需要把第二个USB(就是烧写的那个 USB 口)设置为USB device 1、修改源码 首先把开发板当成从设备 来 用,也 就 是 该 USB 口 使 用 USB Device 功 能 , 修 改 内 核 源 码 的“arch/arm/mach-s3c2440/mach-smdk2440.c”文件: 在 2.6.30.4 中的 52 行添加如下内容: #include plat/udc.h 在 151 行添加如下内容: .lpcsel = ((0xCE6) & ~7) | 1 4, }; static void EmbedSky_udc_pullup(enum s3c2410_udc_c
[单片机]
USB<font color='red'>设备驱动</font>移植之<font color='red'>开发</font>板做U盘
USB设备驱动程序开发
引言   USB总线是1995年微软、IBM等公司推出的一种新型通信标准总线,特点是速度快、价格低、独立供电、支持热插拔等,其版本从早期的1.0、1.1已经发展到目前的2.0版本,2.0版本的最高数据传输速度达到480Mbit/s,能满足包括视频在内的多种高速外部设备的数据传输要求,由于其众多的优点,USB总线越来越多的被应用到计算机与外设的接口中,芯片厂家也提供了多种USB接口芯片供设计者使用,为了开发出功能强大的USB设备,设计者往往需要自己开发USB设备驱动程序,驱动程序开发一直是Windows开发中较难的一个方面,但是通过使用专门的驱动程序开发包能减小开发的难度,提高工作效率,本文使用Compuware Numega公司的D
[嵌入式]
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved