LINUX平台设备(linux platform_device and platform_driver)

转载 2012年03月26日 15:01:26

LINUX平台设备(linux platform_device and platform_driver)  

2011-10-08 09:05:33|  分类: Android测试 |  标签: |字号 订阅

LINUX平台设备(linux platform_device and platform_driver)zhuan
2010-11-15 17:36
http://hi.baidu.com/lala19861008/blog/item/f5d72af7052cdb7edcc474bc.html

LINUX平台设备分为

1 设备层(主要是描述设备资源)
2 驱动层(我们写驱动要实现的)
设备层:主要定义个设备的资源。
用platform_device结构体来描述一个平台设备。定义在(/include/LINUX/platform_device.h)
struct platform_device {
const char * name;//设备名称
int   id;
struct device dev;
u32   num_resources;//设备使用资源的数量
struct resource * resource;//使用的资源
};
例如:/* RTC */
/**************************************************************/
arch/arm/plat-s3c24xx/devs.c中就定义了很多平台设备,截取RTC的设备结构
static struct resource s3c_rtc_resource[] = {
[0] = {//IO端口资源范围
   .start = S3C24XX_PA_RTC,
   .end   = S3C24XX_PA_RTC + 0xff,
   .flags = IORESOURCE_MEM,//定义了这个资源的类型(通俗点就是要内存映射的类型)/include/linux/ioport.h
},
[1] = {//RTC报警中断资源
   .start = IRQ_RTC,
   .end   = IRQ_RTC,
   .flags = IORESOURCE_IRQ,//这个资源是中断类型的
},
[2] = {//TICK节拍时间中断资源
   .start = IRQ_TICK,
   .end   = IRQ_TICK,
   .flags = IORESOURCE_IRQ,
}
};

struct platform_device s3c_device_rtc = {
.name    = "s3c2410-rtc",//RTC名字(与驱动里面的name要一样)
.id    = -1,
.num_resources   = ARRAY_SIZE(s3c_rtc_resource),(对上面的s3c_rtc_resource求值,求出的是定义了几个资源)
.resource   = s3c_rtc_resource,//对应上面的 struct resource s3c_rtc_resource[]
};

EXPORT_SYMBOL(s3c_device_rtc);
/**************************************************************/
以上定义了RTC所有的设备资源!然后我们要使用这些资源,就要添加到内核里面!
打开arch/arm/mach-s3c2440/mach-smdk2440.c这个ARM 2440平台的系统入口文件。里面有这两个!
static struct platform_device *smdk2440_devices[] __initdata = {
&s3c_device_usb,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c0,
&s3c_device_iis,
&s3c_device_rtc,//因为我们要加入RTC设备到系统,在这里加入
};
static void __init smdk2440_machine_init(void)
{
s3c24xx_fb_set_platdata(&smdk2440_fb_info);
s3c_i2c0_set_platdata(NULL);

platform_add_devices(smdk2440_devices, ARRAY_SIZE(smdk2440_devices));//这里是添加设备的注册函数!刚好调用上面的smdk2440_devices。
smdk_machine_init();
}
上面就吧设备资源加入到了内核!
下面就是实现我们的驱动!
具体步骤和RTC驱动的实现参照黄刚前辈的博客!
http://blog.chinaunix.net/u3/101649/showart_2142248.html
我也是个菜鸟,我只是吧我的理解写下来,便以记忆!
有错误,欢迎拍砖,指正!谢谢!
《《《《《《《《《《《《《《驱动部分《《《《《《《《《《《《《《《《《《《《《《《《《《《《《

驱动层用struct platform_driver 结构体来定义驱动。

static struct platform_driver rtc_driver = //定义platform_driver 结构体
{
    .probe   = rtc_probe, /*RTC探测函数,
    .remove = __devexit_p(rtc_remove),/*RTC移除函数,*/
    .suspend = rtc_suspend, /*RTC挂起函数,
    .resume = rtc_resume, /*RTC恢复函数,
    .driver =
    {
        /*注意这里的名称一定要和系统中定义平台设备的地方一致,这样才能把平台设备与该平台设备的驱动关联起来*/
        .name   = "s3c2410-rtc",
        .owner = THIS_MODULE,
    },
};

static int __init rtc_init(void)
{
    /*将RTC注册成平台设备驱动*/
    return platform_driver_register(&rtc_driver);
}

static void __exit rtc_exit(void)
{
    /*注销RTC平台设备驱动*/
    platform_driver_unregister(&rtc_driver);
}

module_init(rtc_init);
module_exit(rtc_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Huang Gang");
MODULE_DESCRIPTION("My2440 RTC driver");
这个地方还跟我们以前写字符模块驱动一样,用module_init(),,但是我们把类似于中断注册,IO映射等等都都放到rtc_probe里面实现!所以这里只是调用return platform_driver_register(&rtc_driver)将RTC注册成平台设备驱动。
其实很多地方我也不懂,查查资料,我是这样理解的:为了保持低功耗,我们只是在用的某个设备的时候才将其打开,平时不用的时候我们可以挂起。因为ARM一般都用到消费电子上,所以对功耗有很高的要求!这也是我们采用平台设备的目的!
开始我以为这里就是驱动实现函数(类似于open ,read等等)!看到后来才发现不是!接口函数在后面!
注册完设备,此时系统只是知道有这个设备,但是不知道要使用什么资源!于是rtc_probe这个探测函数出场了!它主要负责探测资源,初始化,(其实设备的初始化可以放到__init rtc_init()函数里面进行的)。我们在探测函数里面注册中断(RTC有2个中断),进行内存映射(IOMAP()),就像我们写字符驱动的初始化一样!但王刚的注册中断在后面的open里面,iomap在这里面,我觉得根据实际情况来,其实放哪里都可以,比如中断,如果牵扯到共享中断,还是要放到open里面来注册。
probe函数见黄刚前辈的博客!

一切初始化完后,我们要注册一个RTC设备类。
| /*将RTC注册为RTC设备类,RTC设备类在RTC驱动核心部分中由系统定义好的,
|     注意rtcops这个参数是一个结构体,该结构体的作用和里面的接口函数实现在第③步中。
|     rtc_device_register函数在rtc.h中定义,在drivers/rtc/class.c中实现*/
|    rtc = rtc_device_register("my2440", &pdev->dev, &rtcops, THIS_MODULE);
|    if (IS_ERR(rtc))
|    {
|        /*错误处理*/
|        dev_err(&pdev->dev, "cannot attach rtc\n");
|        ret = PTR_ERR(rtc);
|        goto err_nortc;
|    }
|

static const struct rtc_class_ops rtcops = {         / /RTC类的file_operation函数)
    .open            = rtc_open,
    .release         = rtc_release,
    .irq_set_freq    = rtc_setfreq,

    .irq_set_state   = rtc_setpie,
    .read_time       = rtc_gettime,
    .set_time        = rtc_settime,
    .read_alarm      = rtc_getalarm,
    .set_alarm       = rtc_setalarm,
};
//这个是RTC类注册函数的原型!
struct rtc_device *rtc_device_register(const char *name,
      struct device *dev,
      const struct rtc_class_ops *ops,
      struct module *owner);

我也不太清楚这个类的作用,我理解的是为了统一管理吗???不清楚!知道的说下!
类注册的函数里面有一个struct rtc_class_ops *ops, 这个结构体很重要,他就是我们写驱动时候那些个(READ ,WRITE等),我们主要来实现这个rtc_class_ops。
struct rtc_class_ops {
int (*open)(struct device *);//打开
void (*release)(struct device *);//关闭
int (*ioctl)(struct device *, unsigned int, unsigned long);//IOCTL
int (*read_time)(struct device *, struct rtc_time *);//读时间
int (*set_time)(struct device *, struct rtc_time *);//设置时间
int (*read_alarm)(struct device *, struct rtc_wkalrm *);
int (*set_alarm)(struct device *, struct rtc_wkalrm *);
int (*proc)(struct device *, struct seq_file *);
int (*set_mmss)(struct device *, unsigned long secs);
int (*irq_set_state)(struct device *, int enabled);
int (*irq_set_freq)(struct device *, int freq);
int (*read_callback)(struct device *, int data);
};
看看,跟我们的file_operation是多么的相似!可以说是完全一样!我们就是来实现这些函数来操作我们的RTC。目前我是这样理解的!
差不多就这样吧!我太菜了!也不是很清楚!


那什么情况可以使用platform driver机制编写驱动呢?//下面的话是转的!!哈哈!

我的理解是只要和内核本身运行依赖性不大的外围设备(换句话说只要不在内核运行所需的一个最小系统之内的设备),相对独立的,拥有各自独自的资源(addresses and IRQs),都可以用platform_driver实现。如:lcd,usb,uart等,都可以用platfrom_driver写,而timer,irq等最小系统之内的设备则最好不用platfrom_driver机制,实际上内核实现也是这样的。

下图截至黄刚的博客!http://blog.chinaunix.net/u3/101649/showart_2142248.html

图片

RTC在Linux中的整体结构:
就个人理解,RTC在Linux中整体结构分为两个部分。第一个是部分就是上面所讲的作为平台设备被挂接到系统总线中,这里我把他叫做设备层(呵呵,可能不是很准确的叫法);第二部分就是驱动部分,这里叫做驱动层。在Linux中要使一个驱动在不同的平台中都能够使用似乎是不可能的,所以我们先看2.6.30.4内核驱动中的RTC部分是单独的一个文件夹,在文件夹中包含了很多不同体系结构的RTC驱动,当然也有S3C2440的RTC驱动,然而在这些驱动中他们都使用了一组文件里面的方法,那么这组文件就是RTC的核心(注意这里的核心不是指对RTC硬件的操作,指的是对RTC操作的方法。对硬件寄存器的操作还是在具体的驱动中)。好了,我们还是用图来说明这种关系吧!!

图片

Linux 设备驱动开发 —— platform设备驱动应用实例解析

前面我们已经学习了platform设备的理论知识Linux 设备驱动开发 —— platform 设备驱动 ,下面将通过一个实例来深入我们的学习。         一、platform 驱动的工作过程...
  • zqixiao_09
  • zqixiao_09
  • 2016年03月14日 19:27
  • 12397

Linux 设备驱动开发 —— 设备树在platform设备驱动中的使用

关与设备树的概念,我们在Exynos4412 内核移植(六)—— 设备树解析 里面已经学习过,下面看一下设备树在设备驱动开发中起到的作用          Device Tree是一种描述硬件的...
  • qq_21593899
  • qq_21593899
  • 2016年06月19日 11:40
  • 1055

Linux 设备驱动开发 —— 设备树在platform设备驱动中的使用

关与设备树的概念,我们在Exynos4412 内核移植(六)—— 设备树解析 里面已经学习过,下面看一下设备树在设备驱动开发中起到的作用          Device Tree是一种描述硬件的数据结...
  • zqixiao_09
  • zqixiao_09
  • 2016年03月14日 20:47
  • 9901

linux平台设备驱动架构详解 Linux Platform Device and Driver

从Linux 2.6起引入了一套新的驱动管理和注册机制:Platform_device和Platform_driver。 Linux中大部分的设备驱动,都可以使用这套机制, 设备用Platfor...
  • lvlufeng
  • lvlufeng
  • 2012年05月28日 09:59
  • 1234

linux平台设备驱动架构详解 Linux Platform Device and Driver——神文,非常详细

https://www.cnblogs.com/lifan3a/articles/5045447.html https://www.cnblogs.com/lifan3a/articles/5045...
  • STN_LCD
  • STN_LCD
  • 2017年12月07日 17:02
  • 81

Linux设备模型之platform_device和platform_driver

     在《Linux设备模型分析之基本数据结构》一文中我分析了kobject,kset,device,device_driver等构成Linux设备模型的重要数据结构。但在分析Linux内核代码时...
  • cskywit
  • cskywit
  • 2011年03月25日 20:02
  • 1234

platform_device 和 platform_driver(平台设备和平台驱动)

做Linux方面也有三个多月了,对代码中的有些结构一直不是很明白,比如platform_device与platform_driver一直分不清关系。在网上搜了下,做个总结。两者的工作顺序是先定义pla...
  • zhouwulin145
  • zhouwulin145
  • 2013年08月27日 17:17
  • 566

平台设备与平台驱动注册过程platform_driver_register与platform_device_register

1、platform_device_regisger2、platform_driver_regisgerplatform_driver_register  driver_register    bus...
  • hjjomiqpl
  • hjjomiqpl
  • 2015年08月21日 15:10
  • 992

Linux 2.6下的platform_driver和platform_device(结合G870加密磁头驱动分析)

首先介绍一下注册一个驱动的步骤: 1、定义一个platform_driver结构 2、初始化这个结构,指定其probe、remove等函数,并初始化其中的driver变量 3、实现其prob...
  • coolkids_2008
  • coolkids_2008
  • 2011年11月17日 17:26
  • 726

30、Linux Platform Device and Driver

作者: Dongas 日期: 08-06-27   从 Linux 2.6 起引入了一套新的驱动管理和注册机制 :Platform_device 和 Platform_driver 。 ...
  • mianyy
  • mianyy
  • 2011年08月23日 17:54
  • 426
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:LINUX平台设备(linux platform_device and platform_driver)
举报原因:
原因补充:

(最多只允许输入30个字)