LV09-01-pinctrl和gpio子系统-02-虚拟pinctrl驱动实例
来写一个虚拟的pinctrl子系统的驱动程序?。若笔记中有错误或者不合适的地方,欢迎批评指正😃。
点击查看使用工具及版本
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源码 |
一、编写pinctrl驱动程序要做什么?
1. pinctrl三大作用
- (1)引脚枚举与命名(Enumerating and naming):包括单个引脚和各组引脚。
- (2)引脚复用(Multiplexing):比如用作GPIO、I2C或其他功能。
- (3)引脚配置(Configuration):比如上拉、下拉、open drain、驱动强度等。
2. 做哪些事?
- pin controller:
(1)创建设备树节点

(2)编写驱动程序
- 开发板测试
(1)创建client设备树节点
(2)编写驱动程序
二、编写虚拟pinctrl程序实例
1. 硬件功能
假设这个虚拟的pin controller有4个引脚:

- pin0,1,2,3都可以配置为GPIO功能。
- pin0,1还可以配置为I2C功能。
- pin2,3还可以配置为UART功能。
2. 编写设备树文件
1 | / { |
编译完设备树,就更新到开发板上去。更新成功可以看到如下节点:

3. 驱动程序
3.1 pinctrl驱动
核心是pinctrl_desc:分配、设置和注册pinctrl_desc结构体。这里是一个platform_driver。
3.2 client驱动
编写、注册一个platform_driver即可。
三、调试虚拟的pinctrl
1. 开发板准备
1.1 设备树
前面更新了设备树,注意更新。
1.2 加载驱动
这个需要加载两个驱动:
1 | insmod ./virtual_pinctrl_driver.ko |

1 | insmod ./virtual_pinctrl_client.ko |

2. pinctrl调试信息
开发板的/sys/kernel/debug/pinctrl/
目录下,每一个pin controller都有一个目录,比 virtual_pincontroller。里面有很多文件,作用如下:
pinctrl的虚拟文件 | 作用 |
---|---|
pins | 单个引脚信息 |
pingroups | 引脚的组信息 |
pinmux-pins | 单个引脚的复用信息 |
pinmux-functions | function下的group(支持该function的group) |
pinconf-pins | 单个引脚的配置 |
pinconf-groups | 引脚组的配置 |
pinconf-config | 可以通过写它修改指定设备、指定状态下、指定(组)引脚的config值 |
2.1 单个引脚信息
1 | cat /sys/kernel/debug/pinctrl/virtual_pincontroller/pins |
以刚才我们的设备树为例就是:
1 | cat /sys/kernel/debug/pinctrl/alpha:virtual_pincontroller/pins |

2.2 引脚的组信息
1 | cat /sys/kernel/debug/pinctrl/virtual_pincontroller/pingroups |
以刚才我们的设备树为例就是:
1 | cat /sys/kernel/debug/pinctrl/alpha:virtual_pincontroller/pingroups |

2.3 单个引脚的复用信息
1 | cat /sys/kernel/debug/pinctrl/virtual_pincontroller/pinmux-pins |
以刚才我们的设备树为例就是:
1 | cat /sys/kernel/debug/pinctrl/alpha:virtual_pincontroller/pinmux-pins |

2.4 function下的group(支持该function的group)
1 | cat /sys/kernel/debug/pinctrl/virtual_pincontroller/pinmux-functions |
以刚才我们的设备树为例就是:
1 | cat /sys/kernel/debug/pinctrl/alpha:virtual_pincontroller/pinmux-functions |

2.5 单个引脚的配置
1 | cat /sys/kernel/debug/pinctrl/virtual_pincontroller/pinconf-pins |
以刚才我们的设备树为例就是:
1 | cat /sys/kernel/debug/pinctrl/alpha:virtual_pincontroller/pinconf-pins |

2.6 引脚组的配置
1 | cat /sys/kernel/debug/pinctrl/virtual_pincontroller/pinconf-groups |
以刚才我们的设备树为例就是:
1 | cat /sys/kernel/debug/pinctrl/alpha:virtual_pincontroller/pinconf-groups |

3. 修改配置值
在内核源码中为我们提供了下面的函数来修改配置值
1 | // drivers/pinctrl/pinconf.c |
如果pin controller驱动程序中的pinconf_ops提供了pin_config_dbg_parse_modify函数,就可以通过pinconf-config
文件修改某个pin或某个group的配置值。
1 | 格式: modify <config> <devicename> <state> <pin_name|group_name> <newvalue> |
以上面的设备树为例就是:
1 | echo "modify config_pin virtual_i2c default pin0 0xaabb" > /sys/kernel/debug/pinctrl/alpha:virtual_pincontroller/pinconf-config |

不过上面失败了,没太搞明白为啥,不过这里主要是了解虚拟pinctrl子系统的实例,这里先不管了,后面有需要再说。