- 积分
- 115
- 鸿鹄币
- 个
- 好评度
- 点
- 精华
- 注册时间
- 2022-7-25
- 最后登录
- 1970-1-1
- 阅读权限
- 20
- 听众
- 收听
助理工程师
|
今天主要和大家聊一聊,如何理解Linux内核中平台驱动总线的使用方法。
第一:Platform总线介绍
总线代表着同类设备需要共同遵循的工作时序,不同的总线对于物理电平的要求是不一样的,对于每个比特的电平维持宽度也是不一样的,总线上传递的命令也会有自己的格式约束。
在Linux系统中总线可分为两种,
1、一种是实际存在的总线(例如I2C、SPI、USB等总线)。
2、另一种是虚拟存在的总线(platform总线)。
为什么需要虚拟的platform总线?
这是因为在嵌入式系统里面SOC系统中集成的独立的外设控制器,挂接在SOC内存空间的外设等无法依附于第一种总线,所以基于这一背景,Linux发明了platform总线。
第二:Platform总线的数据结构
1、platform_bus_type总线注册
设备和驱动需要挂载在总线上,要先指明设备和驱动是属于哪条总线的,所以设备与驱动需要注册,而总线在Linux系统中也是属于设备,所以总线也要注册,同时因为设备和驱动要挂载在总线上,所以总线要先注册。
文件:driver/base/platform.c
struct bus_type platform_bus_type = {
.name = "platform",
.dev_attrs = platform_dev_attrs, //设备属性
.match = platform_match, //match函数
.uevent = platform_uevent, //热拔插操作函数
.pm = &platform_dev_pm_ops, //休眠唤醒操作集
};
次结构体通过platform_bus_init函数进行注册
2、platform_device结构体
此结构体通过platform_add_devices函数进行注册
目录: include\linuxplatform_device.h
struct platform_device {
const char * name; //设备名字
int id; //一个设备为-1,多于一个则从 0 开始增加
struct device dev; //设备结构体
u32 num_resources; //所拥有的资源数量,
struct resource * resource; //资源存放的指针
}
从中可以看出它是 device的子类,name用于驱动邦定,还有需要何种资源。定义(resouce后,系统启动时完成对硬件资源的规划,硬件不会获得规划以外的资源,减少的冲突。
其中resource结构体表明该平台设备所需要的资源(IRQ、内存、DMA或I0),具体结构如下:
struct resource {
const char *name; //向内核注册的资源名
unsigned long start, end; //资源开始,结束地址,只有一个则 start 与 end 相同
unsigned long flags; //表明资源的类型,目前支持 IRQ 以及内存
struct resource *parent, *sibling, *child; //资源在内核中的组织关系的节点
}
3、platform_driver结构体
platform_driver除了driver结构体外,还定义了一些函数,这些函数与结构体driver_device中的函数意义一样,只不过它们的输入参数变成了platform_device。具体结构如下所示
文件:include/linux/device.h
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 (*suspend_late)(struct platform_device *, pm_message_t state);
int (*resume_early)(struct platform_device *);
int (*resume)(struct platform_device *);
struct pm_ext_ops *pm;
const struct platform_device_id *id_table;
struct device_driver driver;
(1)、probe探测函数,如果驱动匹配到了目标设备,总线会自动回调probe函数,必须实现。
(2)、remove释放函数,如果匹配到的设备从总线移除了,总线会自动回调remove函数,必须实现
(3)、device_driver是platform_driver的父类
(4)、id_table设备信息
此结构体使用platform_driver_register注册
总结:Linux内核中平台设备总线是非常重要的,掌握核心结构体的注册方法,方能走的更远。
|
|