Linux 中的 Platform 总线是虚拟总线, 它把驱动和设备的注册都分开来, 对于他们的牵红线 (匹配) 过程, 提供了 "总线 - 设备 - 驱动" 模型.
它的结构如下图所示:
为什么要这么做?
试想, 如果设备和驱动不分开, 那么不同设备将会产生大量驱动(代码冗余), 而且维护起来工作量很大.
Platform 模型则把稳定不变的部分放在 driver, 把尽量可变需要设置的部分放到 device 端, 并且两边分别注册管理.
这样做有如下好处:
平台设备都挂在一条 Platform 总线上
设备和驱动代码隔离, 可移植性和扩展性强
适用范围
适用于可选的平台资源, 例如灯, 按键, LCD 等
常用 API
注册设备
int platform_device_register(struct platform_device *pdev);
注销设备
void platform_device_unregister(struct platform_device *pdev);
注册驱动
int platform_driver_register(struct platform_driver *drv);
注销驱动
void platform_driver_unregister(struct platform_driver *drv);
获取平台资源
- struct resource *platform_get_resource(struct platform_device *dev, unsigned int type, unsigned int num);
- int platform_get_irq(struct platform_device *dev, unsigned int num);
- struct resource *platform_get_resource_byname(struct platform_device *dev, unsigned int type, const char *name);
- int platform_get_irq_byname(struct platform_device *dev, const char *name);
基本使用
设备端注册
- /************************ arch/xxx/xxx_platform.c ************************/
- static void device_release(struct device *dev)
- {
- }
- static struct resource xxx_res[]={
- [0]={
- .start = 11,
- .end = 22,
- .flags = IORESOURCE_MEM,
- },
- [1]={
- .start = 33,
- .end = 44,
- .flags = IORESOURCE_IRQ,
- },
- };
- struct platform_device xxx_device = {
- .id = -1,
- .name = "xxx_device"
- .resource = xxx_res,
- .num_resources = ARRAY_SIZE(xxx_res);
- .dev = {
- .release = device_release, /* 一般要有改函数, 否则驱动卸载会异常 */
- },
- };
- static int __init xxx_platform_init(void)
- {
- return platform_device_register(&xxx_device);
- }
- static void __exit xxx_platform_exit(void)
- {
- platform_device_unregister(&xxx_device);
- }
- module_init(xxx_platform_init);
- module_exit(xxx_platform_exit);
驱动注册
- /************************ driver/xxx/xxx_driver.c ************************/
- static int driver_probe(struct platform_device *dev)
- {
- struct resource * res = platform_get_resource(dev, IORESOURCE_MEM, 0);
- ...
- res=platform_get_resource(dev,IORESOURCE_IRQ,0);
- ...
- return 0;
- }
- static int driver_remove(struct platform_device *dev)
- {
- return 0;
- }
- static sturct platform_driver xxx_driver = {
- .probe = driver_probe,
- .remove = driver_remove,
- .driver = {
- .name = "xxx_device"
- },
- };
- static int __init xxx_driver_init(void)
- {
- return platform_driver_register(&xxx_driver);
- }
- static void __exit xxx_driver_exit(void)
- {
- platform_driver_unregister(&xxx_driver);
- }
- module_init(xxx_driver_init);
- module_exit(xxx_driver_exit);
实现原理
TBD
来源: http://www.bubuko.com/infodetail-2990073.html