RK3588 UART引脚复用配置实战:从Pinctrl原理到设备树修改

发布时间:2026/5/20 15:55:57

RK3588 UART引脚复用配置实战:从Pinctrl原理到设备树修改 1. 项目概述与核心价值最近在RK3588平台上做开发特别是像ELF 2这样的紧凑型开发板引脚资源总是捉襟见肘。一个典型的场景是当你需要连接多个串口设备比如GPS模块、4G/5G模块、调试串口或者与其他微控制器通信时板载的硬件UART接口数量可能不够用。这时候引脚复用功能就成了解决问题的关键。RK3588作为一款高性能的SoC其引脚功能复用能力非常强大但配置起来也相对复杂新手很容易在这里踩坑。这篇帖子我就以ELF 2开发板为例手把手带你走一遍UART引脚复用的完整配置流程。这不仅仅是改个设备树节点那么简单我会深入拆解RK3588的引脚控制器Pinctrl机制解释为什么需要这样配置以及在配置过程中可能遇到的“坑”和应对技巧。无论你是刚接触RK3588的新手还是想深入了解其IO子系统工作原理的开发者相信都能从中获得实用的参考。我们的目标很明确让你不仅能配置成功更能理解背后的原理做到举一反三灵活应对其他引脚复用需求。2. RK3588引脚复用系统深度解析在动手配置之前我们必须先理解RK3588的引脚控制系统是如何工作的。这就像你要操作一台复杂的机器必须先看懂它的控制面板和原理图。2.1 Pinctrl子系统与设备树的作用在Linux内核中PinctrlPin Control子系统是专门用来管理芯片引脚复用的框架。它抽象了不同芯片厂商的引脚控制硬件细节为驱动开发者提供统一的API。对于RK3588来说它的引脚功能比如是作为GPIO、UART的TX还是I2C的SCL是由一系列内部寄存器控制的。Pinctrl子系统就是这些寄存器的软件抽象层。而设备树Device Tree则是描述这些硬件连接关系的“地图”。它以一种树状结构的数据格式告诉内核这块开发板上有什么硬件这些硬件连接到了SoC的哪个引脚这些引脚当前应该被配置成什么功能。内核在启动时解析这个设备树文件然后调用Pinctrl子系统去配置对应的硬件寄存器从而完成引脚的初始化。所以我们的核心工作就是修改设备树文件准确地描述“我们希望某个引脚作为UART功能使用”这个需求。2.2 RK3588引脚命名与分组规则RK3588的引脚数量庞大命名有其规律。通常格式如GPIO1_A0、GPIO3_B5等。这里的“GPIO1”指的是GPIO控制器编号RK3588有多个GPIO控制器GPIO0~GPIO4。字母“A”、“B”代表该控制器下的Bank每个Bank通常包含8个或16个引脚。最后的数字“0”、“5”则是该Bank内的引脚序号。更重要的是引脚功能复用编号Mux Function。一个物理引脚可以有多个功能比如GPIO1_A0这个引脚可能同时是Function 0: GPIOFunction 1: UART0_TXFunction 2: I2C1_SDAFunction 3: PWM5在设备树中配置时我们就是通过指定这个功能编号来选择引脚的具体角色。RK3588的引脚功能定义通常在内核源码的include/dt-bindings/pinctrl/rockchip.h头文件中以宏定义的形式给出例如RK_PA0表示GPIO0_A0UART0_TX_M0表示UART0发送功能复用模式0M0。注意RK3588的同一个UART控制器如UART0的TX、RX引脚可能有多种不同的引脚位置选项M0, M1, M2...这对应着SoC内部不同的物理连接路由。你需要查阅官方原理图或数据手册确认你打算使用的物理引脚支持哪种复用模式Mx。选错了模式配置是不会生效的。2.3 ELF 2开发板引脚资源现状分析以ELF 2开发板为例板载的40针扩展接口类似树莓派引出了大量的RK3588引脚。但很多引脚默认功能可能被设置为GPIO或其他功能。例如扩展接口上的第8、10针脚对应物理引脚GPIO1_B1和GPIO1_B0在默认配置中可能未被使用或用作普通GPIO而它们恰好可以复用为UART1的TX和RX假设是M1模式。我们的任务就是1确认目标引脚是否可用且支持UART功能2在设备树中解除它原有的功能绑定如果有3将其配置为我们需要的UART功能。3. UART引脚复用配置实操全流程理论清晰后我们进入实战环节。整个流程可以概括为查找资料 - 修改设备树 - 编译更新 - 验证测试。3.1 前期准备与资料查找获取开发板原理图与引脚定义表这是最重要的第一步。你需要从板卡供应商ElfBoard的官网或资料包中找到ELF 2开发板的原理图PDF。在原理图中找到40针扩展接口的电路图部分确认你计划使用的两个引脚例如Pin8和Pin10连接到了RK3588的哪两个引脚上记下它们的SoC引脚名称如GPIO1_B1,GPIO1_B0。查阅RK3588数据手册找到官方数据手册中关于“Pin Description”或“Pin Multiplexing”的章节。根据你记下的SoC引脚名称查找其所有可用的复用功能列表确认它是否支持UART以及对应的功能复用编号Function Number和复用模式M0/M1/M2。例如找到GPIO1_B1的描述看到其Function 2可能是UART1_TX_M1。定位内核设备树源码进入你的Linux内核源码目录。RK3588的设备树文件通常位于arch/arm64/boot/dts/rockchip/下。对于ELF 2开发板核心的设备树文件可能是rk3588-elf2.dts或类似名称。同时会有一个rk3588s-pinctrl.dtsi文件里面定义了所有引脚的复用配置节点即pinctrl节点这是我们修改的重点。3.2 设备树节点修改详解假设我们目标是将GPIO1_B1和GPIO1_B0复用为 UART1 的 TX 和 RX复用模式为 M1。定义Pinctrl配置节点 首先我们需要在rk3588s-pinctrl.dtsi或直接在板级设备树文件如rk3588-elf2.dts的pinctrl节点区域添加一个新的引脚配置节点。通常我们会选择在板级文件中添加以避免修改通用文件。// 在 pinctrl 节点内添加 pinctrl { // 其他已有的 pinctrl 配置... // 新增UART1的M1模式引脚配置 uart1m1_xfer: uart1m1-xfer { rockchip,pins // GPIO1_B1 复用为 UART1_TX_M1, 引脚内部上拉 1 RK_PB1 2 pcfg_pull_up, // GPIO1_B0 复用为 UART1_RX_M1, 引脚内部上拉 1 RK_PB0 2 pcfg_pull_up; }; };代码解析uart1m1_xfer是我们自定义的这个配置节点的标签label后面会引用它。rockchip,pins属性是Rockchip平台定义的格式用于描述一组引脚配置。1 RK_PB1 2 pcfg_pull_up这是一个四元组。1代表GPIO控制器编号GPIO1。RK_PB1这是一个宏在rockchip.h中定义代表GPIO1的Bank B引脚1即GPIO1_B1。RK_PB0同理。2这就是功能复用编号。这里的“2”对应数据手册中GPIO1_B1的Function 2即UART1_TX_M1。这个数字是配置的关键必须与数据手册严格对应pcfg_pull_up这是一个引用指向内核预定义的“上拉”配置。也可以使用pcfg_pull_none无上下拉或pcfg_pull_down下拉。对于UART的TX和RX线通常建议设置为上拉以确保在空闲状态下保持稳定的高电平。将Pinctrl配置应用到UART设备节点 接下来我们需要找到UART1的设备节点并将我们自定义的pinctrl配置指定给它。UART设备节点通常在rk3588s.dtsi中定义我们需要在板级文件rk3588-elf2.dts中通过“覆盖”的方式修改其属性。// 在 rk3588-elf2.dts 文件中添加 uart1 { status okay; // 确保UART1控制器使能 pinctrl-names default; pinctrl-0 uart1m1_xfer; // 引用我们刚才定义的pinctrl配置 };代码解析uart1表示引用覆盖在rk3588s.dtsi中已经定义好的uart1节点。status okay;是启用这个外设控制器。pinctrl-names和pinctrl-0是标准属性。pinctrl-names定义状态名这里我们只用默认状态“default”。pinctrl-0则指定在“default”状态下使用哪个pinctrl配置这里填入我们刚才定义的uart1m1_xfer节点的标签。检查并处理引脚冲突 在修改前务必用文本编辑器的搜索功能在整个设备树源文件中搜索GPIO1_B1和GPIO1_B0看看它们是否已经被其他节点比如另一个UART、SPI、I2C或某个GPIO LED所使用。如果被占用你有两个选择方案A禁用那个冲突的设备节点将其status改为disabled前提是你确定不需要那个功能。方案B更换为另一组支持UART1功能的空闲引脚重复上述查找和配置步骤。3.3 内核编译与固件更新修改保存设备树源文件.dts后需要重新编译内核或设备树并更新到开发板。编译设备树 在Linux内核源码根目录下执行编译命令。具体命令取决于你的编译环境通常如下# 设置环境变量根据你的工具链调整 export PATH/path/to/your/toolchain/bin:$PATH export CROSS_COMPILEaarch64-linux-gnu- export ARCHarm64 # 使用ELF 2的默认配置 make rockchip_defconfig # 或 make rk3588-elf2_defconfig取决于板级支持包 # 编译设备树 make dtbs编译成功后新的设备树二进制文件.dtb会生成在arch/arm64/boot/dts/rockchip/目录下文件名可能是rk3588-elf2.dtb。更新设备树到开发板 将生成的.dtb文件替换到开发板启动分区通常是FAT格式的/boot分区中对应的文件。你可以通过SD卡、网络tftp, scp或ADB等方式进行替换。替换后重启开发板。3.4 配置验证与功能测试开发板重启后需要验证配置是否生效。检查系统日志 使用dmesg | grep uart1命令查看内核启动日志。如果看到类似ff1a0000.serial: ttyS1 at MMIO 0xff1a0000 (irq 45, base_baud 1500000) is a 16550A的信息并且没有报错说明UART1控制器已成功注册。检查Pinctrl状态 更直接的验证是查看sysfs中引脚的状态。RK3588的引脚状态通常在/sys/kernel/debug/pinctrl/pinctrl-rockchip-pinctrl/pinmux-pins或类似路径下具体路径可能因内核版本而异。你可以cat这个文件搜索GPIO1-B1和GPIO1-B0看其function字段是否显示为uart1或uart1m1。测试UART通信 这是最终的验收测试。你需要一个USB转TTL串口模块。硬件连接将USB转TTL模块的TX线连接到开发板的GPIO1_B0UART1_RXRX线连接到GPIO1_B1UART1_TXGND对接。软件操作在开发板上配置UART1的波特率等参数。通常对应的设备文件是/dev/ttyS1。# 安装串口工具如minicom sudo apt install minicom -y # 配置minicom使用ttyS1波特率115200根据你的需求调整 sudo minicom -D /dev/ttyS1 -b 115200在连接开发板的PC端打开串口调试助手如Putty、SecureCRT选择USB转TTL对应的COM口设置相同的波特率。在开发板的minicom中和PC的串口调试助手中互相发送字符如echo hello from elfboard /dev/ttyS1如果双方都能正确接收则证明UART引脚复用配置完全成功。4. 常见问题排查与实战心得即使按照步骤操作也可能会遇到问题。下面是我在多次配置中总结的常见“坑点”和解决方法。4.1 配置后系统无法启动或串口无输出这是最严重的问题通常意味着设备树配置有根本性错误导致内核在初始化硬件时崩溃。可能原因1引脚功能编号错误。排查反复核对数据手册。确认rockchip,pins属性中的第三个数字功能编号100%准确。一个数字之差引脚可能被配置成完全不同的功能甚至是不允许的配置导致硬件异常。技巧可以先用一个“安全”的功能比如GPIO功能号通常是0进行测试确保引脚基础访问正常再切换到UART功能。可能原因2引脚冲突未被正确处理。排查仔细检查设备树中所有使用了目标引脚的节点。一个引脚在同一时刻只能有一个功能。如果另一个设备比如一个LED灯也配置为使用该引脚就会冲突。技巧使用grep -r RK_PB1\|GPIO1_B1 arch/arm64/boot/dts/rockchip/这样的命令进行全局搜索确保没有遗漏。可能原因3时钟或电源域未开启。排查UART控制器需要对应的时钟和电源。虽然大多数情况下在uart1节点使能status okay后内核会自动处理但某些特殊引脚组可能依赖特定的电源域PMU。需要查阅RK3588 TRM技术参考手册中关于Power Management的部分。技巧对比一个已知工作正常的UART节点如UART2的配置看是否有额外的assigned-clocks,assigned-clock-rates或power-domains属性。4.2 能识别到ttyS设备但无法收发数据系统日志显示UART注册成功/dev/ttyS1也存在但通信失败。可能原因1引脚电气属性配置不当。排查检查pcfg_pull_up的配置。对于UARTTX和RX线通常都需要上拉。如果配置为pcfg_pull_none在引脚悬空时电平可能不稳定导致数据误判。尝试改为pcfg_pull_up。深入除了上下拉Rockchip引脚还可以配置驱动强度drive strength和施密特触发器schmitt。对于长线通信可能需要增加驱动强度。配置格式类似1 RK_PB1 2 pcfg_pull_up_drv_level_2具体宏定义需参考内核头文件。可能原因2硬件连接错误或电平不匹配。排查这是最经典的硬件问题。请再次确认开发板的TX应接USB转TTL的RX开发板的RX接USB转TTL的TX。同时确认USB转TTL模块是3.3V电平与RK3588 IO电压匹配而不是5V。技巧用万用表测量引脚电压。在配置为上拉且空闲时TX和RX引脚电压应接近3.3V。可能原因3内核串口驱动流控干扰。排查有些USB转TTL模块的RTS/CTS引脚可能悬空或处于异常状态而内核默认可能启用了硬件流控。解决在打开串口设备时在应用程序中明确关闭流控。对于minicom可以在配置中禁用硬件流控Hardware Flow Control和软件流控Software Flow Control。对于编程在termios结构体中清除CRTSCTS等标志。4.3 复用模式M0/M1/M2选择困惑同一个UART控制器为什么会有M0, M1, M2多种引脚选择原理这是SoC设计上的灵活性。RK3588内部一个外设控制器如UART1的信号可以通过不同的“路由网络”连接到多组物理引脚上。M0, M1, M2就代表了不同的路由路径。这样设计可以让PCB布局更灵活避免走线交叉。如何选择完全由硬件原理图决定。你必须在原理图上找到UART1的TX和RX信号线最终连接到了哪两个物理引脚上然后查看这两个引脚的数据手册页看它们支持UART1的哪种复用模式Mx。原理图是唯一依据不能猜测。4.4 设备树修改的版本管理与调试建议版本管理在修改dts文件前务必先进行备份。可以使用git管理你的内核源码在修改前git add和git commit方便回滚。增量修改一次只修改一个功能验证通过后再进行下一个。避免同时修改多处导致问题难以定位。善用调试工具fdtdump工具可以将编译后的.dtb文件反编译成可读的.dts格式用于验证最终的设备树内容是否与你修改的源码一致。命令fdtdump your-board.dtb decompiled.dts。devmem2工具一个直接读写物理内存地址的小工具。在极端情况下你可以用它来直接读取引脚控制寄存器的值确认配置是否被正确写入硬件。使用此工具需要格外小心错误的写入可能导致系统崩溃。配置RK3588的引脚复用尤其是像UART这样常用的功能是嵌入式Linux开发中的一项基本功。这个过程融合了对硬件原理图、芯片数据手册、设备树语法和内核驱动框架的理解。刚开始可能会觉得繁琐但一旦走通整个流程并理解了各个步骤背后的“为什么”你就会发现这套机制其实非常清晰和强大。它带来的灵活性让我们能够在一颗固定的芯片上通过软件配置来适应千变万化的硬件连接需求这正是嵌入式Linux的魅力之一。希望这篇详细的梳理能帮你扫清RK3588 UART引脚复用路上的障碍。如果在实践中遇到新的问题多查手册、多分析日志、善用搜索大部分难题都能找到答案。

相关新闻