一、ID匹配之框架代码
id匹配(可想象成八字匹配):一个驱动可以对应多个设备 ------优先级次低
注意事项:
-
device模块中,id的name成员必须与struct platform_device中的name成员内容一致,因此device模块中,struct platform_device中的name成员必须指定
-
driver模块中,struct platform_driver成员driver的name成员必须指定,但与device模块中name可以不相同
/*platform device框架*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
//定义资源数组
static void device_release(struct device *dev)
{printk("platform: device release\n");
}
struct platform_device_id test_id = {.name = "test_device",
};
struct platform_device test_device = {.name = "test_device",//必须初始化.dev.release = device_release, .id_entry = &test_id,
};
static int __init platform_device_init(void)
{platform_device_register(&test_device);return 0;
}
static void __exit platform_device_exit(void)
{platform_device_unregister(&test_device);
}
module_init(platform_device_init);
module_exit(platform_device_exit);
MODULE_LICENSE("Dual BSD/GPL");
/*platform driver框架*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
static int driver_probe(struct platform_device *dev)
{printk("platform: match ok!\n");return 0;
}
static int driver_remove(struct platform_device *dev)
{printk("platform: driver remove\n");return 0;
}
struct platform_device_id testdrv_ids[] =
{[0] = {.name = "test_device"},[1] = {.name = "abcxyz"},[2] = {}, //means ending
};
struct platform_driver test_driver = {.probe = driver_probe,.remove = driver_remove,.driver = {.name = "xxxxx", //必须初始化},.id_table = testdrv_ids,
};
static int __init platform_driver_init(void)
{platform_driver_register(&test_driver);return 0;
}
static void __exit platform_driver_exit(void)
{platform_driver_unregister(&test_driver);
}
module_init(platform_driver_init);
module_exit(platform_driver_exit);
MODULE_LICENSE("Dual BSD/GPL");
用到结构体数组,一般不指定大小,初始化时最后加{}表示数组结束
设备中增加资源,驱动中访问资源
二、ID匹配之led驱动
三、设备树匹配
设备树匹配:内核启动时根据设备树自动产生的设备 ------ 优先级最高
注意事项:
-
无需编写device模块,只需编写driver模块
-
使用compatible属性进行匹配,注意设备树中compatible属性值不要包含空白字符
-
id_table可不设置,但struct platform_driver成员driver的name成员必须设置
/*platform driver框架*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
static int driver_probe(struct platform_device *dev)
{printk("platform: match ok!\n");return 0;
}
static int driver_remove(struct platform_device *dev)
{printk("platform: driver remove\n");return 0;
}
struct platform_device_id testdrv_ids[] =
{[0] = {.name = "test_device"},[1] = {.name = "abcxyz"},[2] = {}, //means ending
};
struct of_device_id test_of_ids[] =
{[0] = {.compatible = "xyz,abc"},[1] = {.compatible = "qwe,opq"},[2] = {},
};
struct platform_driver test_driver = {.probe = driver_probe,.remove = driver_remove,.driver = {.name = "xxxxx", //必须初始化.of_match_table = test_of_ids,},
};
static int __init platform_driver_init(void)
{platform_driver_register(&test_driver);return 0;
}
static void __exit platform_driver_exit(void)
{platform_driver_unregister(&test_driver);
}
module_init(platform_driver_init);
module_exit(platform_driver_exit);
MODULE_LICENSE("Dual BSD/GPL");
四、设备树匹配之led驱动
五、一个编写驱动用的宏
struct platform_driver xxx = { ...
};
module_platform_driver(xxx);
//最终展开后就是如下形式:
static int __init xxx_init(void)
{return platform_driver_register(&xxx);
}
module_init(xxx_init);
static void __exit xxx_init(void)
{return platform_driver_unregister(&xxx);
}
module_exit(xxx_exit)
;