Linux驱动:module_platform_driver

甄文彬
2023-12-01

该宏是用来定义驱动的入口函数

使用方法:

include <linux/platform_device.h>

static struct platform_driver power_supply_driver ={
      .driver  = { 
        .name = "power-supply",
        .owner = THIS_MODULE,
        .of_match_table = power_supply_id_table,
    },
    .probe   = power_supply_probe,
    .remove  = power_supply_remove,
    .suspend = power_supply_suspend,
    .resume  = power_supply_resume,
}


module_platform_driver(power_supply_driver)

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;
    bool prevent_deferred_probe;
 };

原理:

  • module_platform_driver :
#define module_platform_driver(__platform_driver) \
    module_driver(__platform_driver, platform_driver_register, \
            platform_driver_unregister)

上面的宏定义展开如下:

module_driver(power_supply_driver, platform_driver_register, \
            platform_driver_unregister)

  • module_driver
    定义:linux/device.h
#define module_driver(__driver, __register, __unregister, ...) \
static int __init __driver##_init(void) \
{ \
    return __register(&(__driver) , ##__VA_ARGS__); \
} \
module_init(__driver##_init); \
static void __exit __driver##_exit(void) \
{ \
    __unregister(&(__driver) , ##__VA_ARGS__); \
} \
module_exit(__driver##_exit);

展开规则:

 __driver         ----->    power_supply_driver
 __register      ----->   platform_driver_unregister
 __unregister  ----->   platform_driver_register
 __VA_ARGS__ ----->  .....

注意

    C99 引入了对参数个数可变的函数式宏的正式支持。在宏原型的末尾加上符号 ... (就像在参数可变的函数定义中), 宏定义中的伪宏__VA_ARGS__ 就会在调用是 替换成可变参数。
    ##__VA_ARGS__
    当可变参数...的个数为0 时,'##'操作将使预处理器(preprocessor)去除掉它前面的那个逗号,保证编译能够通过

所以上面的方法最终形式如下:


 static int __init power_supply_driver_init(void)
 {
   return platform_driver_register(&(power_supply_driver) );
 }
module_init(power_supply_driver_init); 
static void __exit power_supply_driver_exit(void) 
{ 
    platform_driver_unregister(&(power_supply_driver) ); 
} 
module_exit(power_supply_driver_exit);

结论

驱动中使用module_platform_driver 来注册驱动 跟自定义module_init &&module_exit 的结果是一致的,module_platform_driver 更加简洁,推荐使用

 类似资料: