• platform设备模型


    1.platform设备模型
        从Linux 2.6起引入了一套新的驱动管理和注册机制,platform_device和platform_driver,Linux中大部分的设备驱动都可以使用这套机制。platform是一条虚拟的总线。设备用platform_device表示,驱动用platform_driver进行注册,Linux platform driver机制和传统的device driver机制(通过driver_register进行注册)相比,一个明显的优势在于platform机制将设备本身的资源注册进内核,由内核统一管理,在驱动中使用这些资源时通过platform device提供的标准结构进行申请并使用。这样提高了驱动和资源的独立性,并且具有较好的可移植性和安全性(这些标准接口是安全的)。

        pltform机制本身使用并不复杂,由两部分组成:platform_device和platform_driver。通过platform机制开发底层驱动的大致流程为:定义platform_deive->注册platform_device->定义platform_driver->注册platform_driver。

        首先要确认的就是设备的资源信息,例如设备的地址,中断号等。

    1)platform_device
    在 2.6 内核中 platform 设备用结构体 platform_device 来描述,该结构体定义在 kernel/include/linux/platform_device.h 中,

    structplatform_device {

     const char * name;

     u32  id;

     struct device dev;

     u32  num_resources;

     struct resource * resource;

    };

    该结构一个重要的元素是resource ,该元素存入了最为重要的设备资源信息,定义在kernel/include/linux/ioport.h 中,

    structresource {

     const char *name;//资源的名称

     unsigned long start, end;//资源起始的和结束的物理地址

     unsigned long flags;//资源的类型,比如MEM,IO,IRQ类型

     struct resource *parent, *sibling, *child;//资源链表的指针

    };

    structplatform_device的分配使用

    structplatform_device *platform_device_alloc(const char *name, int id)

    name是设备名,id,设备id,一般为-1,如果是-1,表示同样名字的设备只有一个

    注册平台设备,使用函数

    int  platform_device_add(struct platform_device *pdev)

    注销使用

    void  platform_device_unregister(struct platform_device *pdev)

    2)platform_driver
    在平台设备驱动中获取平台设备资源使用

    structresource *platform_get_resource(struct platform_device *dev, unsigned int type,unsigned int num)

    该函数用于获取dev设备的第num个类型为type的资源,如果获取失败,则返回NULL。例如 platform_get_resource(pdev,IORESOURCE_IRQ, 0)。

    平台驱动描述使用

    structplatform_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 (*suspend_late)(struct platform_device *, pm_message_t state);

     int (*resume_early)(struct platform_device *);

     int (*resume)(struct platform_device *);

     struct device_driver driver;

    };

    Probe()函数必须验证指定设备的硬件是否真的存在,probe()可以使用设备的资源,包括时钟,platform_data等,Platform driver可以通过下面的函数完成对驱动的注册:

    int platform_driver_register(structplatform_driver *drv);一般来说设备是不能被热插拔的,所以可以将probe()函数放在init段里面来节省driver运行时候的内存开销:

    int platform_driver_probe(struct platform_driver *drv, int (*probe)(structplatform_device *));

    注销使用void  platform_driver_unregister(struct platform_driver *drv)

    2.中断处理
    在Linux驱动程序中,为设备实现一个中断包含 两个步骤1.向内核注册(申请中断)中断 2.实现中断处理函数

    request_irq用于实现中断的注册

    int  request_irq(unsigned in irq, void(*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void*dev_id)

    向内核申请中断号为irq,中断处理函数为handler指针指向的函数,中断标志为flag,设备名为devname的中断。成功返回0,或者返回一个错误码。

    当request_irq不用于共享中断时,dev_id可以为NULL,或者指向驱动程序自己的私有数据。但用于共享中断时dev_id必须唯一。因为free_irq时也需要dev_id做参数,这样free_irq才知道要卸载共享中断上哪个中断服务处理函数。共享中断会在后面讲到。

    在flag参数中,可以选以下参数

    IRQF_DISABLED(SA_INTERRUPT)

    如果设置该位,表示是一个“快速”中断处理程序,如果没有,那么就是一个“慢速”中断处理程序。

    IRQF_SHARED(SA_SHITQ)

    该位表示中断可以在设备间共享。

    快速/慢速中断

    这两种类型的中断处理程序的主要区别在于:快速中断保证中断处理的原子性(不被打断),而慢速中断则不保证。换句话说,也就是开启中断标志位在运行快速中断处理程序时

    关闭的,因此在服务该中断时,不会被其他类型的中断打断;而调用慢速中断处理时,其他类型中断扔可以得到服务。

        共享中断

    共享中断就是将不同的设备挂到同一个中断信号线上。linux对共享的支持主要是位PCI设备服务。

    释放中断

    void  free_irq(unsigned int irq)

    当设备不再需要使用中断时(通常是设备关闭和驱动卸载时),应该使用该函数把他们返回给内核使用。

    禁用中断

    void  disable_irq(int irq)

    当一些代码中不能使用中断时(如支持自旋锁的上下文中)使用该函数禁用中断。

    启用中断

    void  enable_irq(int irq)

    当禁止后可以使用该函数重新启用。

  • 相关阅读:
    window查看已保存过的wifi的密码
    js 多个数组取交集
    macOS APP 窗口焦点监听
    proxifier注册码
    天才算法之睡眠排序(C#实现)
    Tomcat 7使用AJP协议设置问题
    nginx启动报错(1113: No mapping for the Unicode character exists in the target multi-byte code page)
    八皇后的n种放置方法
    insufficient permission for adding an object to repository database .git/objects
    centos下搭建php开发环境(lamp)
  • 原文地址:https://www.cnblogs.com/zhou2011/p/3013600.html
Copyright © 2020-2023  润新知