Linux驱动学习笔记(六)

平台总线

1.平台总线模型也叫platform总线模型,平台总线是Linux系统虚拟出来的总线, 引入总线的概念可以对驱动代码和设备信息进行分离。平台总线模型将一个驱动分成了两个部分:platform_device和platform_driver,例如可使用文件device.c和driver.c来分别描述这两部分,device.c用来描述硬件,driver.c用来控制硬件,平台总线通过字符串比较来match,将name相同的device.c和driver.c匹配到一起来控制硬件。

2.platform设备驱动(device.c)里面写的是硬件资源,这里的硬件资源指的是寄存器地址,中断号以及其他硬件资源等。在Linux内核里面用struct platform_device结构体来描述硬件资源。这个结构体定义在include/linux/platform_device.h文件当中,如下图:

在struct platform_device中,name为设备名称,总线进行匹配时,会比较设备和驱动的名称是否一致。设备驱动注册成功之后,可以在/sys/bus/platform/devices/目录下看到对应的name;id是一个编号,Linux用这个id来区分同名设备,id会跟在设备名后面以后缀形式显示,若将id设置为-1表示设备名后面没有后缀;id_auto表示是否自动设置id,若设置了设备名后面会跟上auto的后缀;dev表示设备的通用属性部分,struct device结构定义在include/linux/device.h中,必须实现该结构体中的void (*release)(struct device *dev);成员函数,否则驱动会报错;resource用于定义硬件资源信息,struct resource定义在include/linux/ioport.h中,如下图:

在struct resource结构体中,start和end分别表示资源的起始信息和终止信息,name表示存储的资源名,flags表示存储资源的类型,可取下图中的值(只截取了一部分,具体参考include/linux/ioport.h):

struct platform_device中的num_resources记录资源的总个数。/sys/bus/platform/devices/目录下的内容示例如下:

如上图中的alarmtimer.0.auto表示一个名为alarmtimer的设备,编号为0,标号是自动分配的。int platform_device_register(struct platform_device *device)和void platform_device_unregister(struct platform_device *device)函数分别用于注册和卸载platform设备(device.c)(可参考讯为Linux驱动视频第六期P2)。

3.platform设备驱动(driver.c)里面写的是软件驱动,在driver.c文件中首先需要定义一个platform_driver结构体,然后去实现这个结构体中的各个成员变量,当driver.c和device.c匹配成功以后,会执行driver.c里面的probe函数,所以probe函数是必须被实现的。platform_driver定义在include/linux/platform_device.h文件当中,如下图:

struct platform_driver结构体中的probe函数在device.c和driver.c匹配成功时会被自动执行,不论先insmod加载device.ko还是先insmod加载driver.ko都会执行probe函数。remove函数在platform_driver_unregister()被调用时会被执行。id_table用于记录一组待匹配的设备名。struct device_driver定义在include/linux/device/driver.h,它也有一个name成员记录设备名,但是优先级没有id_table高,匹配时会优先使用id_table中的名字。int platform_driver_register(struct platform_driver *driver)和void platform_driver_unregister(struct platform_driver *driver)函数分别用于注册和卸载platform设备(driver.c)。设备驱动注册成功之后,可以在/sys/bus/platform/drivers/目录下看到对应的name(可参考讯为Linux驱动视频第六期P4)。在probe函数中可以通过其实参直接获取platform_device中的硬件信息,也可以通过函数struct resource *platform_get_resource(struct platform_device *,unsigned int,unsigned int);获取,该函数的第一个参数是指向目标platform_device的指针,第二个参数是目标资源的类型,例如IORESOURCE_IRQ,第三个参数是目标资源在同类资源中的索引号(注意是同类资源,索引从0开始,具体可参考讯为Linux驱动视频第六期P6)。可以将平台总线模型与前几期的字符设备、杂项设备、并发与竞争、中断等知识结合起来使用,具体可参考讯为Linux驱动视频第六期P8、P10。

相关推荐
ACP广源盛139246256735 小时前
Type-C 扩展坞方案选型笔记:DP1.4 转 HDMI2.0 桥接方案评估@ACP
笔记·硬件架构·hdmi·国产芯片·扩展坞
Canmag 兴隆磁性6 小时前
中大型钕铁硼产品的磁通测量与自动分选:一条产线自动化的工程实现思路
运维·学习·自动化·永磁材料
ss2738 小时前
AI时代首先数据库-PostgreSQL实战笔记 | 22 PostgreSQL实例与集群
数据库·笔记·postgresql
ss2738 小时前
AI时代首先数据库-PostgreSQL实战笔记 | 21 PostgreSQL进程与内存架构介绍
数据库·笔记·postgresql
小黄人软件8 小时前
桌面需要整理吗?有工具自动分类
学习
水饺编程8 小时前
第2章:Linux 基础,切换到超级用户
linux·c语言·汇编
老衲不用@飘柔9 小时前
SFP与SFP+学习知识整理
学习
便利店10249 小时前
系统活动一抓留存!深入 Linux C/C++ 调试工具之 sysdig
linux·运维·服务器·sysdig
X54先生(人文科技)9 小时前
社会嵌入式终身学习机器与修复时代-ELR架构和技术演化探讨
人工智能·深度学习·学习·架构·开源协议
qetfw9 小时前
Bash 变量:export、位置参数与默认值展开验证
linux·开发语言·chrome·bash