LV06-05-linux平台总线模型-04-驱动和设备资源的获取
前面我们已经知道了怎么让平台设备和平台驱动进行匹配,那么匹配的目录肯定是驱动获取设备中的资源了,那怎么获取?设备能获取驱动的信息吗,能的话,又该怎么获取呢?若笔记中有错误或者不合适的地方,欢迎批评指正😃。
点击查看使用工具及版本
PC端开发环境 | Windows | Windows11 |
Ubuntu | Ubuntu20.04.2的64位版本 | |
VMware® Workstation 17 Pro | 17.6.0 build-24238078 | |
终端软件 | MobaXterm(Professional Edition v23.0 Build 5042 (license)) | |
Win32DiskImager | Win32DiskImager v1.0 | |
Linux开发板环境 | Linux开发板 | 正点原子 i.MX6ULL Linux 阿尔法开发板 |
uboot | NXP官方提供的uboot,使用的uboot版本为U-Boot 2019.04 | |
linux内核 | linux-4.19.71(NXP官方提供) |
点击查看本文参考资料
分类 | 网址 | 说明 |
官方网站 | https://www.arm.com/ | ARM官方网站,在这里我们可以找到Cotex-Mx以及ARMVx的一些文档 |
https://www.nxp.com.cn/ | NXP官方网站 | |
https://www.nxpic.org.cn/ | NXP 官方社区 | |
https://u-boot.readthedocs.io/en/latest/ | u-boot官网 | |
https://www.kernel.org/ | linux内核官网 |
点击查看相关文件下载
分类 | 网址 | 说明 |
NXP | https://github.com/nxp-imx | NXP imx开发资源GitHub组织,里边会有u-boot和linux内核的仓库 |
nxp-imx/linux-imx/releases/tag/v4.19.71 | NXP linux内核仓库tags中的v4.19.71 | |
nxp-imx/uboot-imx/releases/tag/rel_imx_4.19.35_1.1.0 | NXP u-boot仓库tags中的rel_imx_4.19.35_1.1.0 | |
I.MX6ULL | i.MX 6ULL Applications Processors for Industrial Products | I.MX6ULL 芯片手册(datasheet,可以在线查看) |
i.MX 6ULL Applications ProcessorReference Manual | I.MX6ULL 参考手册(下载后才能查看,需要登录NXP官网) | |
Source Code | https://elixir.bootlin.com/linux/latest/source | linux kernel源码 |
kernel/git/stable/linux.git - Linux kernel stable tree | linux kernel源码(官网,tag 4.19.71) | |
https://elixir.bootlin.com/u-boot/latest/source | uboot源码 |
一、设备获取驱动的资源
前面在学习平台设备和平台驱动的时候,我们有看到这个 struct platform_device_id 结构体,它在 struct platform_device 和 struct platform_driver 都有,设备获取驱动资源可以通过这个来进行,接下来就来了解一下吧。
1. struct platform_device_id
先来回顾一下这个结构体,struct platform_device_id 结构体定义如下:
1 | struct platform_device_id { |
在 struct platform_device_id 这个结构体中,有两个成员,第一个是数组用于指定驱动的名称,总线进行匹配时,会依据该结构体的name成员与 struct platform_device 中的成员name进行比较匹配, 另一个成员变量driver_data,则是用于来保存设备的配置。我们知道在同系列的设备中,往往只是某些寄存器的配置不一样,为了减少代码的冗余, 尽量做到一个驱动可以匹配多个设备的目的。
2. 平台设备怎么得到这个结构体数据?
前面学习id匹配的时候,完成id匹配的是这个 platform_match_id() 函数:
1 | static const struct platform_device_id *platform_match_id( |
我们可以看一下传进来的都是什么:

可以看到,传进来的指针 id 指向的是 platform_driver.id_table,而指针 pdev则是 platform_device 。在函数内部,遍历 platform_driver.id_table 中的成员,当 platform_driver.id_table[i].name和 platform_device.name 匹配的相等的时候,就将platform_device.id_entry 这个指针指向 platform_driver.id_table[i] 的地址:

当匹配成功的时候,我们就可以以访问 platform_device.id_entry 来获取驱动中的数据了,即访问平台设备的platform_device.id_entry.driver_data 成员就是访问平台驱动的 platform_driver.id_table[i].driver_data 成员。
3. 应用场景
可以以以imx的串口为例,具体看下这个结构体的作用:
1 | static struct imx_uart_data imx_uart_devdata[] = { |
在上面的代码中,支持三种设备的串口,支持imx1、imx21、imx6q三种不同系列芯片,他们之间区别在于串口的test寄存器地址不同。 当总线成功配对平台驱动以及平台设备时,会将对应的id_table条目赋值给平台设备的id_entry成员,而平台驱动的probe函数是以平台设备为参数, 这样的话,就可以拿到当前设备串口的test寄存器地址了。
4. 设备获取驱动资源demo
4.1 demo源码
06_platform_bus/05_id_match_get_drv_info · 苏木/imx6ull-driver-demo - 码云 - 开源中国
4.2 开发板验证
将编译完的sdriver_demo.ko、sdevice_demo.ko拷贝到开发板,然后执行以下命令加载:
1 | insmod sdriver_demo.ko |
然后就会看到以下打印信息:

可以看到驱动中的xxx_probe()函数执行,然后会有提示驱动和设备匹配成功。为了方便查看平台设备获取驱动中资源的情况,我们可以看一下 /sys/bus/platform/devices/sdev 中的属性文件的值:
1 | cat /sys/bus/platform/devices/sdev/sdev_attr_reg |

其实可以在匹配之前看一下的:

二、驱动获取设备资源
1. 怎么获取设备资源?
这个就比较简单了,因为传到驱动中的是平台设备的哪个全局变量,我们可以直接访问平台设备的资源数组。
1 | static int sdrv_probe(struct platform_device *pdev) |
例如上面的sdrv_probe()函数,我们可以通过 pdev 直接访问的,也就是说 pdev直接指向这个对象:
1 | /** |
通过 platform_device.resource 就可以获取资源数组中所有数据,通过 platform_device.num_resources可以获取到设备一共有多少个资源。
2. 获取资源的函数
linux内核提供了几个函数来帮我们获取资源。其实前面都了解设备信息的时候都了解过了,就那几个函数。
2.1 platform_get_resource()
platform_get_resource() 定义如下:
1 | struct resource *platform_get_resource(struct platform_device *dev, |
该函数返回该 dev 中某类型(type)资源中的第几个(num,其中num的值从0开始) 。
2.2 platform_get_irq()
platform_get_irq() 函数定义如下:
1 | /** |
返回该 dev 所用的第几个(num)中断。
2.3 platform_get_resource_byname()
platform_get_resource_byname() 定义如下:
1 | /** |
通过名字(name)返回该 dev 的某类型(type)资源。
2.4 platform_get_irq_byname()
1 | /** |
通过名字(name)返回该 dev 的中断号。
2.5 dev_get_platdata()
对于存放在device结构体中成员platform_data的软件信息,我们可以使用dev_get_platdata() 函数来获取:
1 | static inline void *dev_get_platdata(const struct device *dev) |
2.6 resource_size()
resource_size()函数用于获取资源的大小,定义如下:
1 | static inline resource_size_t resource_size(const struct resource *res) |
3. 驱动获取设备资源demo
3.1 demo源码
06_platform_bus/06_drv_get_dev_resource · 苏木/imx6ull-driver-demo - 码云 - 开源中国
3.2 开发板验证
将编译完的sdriver_demo.ko、sdevice_demo.ko拷贝到开发板,然后执行以下命令加载:
1 | insmod sdriver_demo.ko |
然后就会看到以下打印信息:

可以看到驱动中的xxx_probe()函数执行,然后会有提示驱动和设备匹配成功。然后便会在xxx_probe()函数中分两种方式打印出从平台设备获取的资源。