分享

linux2.6设备相关的主要是:总线、设备、驱动

 felwell 2012-12-24
设备是具体的硬件,驱动是使设备工作的方法,总线就是连接设备和驱动桥梁。驱动通过总线来控制设备。总线包括usb、i2c等。而platform是一个抽象的总线。本文也将对platform进行初步的介绍。
 
platform包括两个重要的结构体:plateform_device和platform_driver
platform_device:代表一个设备,其中包含这个设备的一些属性,一般是在平台相关的bsp文件中实现的.
其结构体如下:
struct platform_device {
    const char * name;  //设备名称
    int id;             //设备ID
    struct device dev;  //包含设备相关信息
    u32 num_resources;  //设备所使用的资源数目
    struct resource * resource;    //设备所使用的资源
    const struct platform_device_id *id_entry;
 
    struct pdev_archdata archdata;
};
//注册、注销设备的函数
 
extern int platform_device_register(struct platform_device *);
extern void platform_device_unregister(struct platform_device *);
platform_driver:代表设备的驱动,包含了对这个设备操作的一些方法
其对应的结构体如下:
 
struct platform_driver {
int (*probe)(struct platform_device *);  //驱动探测
int (*remove)(struct platform_device *); //驱动移除
void (*shutdown)(struct platform_device *);
int (*suspend)(struct platform_device *, pm_message_t state);//驱动睡眠
int (*resume)(struct platform_device *);  //驱动唤醒
struct device_driver driver;             //包含设备名称
const struct platform_device_id *id_table;
};
//驱动注册、注销函数
 
extern int platform_driver_register(struct platform_driver *);
extern void platform_driver_unregister(struct platform_driver *);
注:
    设备(platform_devie)和驱动(platform_driver)是由总线通过“name”字符串来匹配的。也就是说
platform_device 中的“name”字段要和platform_driver 中的"name"字段一致。当一个驱动平台的device和driver都写好后,注册到内核中,并且他们的name一致。则在启动系统的时,就会匹配这个设备。当匹配成功后就会执行probe这个函数,来探测驱动(主要做初始化的工作,填充一些必要的结构体,生成一些资源,向内核注册一些设备等等,并制定这个驱动要完成的动作).
 
平台资源:
下面讲解下probe函数流程:
  在有些驱动的probe函数中,会使用下列函数,
platform_get_resource:获取设备所使用的来获取IO内存资源;
platform_get_irq:获取设备所使用的IRQ中断资源;
request_mem_region:向内核申请IO内存资源
request_irg:向内核申请中断号
  其中相关资源都是在platform_devic结构体中的resource成员中定义。resoure结构体使用下面形式定义
static struct resource s3c_usb_resource[] = {
[0] = {
.start = S3C_PA_USBHOST,
.end   = S3C_PA_USBHOST + 0x100 - 1,
.flags = IORESOURCE_MEM,    //IO内存地址
},
[1] = {
.start = IRQ_USBH,
.end   = IRQ_USBH,
.flags = IORESOURCE_IRQ,    //IRQ中断号
}
};
 
平台数据:
  它要根据特定的驱动来编写,有的比较简单的设备就没有平台数据,有的设备需要在bsp文件中,给驱动传递一些配置参数,其传递过程是probe函数通过访问platform_device获取。
 
应用:
  如果,我们使用的驱动在内核中已经于源码了,我们移植驱动的一般做法就是
  1.熟悉这个驱动的platform_driver,知道它的driver_name,还有它需要得到的资源所使用的plateform_data
  2.在bsp中构建这个设备的plateform_device,然后创建相应的resource和plateform_data
 
学习方法:
 1.先找一个驱动,如pwm_bl.c
static struct platform_driver pwm_backlight_driver = {
.driver = {
.name = "pwm-backlight",
.owner = THIS_MODULE,
},
.probe = pwm_backlight_probe,
.remove = pwm_backlight_remove,
.suspend = pwm_backlight_suspend,
.resume = pwm_backlight_resume,
};
2.首先确认其driver name,并全局搜索此名称,如"pwm-backlight"
3.在相应的bsp文件中,可以查找到plateform_devic的定义,可以直接将其copy到自己的文件中,
  如“mach-smdk2440.c”,并修改相应的变量名称。
4.在自己的bsp文件(mach-smdk2440.c)中,加上驱动的头文件(pwm_backlight.h)。
5.这样驱动的probe函数可以通过plateform_data拿到需要的平台数据。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多