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。

相关推荐
Fcy64841 分钟前
Linux下 进程(一)(冯诺依曼体系、操作系统、进程基本概念与基本操作)
linux·运维·服务器·进程
袁袁袁袁满42 分钟前
Linux怎么查看最新下载的文件
linux·运维·服务器
代码游侠1 小时前
学习笔记——设备树基础
linux·运维·开发语言·单片机·算法
Gary Studio1 小时前
rk芯片驱动编写
linux·学习
mango_mangojuice1 小时前
Linux学习笔记(make/Makefile)1.23
java·linux·前端·笔记·学习
Harvey9031 小时前
通过 Helm 部署 Nginx 应用的完整标准化步骤
linux·运维·nginx·k8s
工程师老罗1 小时前
YOLOv1 核心知识点笔记
笔记·yolo
lingggggaaaa1 小时前
安全工具篇&动态绕过&DumpLsass凭据&Certutil下载&变异替换&打乱源头特征
学习·安全·web安全·免杀对抗
PP东2 小时前
Flowable学习(二)——Flowable概念学习
java·后端·学习·flowable
学电子她就能回来吗2 小时前
深度学习速成:损失函数与反向传播
人工智能·深度学习·学习·计算机视觉·github