文章目录
- 前言
- 一、什么是平台总线?
- 二、平台总线相关的结构体
- 三、平台总线的注册和注销
- 四、总线平台的框架
- 总结
前言
一个完整的驱动程序总是由三部分组成:设备、总线、驱动
设备就好比我们的硬件:比如oled ,那么总线就相当于iic总线,驱动就是我们编写的控制oled的代码。
那么今天要讲的平台总线又是什么呢?
一、什么是平台总线?
在 Linux 2.6 以后的设备驱动模型中,需关心总线、设备和驱动这 3 个实体,总线将设备和驱动绑定。在系统每注册一个设备的时候,会寻找与之匹配的驱动;相反的,在系统每注册一个驱动的时候,会寻找与之匹配的设备,而匹配由总线完成。
Linux 发明了一种虚拟的总线,称为 platform 总线,相应的设备称为 platform_device,而驱动成为 platform_driver。
平台总线模型就是把原来的驱动 C 文件给分成了两个 C 文件,一个是 device.c,一个是 driver.c 把稳定不变的放在 driver.c 里面,需要变得就放在了 device.c 里面
一般模型如下:
如果我们使用的设备树,那么device.c部分就会换成设备树用来描述硬件资源。
二、平台总线相关的结构体
在 Linux 内核中,用 platform_driver
结构体表示 platform 驱动,platform_driver 结构体定义指定名称的平台设备驱动注册函数和平台设备驱动注销函数
struct platform_driver {
/*当 driver 和 device 匹配成功的时候,就会执行 probe 函数*/
int (*probe)(struct platform_device *);
/*当 driver 和 device 任意一个 remove 的时候,就会执行这个函数*/
int (*remove)(struct platform_device *);
/*当设备收到 shutdown 命令的时候,就会执行这个函数*/
void (*shutdown)(struct platform_device *);
/*当设备收到 suspend 命令的时候,就会执行这个函数*/
int (*suspend)(struct platform_device *, pm_message_t state);
/*当设备收到 resume 命令的时候,就会执行这个函数*/
int (*resume)(struct platform_device *);
// 内置的 device_driver 结构体
struct device_driver driver;
// 该设备驱动支持的设备的列表 他是通过这个指针去指向 platform_device_id 类型的数组
const struct platform_device_id *id_table;
bool prevent_deferred_probe;
};
其中用的最多的就是int (*probe)(struct platform_device *);
这个是总线匹配设备和驱动成功后进入的函数,struct device_driver driver;
这个结构体是用来描述设备驱动的,具体如下:
struct device_driver {
const char *name;
struct bus_type *bus;
struct module *owner;//通常是THIS_MODULE
const char *mod_name; /* used for built-in modules */
bool suppress_bind_attrs; /* disables bind/unbind via sysfs */
enum probe_type probe_type;
const struct of_device_id *of_match_table; //用来匹配设备树
const struct acpi_device_id *acpi_match_table;
int (*probe) (struct device *dev);
int (*remove) (struct device *dev);
void (*shutdown) (struct device *dev);
int (*suspend) (struct device *dev, pm_message_t state);
int (*resume) (struct device *dev);
const struct attribute_group **groups;
const struct dev_pm_ops *pm;
void (*coredump) (struct device *dev);
struct driver_private *p;
};
三、平台总线的注册和注销
注册:
platform_driver_register
注销:
platform_driver_unregister
四、总线平台的框架
在之前的Linux中,还没有设备树,所以平台总线的框架也是要写两个.c文件,一个是device.c,另个就是我们的driver.c,它们之间是通过总线进行匹配的,如下:
名字相同的时候,当两个文件都加载到内核中就会自动匹配成功。
现在的话是使用设备树来替代device.c,如下:
这两个匹配成功之后就会进入probel函数
一般编写流程如下:
注册平台总线----->完善平台总线结构体-------->设置设备树--------->匹配成功之后进入probel函数------>编写自己代码
总结
平台总线是个虚拟的总线,并不是真实存在的,但是确实能够起到设备和驱动分离的效果,在以后有的驱动中基本上要和这个总线见面,所以掌握平台总线,还是很有必要。