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


一、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;//列表--用于匹配(优先用于匹配)
    }
        
    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 初级驱动操作函数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值