ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

RK3588嵌入式开发:UART引脚复用配置实战与深度排查指南

RK3588嵌入式开发:UART引脚复用配置实战与深度排查指南 1. 项目概述为什么UART引脚复用是嵌入式开发的必修课在嵌入式开发尤其是基于像瑞芯微RK3588这类高性能SoC的项目中引脚复用Pin Mux配置是硬件驱动开发的第一步也是最容易“踩坑”的一步。最近在ELF 2开发板上调试一个需要多路串口通信的外设时我就遇到了一个典型问题原理图上标注的UART引脚在系统中死活无法正常收发数据。折腾了半天最后发现是引脚复用功能没有正确配置默认状态被其他功能比如GPIO或I2C占用了。这个经历让我意识到虽然RK3588的文档里提到了引脚复用控制器但如何在实际开发板上快速、准确地完成配置尤其是针对ELF 2这种具体载板其中的门道远比想象中要多。RK3588芯片本身集成了丰富的功能接口但物理引脚数量有限因此一个物理引脚往往可以复用作多种功能例如UART、SPI、I2C或普通的GPIO。开发板设计者如ElfBoard会根据板子的实际功能需求在硬件上将这些引脚连接到特定的外设或接口上。我们的任务就是在软件层面通过配置芯片内部的寄存器将硬件连接对应的引脚“切换”到我们需要的功能模式上。这个过程如果出错轻则功能无法使用重则可能因为引脚电平冲突损坏硬件。今天我就以在ELF 2开发板上配置UART引脚为例把整个配置流程、背后的原理、以及我趟过的那些坑系统地梳理一遍希望能帮你绕过这些弯路。2. 核心原理深入理解RK3588的引脚控制体系在动手修改配置文件之前我们必须先搞清楚RK3588是如何管理这么多引脚的。盲目操作寄存器就像在黑箱里乱摸开关非常危险。2.1 PMU与GRF引脚控制的左右手RK3588的引脚复用配置主要依赖于两类寄存器组GRF和PMU。这不是RK3588独有的设计但在RK3588上尤为重要。GRF即“通用寄存器文件”。它负责管理芯片上大部分通用功能引脚的复用和电气属性配置。我们常说的UART、I2C、SPI、PWM等外设的引脚其功能选择、上下拉电阻、驱动强度等基本都是通过配置对应的GRF寄存器来完成的。你可以把它理解为管理“业务引脚”的大管家。PMU即“电源管理单元”。它主要负责管理与电源、休眠、复位等系统级功能相关的引脚。一些特殊的引脚比如某些GPIO在RK3588上GPIO0_A到GPIO0_D通常由PMU管理就需要通过PMU的寄存器来配置。它管理的是“系统关键引脚”。对于UART引脚绝大多数情况下我们只需要和GRF打交道。但有一个关键点需要注意RK3588的引脚编号Pin Number和我们在原理图上看到的丝印编号如“GPIO1_B5”并不是直接对应的。芯片内部有一套自己的“引脚ID”体系而GRF和PMU寄存器操作的对象正是这个内部的引脚ID。因此我们需要一个“翻译”工具将原理图上的丝印号转换成内核驱动能识别的配置参数。这个工具就是设备树Device Tree中的pinctrl子系统。2.2 设备树中的Pinctrl配置的载体在Linux内核中pinctrl子系统统一管理所有引脚的复用和配置。对于RK3588瑞芯微提供了完善的pinctrl驱动。我们要做的不是直接去写GRF寄存器的地址和值而是在设备树源文件.dts或.dtsi中以声明式的方式描述我们想要的引脚状态。一个典型的引脚配置包含两个部分引脚功能选择指定这个引脚是用于UART的TX、RX还是其他功能。引脚电气属性指定上下拉电阻、驱动电流等。对于UART这类串行通信接口通常配置为无上下拉高阻态即可但最好明确指定避免默认状态不确定。在设备树中这些配置被定义成一个个“引脚控制状态”比如uart2m0_xfer就表示将一组引脚复用为UART2功能并使用“m0”这组引脚RK3588的许多功能有多个引脚组可选称为“复用功能等级”。3. 实战准备定位ELF 2开发板的UART资源理论清楚了我们开始实战。首先要明确我们在ELF 2开发板上到底要配置哪个UART以及它对应哪些物理引脚。3.1 查阅硬件资料这是最关键的一步绝对不能错。你需要找到ELF 2开发板的原理图和硬件用户手册。确定UART编号与引脚在原理图中搜索“UART”。以常见的调试串口为例它通常连接在RK3588的UART2上。在ELF 2的原理图上你可能会找到标有“UART2_TX”、“UART2_RX”的网络标签并追踪到具体的连接器引脚比如40针的扩展排针上的某两个针脚。记录下这两个引脚在RK3588芯片端的引脚丝印名称例如GPIO1_B5和GPIO1_B6。确认复用功能等级RK3588的每个UART控制器可能有多个引脚组m0, m1, m2等可选。原理图设计者已经为我们选定了其中一组。你需要确认ELF 2使用的是哪一组。通常在原理图的引脚网络标签或芯片引脚标注附近会有小字注明例如UART2_TX_M0。这里的“M0”就是复用功能等级。这个信息至关重要因为它直接决定了我们在设备树中应该引用哪个预定义的引脚配置节点。3.2 分析内核源码中的预定义配置RK3588的Linux内核源码中已经为我们定义好了几乎所有可能的引脚配置组合。它们位于arch/arm64/boot/dts/rockchip/rk3588s-pinctrl.dtsi文件中。我们用UART2的M0引脚组举例看看里面是怎么定义的// 这是一个示例具体内容需以实际内核源码为准 uart2m0_xfer: uart2m0-xfer { rockchip,pins 4 RK_PB1 1 pcfg_pull_none, // GPIO1_B1 as UART2_TX_M0 4 RK_PB2 1 pcfg_pull_none; // GPIO1_B2 as UART2_RX_M0 };我们来解析一下uart2m0_xfer 这是一个“引脚控制状态”的标签。uart2指UART2控制器m0指复用功能等级0xfer表示数据传输引脚组通常包含TX和RX。rockchip,pins 这是一个数组每个条目描述一个引脚的配置。4 RK_PB1 1 pcfg_pull_none 这是一个引脚配置项。4 代表引脚所在的“组”Bank。RK_PB1中的“P”是“Port”的缩写B是Bank1是引脚号。这里RK_PB1对应的是GPIO1_B1。这个“4”是内核内部对GPIO1 Bank的编号。RK_PB1 是引脚的宏定义对应芯片数据手册里的引脚名。1 表示引脚的“复用功能编号”。这里的“1”代表将这个引脚配置为“功能1”在RK3588的引脚复用表中对于GPIO1_B1这个引脚“功能1”很可能就是UART2_TX。pcfg_pull_none 这是一个对电气属性配置的引用表示该引脚不启用内部上拉或下拉电阻。注意这里示例的引脚GPIO1_B1/B2可能并非ELF 2实际使用的引脚。你必须根据你从原理图上查到的实际引脚比如GPIO1_B5/B6去内核的pinctrl文件中找到对应的配置节点标签。这个标签名很可能类似uart2m0_xfer但也可能是其他名字具体需要根据引脚归属的Bank和Mux值来确定。4. 配置实战修改设备树启用UART假设我们已经确定ELF 2的UART2使用M0引脚组对应的引脚控制标签是uart2m0_xfer。4.1 定位并编辑设备树文件开发板厂商通常会提供一个基础设备树文件。对于ELF 2这个文件可能叫rk3588-elf2.dts或类似的名字。它通常位于内核源码的arch/arm64/boot/dts/rockchip/目录下。找到UART节点在这个.dts文件中搜索uart2。你会找到一个类似下面的节点uart2 { status disabled; pinctrl-names default; pinctrl-0 uart2m0_xfer; };如果找不到你可能需要在文件末尾通过uart2 { ... };的方式来覆盖或添加配置。修改配置我们的目标是将这个UART2节点启用并确保其引脚配置指向正确的pinctrl节点。uart2 { status okay; // 将状态从“disabled”改为“okay”启用该控制器 pinctrl-names default; pinctrl-0 uart2m0_xfer; // 确保这里引用的标签与你查到的实际标签一致 // 如果需要指定特定的波特率非标准115200可以添加如下属性 // assigned-clocks cru SCLK_UART2; // assigned-clock-parents cru PLL_HPLL; // clock-frequency 24000000; // 指定时钟频率 };关键检查pinctrl-0属性后面的标签uart2m0_xfer必须与你在rk3588s-pinctrl.dtsi文件中找到的、对应你实际硬件引脚的那个节点标签完全一致。这是最容易出错的地方。4.2 编译与更新设备树修改保存后需要重新编译设备树并更新到开发板。编译设备树在内核源码根目录下执行编译命令。命令取决于你的编译配置通常如下make ARCHarm64 CROSS_COMPILEaarch64-linux-gnu- rk3588-elf2.dtb这条命令会生成rk3588-elf2.dtb文件。更新开发板将生成的.dtb文件替换到开发板启动分区通常是/boot目录下。具体方法取决于你的启动方式SD卡启动将SD卡挂载到PC替换boot分区下的对应.dtb文件。eMMC启动可以通过scp命令将文件传到开发板然后使用dd命令或update_dtb脚本如果厂商提供写入到eMMC的特定位置。网络启动替换TFTP服务器上的dtb文件。重启验证重启开发板后首先检查UART控制器是否成功启用# 在开发板的Linux终端中执行 ls /dev/ttyS*你应该能看到ttyS2出现因为UART2通常对应ttyS2UART0对应ttyS0以此类推具体映射关系需参考内核串口驱动文档。4.3 功能测试使用echo和cat命令或者更专业的串口工具如minicom、picocom进行回环测试。短接TX和RX用杜邦线将UART2的TX和RX引脚物理上短接构成回环。发送与接收测试# 在一个终端监听UART2 cat /dev/ttyS2 # 在另一个终端向UART2发送数据 echo Hello UART2 /dev/ttyS2如果配置正确在第一个终端中应该能看到 “Hello UART2” 被回显出来。5. 深度排查与常见问题解决即使按照步骤操作也可能遇到问题。下面是我遇到过的几个典型问题及解决方法。5.1 问题一/dev/ttyS2设备节点未出现这是最普遍的问题。排查思路1检查设备树状态# 查看设备树中uart2节点的状态 cat /sys/firmware/devicetree/base/serialfe660000/status 2/dev/null如果输出不是okay说明设备树修改未生效或编译/更新有误。请确认设备树源文件修改正确并已保存。编译命令针对的是正确的dtb目标文件。开发板上加载的dtb文件确实是你新编译的版本可以通过cat /proc/device-tree/model查看模型信息但更直接的是核对文件时间戳或MD5。排查思路2检查引脚复用配置这是更深层的问题。即使节点状态是okay如果引脚复用错误驱动也无法成功探测硬件。我们可以通过io工具需自行交叉编译或从busybox中获取直接读取GRF寄存器来验证。 首先需要找到UART2对应引脚的GRF寄存器地址和配置值。这需要查阅RK3588的TRM技术参考手册。假设我们怀疑的引脚是GPIO1_B5。查找寄存器在TRM中搜索 “GRF_GPIO1B_IOMUX” 或类似名称的寄存器。每个Bank的IOMUX寄存器控制该Bank所有引脚的复用功能。计算位域找到控制GPIO1_B5的位域。通常是2个比特位用来选择4种功能之一00GPIO01功能110功能211功能3。根据pinctrl定义UART2_TX_M0对应的功能编号是1。读取验证# 假设 GRF_GPIO1B_IOMUX 的物理地址是 0xFD58C000请务必查TRM确认 # 使用 devmem2 或 io 工具读取。注意直接操作物理内存有风险且需要root权限。 io -4 0xFD58C000查看输出值的对应比特位。如果它不是01功能1则说明引脚复用配置未生效。可能原因设备树中pinctrl-0引用了错误的节点标签。该引脚被其他驱动比如早期内核代码、Bootloader提前配置成了其他功能。这种情况比较棘手可能需要检查是否有其他设备树节点或内核代码覆盖了你的配置。5.2 问题二能收到数据但乱码或发送数据对方收不到排查思路1电气属性冲突。虽然UART通常配置为无上下拉但如果硬件设计上有外部上拉/下拉而软件配置了相反的属性可能导致电平异常。可以尝试在设备树pinctrl节点中将pcfg_pull_none改为pcfg_pull_up或pcfg_pull_down进行测试。注意此操作有风险不当的上下拉可能损坏硬件最好在明确硬件设计后再尝试。排查思路2引脚冲突。确认你配置的UART引脚没有同时被其他功能占用。例如在设备树中搜索你使用的引脚丝印号如GPIO1_B5看是否有其他节点如I2C、SPI、GPIO按键等也声明使用了该引脚。一个引脚在同一时刻只能有一种功能。排查思路3时钟与波特率。确保内核为UART2分配的时钟是正确的。在复杂的低功耗场景下时钟可能被错误地门控或分频。可以在设备树中显式指定时钟如前面示例中注释掉的部分。另外用stty命令检查并设置正确的波特率、数据位、停止位和校验位stty -F /dev/ttyS2 115200 cs8 -parenb -cstopb5.3 问题三系统启动后UART配置被改变有时在Bootloader阶段如U-Boot会初始化某些引脚用于调试或启动进入内核后如果内核驱动配置不一致可能会发生冲突。排查方法查看U-Boot源码中关于该开发板的引脚初始化代码。如果U-Boot将引脚初始化为GPIO或其他功能而内核又将其配置为UART就可能有问题。解决方法是确保U-Boot和内核的配置一致或者让U-Boot在跳转到内核前不要初始化这些引脚设置为输入高阻态。6. 进阶技巧与最佳实践掌握了基础配置后下面这些技巧能让你的开发更顺畅。使用设备树覆盖对于频繁修改的配置不建议直接修改核心的.dts文件。可以利用U-Boot的“设备树覆盖”功能。你可以创建一个只包含UART2修改节点的.dtso文件编译成.dtbo然后在U-Boot启动时动态加载。这样无需重新编译和替换整个dtb特别适合在量产固件上进行定制。利用调试文件系统pinctrl子系统在/sys/kernel/debug/pinctrl/下提供了丰富的调试信息。你可以在这里查看每个引脚组的状态、当前配置的功能等是诊断引脚复用问题的利器。绘制自己的引脚复用表对于核心外设如你项目要用到的所有UART、I2C、SPI建议根据原理图和内核的pinctrl文件自己整理一个表格。列出外设名称、原理图引脚、芯片引脚名、复用功能等级、对应的设备树pinctrl标签。这能极大减少后续调试的时间。版本管理设备树文件是内核配置的一部分务必将其纳入你的版本控制系统如Git。任何修改都要有清晰的提交信息说明修改原因和对应的硬件版本。配置RK3588的引脚复用尤其是像ELF 2这样的具体载板是一个需要细心结合硬件原理图、芯片手册和内核源码的过程。最核心的诀窍就是保持三者的一致原理图上的连接、pinctrl文件中的定义、设备树节点中的引用必须严丝合缝。一旦出现数据收发异常按照“先软件后硬件先配置后电气”的顺序从设备树状态、引脚复用寄存器、电气属性、外部硬件连接一步步排查总能定位到问题所在。
返回列表