您的位置:首页 > 其它

platform 学习笔记——初次接触(1)

2016-11-21 19:20 453 查看
一、platform_device 编程

    1、驱动程序入口出口函数:

        module_init(led_plat_dev_init);

        module_exit(led_plat_dev_exit);

        MODULE_LICENSE("GPL");

    2、编写init和exit框架

        staic int __init led_plat_dev_init(void)

        {

            

        }

        static void __exit led_plat_dev_exit(void)

        {

        }

    3、platform_device结构体成员

        

            struct platform_device

        

    填充platform_device成员:include\linux\platform_device.h

        struct platform_device {

            const char    * name;//名字--用于匹配

            int        id;// 表示不同的控制器组--一般为-1

            struct device    dev;//父类

            u32        num_resources;//资源的个数

            struct resource    * resource;//资源

            const struct platform_device_id    *id_entry;

            /* MFD cell pointer */

            struct mfd_cell *mfd_cell;

            /* arch specific additions */

            struct pdev_archdata    archdata;

        };

        

        //示例:

        struct platform_device led_pdev = {

            .name = "s5pv210_led",

            .id = -1,

            .num_resources = ARRAY_SIZE(led_res),

            .resource = led_res,

            

        }

        

    4、构建resource结构体

        struct resource {

            resource_size_t start; //起始位置

            resource_size_t end;//结束位置

            const char *name;//名字自定义

            unsigned long flags;//区分中断资源还是地址资源

            struct resource *parent, *sibling, *child;

        };

        

        //示例:

            struct resource  led_res[] = {

            [0] = {

                .start = LED_PHY_ADDR,

                .end = LED_PHY_ADDR_LEN + LED_PHY_ADDR -1,

                .name = "GPC0_3_4",

                .flags = IORESOURCE_MEM,

            },

            [1] = {

                .start = 888,

                .end = 888,

                .name = "test_irq",

                .flags = IORESOURCE_IRQ,

            },

            [2] = {

                .start = 0x12345678,

                .end  = 0x12345678 + 4 -1,

                .name = "test_mem" ,

                .flags = IORESOURCE_MEM ,

            },

        };

        

        include\linux\platform_device.h

        此头文件包含platform device的注册与注销函数:

        extern int platform_device_register(struct platform_device *);

        extern void platform_device_unregister(struct platform_device *);

        

        //示例:

            staic int __init led_plat_dev_init(void)

        {

             return platform_device_register(&led_pdev);

        }

        static void __exit led_plat_dev_exit(void)

        {

            return platform_device_unregister(&led_pdev);

        }

        

二、platform_driver 编程

1、声明驱动入口和出口函数:

    module_init(led_plat_drv_init);

    module_exit(led_plat_drv_exit);

    MODULE_LICENSE("GPL");

    

2、编写init和exit框架

        static int __init led_plat_drv_init(void)

    {

        

    }

    static void __exit led_plat_drv_exit(void)

    {

        

    }

    

3、platform_driver注册和注销

    

    //示例:

        static int __init led_plat_drv_init(void)

    {

        return platform_driver_register(&led_pdrv);

    }

    static void __exit led_plat_drv_exit(void)

    {

        return platform_driver_unregister(&led_pdrv);

    }

    

4、填充struct platform_driver结构体

    struct platform_driver {

        int (*probe)(struct platform_device *);//匹配成功之后被调用

        int (*remove)(struct platform_device *);//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;//列表--用于匹配(优先用于匹配)

    }

     
9c7f
   

    struct device_driver {

        const char        *name;    //Name of the device driver设备驱动的名字

        struct bus_type        *bus;    //The bus which the device of this driver belongs to此驱动属于哪一个设备总线

        struct module        *owner;    //The module owner 模块所有者

        const char        *mod_name;    /* used for built-in modules 用于编译进模块 */

        bool suppress_bind_attrs;    /* disables bind/unbind via sysfs */

        const struct of_device_id    *of_match_table;    //The open firmware table 打开固件表

        int (*probe) (struct device *dev);    /*Called to query the existence of a specific device whether this driver can work with it, and bind the driver to a specific device.回调与驱动相匹配的指定设备,并绑定驱动到指定设备*/    

        int (*remove) (struct device *dev);        /*Called when the device is removed from the system to unbind a device from this driver*/

        void (*shutdown) (struct device *dev);    //Called at shut-down time to quiesce the device

        int (*suspend) (struct device *dev, pm_message_t state);    /*    Called to put the device to sleep mode. Usually to a low power state*/

        int (*resume) (struct device *dev);    //Called to bring a device from sleep mode

        const struct attribute_group **groups;    //Default attributes that get created by the driver core automatically

        const struct dev_pm_ops *pm;    //Power management operations of the device which matched this driver

        struct driver_private *p;    //Driver core's private data, no one other than the driver core can touch this.

    }

    

    //示例:

    struct platform_driver led_pdrv = {

    .probe = led_pdrv_probe,

    .remove = led_pdrv_remove,

    .driver = {

        .name = "Samsung led_drv",

    },

    .id_table = led_id_table,

}

struct platform_device_id led_id_table[] ={

    {"s3c2410_led", 0x22222},

    {"s5pv210_led", 0x55555},

    {"exynos4412_led", 0x4444},

}

int led_pdrv_probe(struct platform_device *pdev)

{

    led_dev = kzalloc(sizeof(struct s5pv210_led), GFP_KERNEL);

    led_dev->major = register_chrdev( 0, "plat_led_drv", &led_fops);

    led_dev->cls = class_create(THIS_MODULE, "led_cls");

    led_dev->dev = device_create(led_dev->cls, NULL,

                     MKDEV(led_dev->major, 0), NULL, "led0");

    led_dev->mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

    led_dev->reg_virt_base = ioremap(led_dev->mem_res->start,  resource_size(led_dev->mem_res));

    int irqno = platform_get_irq(pdev, 0);

    return 0;

}

int led_pdrv_remove(struct platform_device *pdev)

{

    iounmap(led_dev->reg_virt_base);

    device_destroy(led_dev->cls,MKDEV(led_dev->major, 0));

    class_destroy(led_dev->cls);

    unregister_chrdev(led_dev->major, "plat_led_drv");

    kfree(led_dev);

    return 0;

}

5、编程:struct file_operations 初级驱动操作函数
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: