尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

PetaLinux下AXI UART Lite串口调试三板斧

PetaLinux下AXI UART Lite串口调试三板斧 串口调试这件事说难不难说容易也真容易把人绕晕。在PetaLinux环境下调试AXI UART Lite设备时很多问题并不是硬件没焊好也不是U-Boot没引导而是调试工具没选对、寄存器状态没看清、设备树节点没确认。AXI UART Lite作为Zynq平台里最常见的PL侧串口IP几乎每个带FPGA逻辑的项目都会用到要么接调试串口要么挂GPS、蓝牙、RS485模块用途非常广泛。我从实际项目里梳理了三种最有效的调试方法minicom、screen、以及直接通过devmem读写寄存器。三种方法各有各的适用场景也各有各的坑。这篇文章会带着你从环境准备、工具安装、具体操作、到常见问题排查完整走一遍。无论你是刚接触Petalinux的新手还是被某个串口问题卡了两天的老手这三板斧都能帮你快速定位问题。1. 为什么调不通先搞清AXI UART Lite与调试环境1.1 AXI UART Lite的硬件与寄存器特征AXI UART Lite是Xilinx/AMD提供的一款轻量级UART IP核通过AXI4-Lite总线与PS端连接。所谓“Lite”体现在功能精简上没有调制解调器控制信号、没有DMA能力、FIFO深度也不大甚至比经典的16550 UART还要简单。正因为简单它在量产项目里反而更可控出错点也更少。它的寄存器布局非常清晰总共就那么几个一般在Vivado的Address Editor里分配基地址常见的是0x42C00000。以这个基地址为例偏移地址寄存器名说明0x00RBR/THR读为接收数据写为发送数据0x04IER中断使能寄存器0x08ISR中断状态寄存器0x0CFCRFIFO控制寄存器0x10LSR线路状态寄存器其中最核心的是LSRLine Status Register调板时一定要盯住它。bit0是接收数据就绪标志置1代表RBR里有新数据可读bit5是发送保持寄存器空标志置1代表THR可以写入新数据bit6则是发送移位寄存器空标志表示整帧数据都已经发完。波特率、数据位、停止位、校验方式这些参数并不是在Linux里通过软件配置的而是在Vivado中硬件定制时就固定下来的。也就是说你终端工具里选的波特率必须和IP配置一致否则后面怎么调都是乱码。这是理解AXI UART Lite调试的关键前提。1.2 PetaLinux下的设备树与设备节点确认我遇到过不少朋友拿着串口线连上板子minicom也启动了结果屏幕上什么都没有。排查到最后发现设备树里根本没有这个UART节点或者IP核的引脚根本没有连到PL侧的管脚上。所以在动手调试之前先确认PetaLinux环境里的设备树是否正确生成了。当你用petalinux-config --get-hw-description导入硬件描述文件后设备树里通常会自动生成类似下面的节点serial42c00000 { compatible xlnx,xps-uartlite-1.00.a; reg 0x42c00000 0x10000; interrupt-parent intc; interrupts 0 11 1; clock-names s_axi_aclk; clocks clkc 15; };启动Linux后对应设备节点一般叫/dev/ttyUL0这是uartlite驱动注册的名字而不是常见的ttyS0。如果你用minicom打开了ttyS0那自然什么都收不到。确认节点的方法是先进系统然后执行ls -l /dev/ttyUL* dmesg | grep -i tty如果设备节点不存在优先查两件事内核是否配置了CONFIG_SERIAL_UARTLITE以及设备树节点是否真的挂在了总线上。排查完这个基础环境下面三种调试方法才有意义。2. 方法一minicom——最稳妥的日常串口调试2.1 minicom的安装与Petalinux镜像配置minicom是Linux下老牌的串口终端程序交互式菜单操作对新手极其友好。在Petalinux构建目标系统时你可以直接把它打进镜像里。在Petalinux工程的根目录执行petalinux-config -c rootfs进入Filesystem packages菜单在apps相关分类下勾选minicom包保存后重新执行petalinux-build编译最终镜像里就会带上minicom。如果你的平台用的是Debian/Ubuntu rootfs也可以直接在板子上执行apt-get install minicom。如果在已经运行的系统上临时用最简单的方式其实是从宿主机的包管理器安装然后把串口设备映射过去。不过真实嵌入式项目中我更推荐直接把minicom编进镜像因为板子在现场调试时没网的情况太多依赖在线安装不现实。2.2 关键配置项与典型操作步骤minicom第一次启动建议先进配置菜单minicom -s重点检查三项Serial Device是不是/dev/ttyUL0Bps/Par/Bits波特率改成与Vivado IP核一致Hardware Flow Control务必关闭。很多初学者板卡接了TX、RX、GND三根线却忽略了流控问题结果数据死活出不去就是因为IP核没有连线RTS/CTS而minicom默认开了硬件流控。配置保存后正常启动minicom -D /dev/ttyUL0 -b 115200这时候如果你把板卡的TX和RX短接做回环测试键盘输入字符应该能直接在终端回显。发送数据时可以观察界面下方的状态栏变化如果波特率匹配能看到输入字符被正确回显如果不匹配就会是一堆乱码。minicom的常用快捷键在会话内随时可以查CtrlA按Z打开帮助菜单CtrlX退出并询问是否留下锁文件CtrlL将当前会话写入日志文件。调试带日志记录非常有用因为现场问题往往要回放数据。2.3 minicom的优缺点与注意事项minicom最大的优点是功能完整、菜单化配置、支持日志和文件传输适合长时间交互调试。缺点也明显配置文件多新手容易在菜单里迷路另外它是通过curses渲染界面的在高波特率大流量打印时偶尔会卡顿。一个实测中容易踩的坑是退出minicom后终端状态没有完全恢复命令输入变成乱码。解决方法是退出后执行stty sane或者先按CtrlZ挂起它回到shell看完信息再fg切回去。3. 方法二screen——一条命令快速挂串口3.1 screen挂载串口的基础用法screen本来是终端复用器用来在一个终端里开多个会话但几乎每个Linux系统都会自带它所以它成了很多人快速挂载串口的利器。在Petalinux最小rootfs里如果busybox编译时带上了screen applet甚至不需要额外安装。挂载串口只需要一条命令参数非常直观screen /dev/ttyUL0 115200就是这么简单省去了minicom的菜单配置环节。连接后直接进入全屏会话所有键盘输入都会发送到串口。在远程SSH环境里特别好用因为不需要额外安装任何图形化组件。我的使用习惯是在需要快速探测一个串口通不通时先用screen顶上去比minicom至少快10秒。如果确认通路正常再切换到minicom做正式交互。3.2 快捷键与退出恢复技巧screen的快捷键设计对新手不那么友好因为它同时承担终端复用功能很多按键都有特殊含义。常用的几个必须记住CtrlA然后按K杀死当前串口会话退出前会询问是否确认CtrlA然后按D分离会话串口会话在后台继续保持适合临时离开CtrlA然后按H开启/关闭日志记录CtrlA然后按C新建一个shell窗口分离后重新回到串口会话screen -r如果你手滑按了CtrlA D发现串口会话消失了不要慌执行screen -r就能恢复。如果想彻底清掉后台会话screen -ls查看会话编号再用screen -X -S 编号 quit结束。还有一个小技巧退出screen后终端偶尔会进入一种奇怪的状态命令行输入显示异常。这其实是串口会话把terminal的line discipline改掉了先执行stty sane再执行reset基本都能恢复。3.3 screen的适用场景与局限性screen最适合的场景是快速验证、远程SSH调试、以及嵌入式板卡上临时操作。它不需要复杂的配置文件一条命令就能启动在只关心“数据能不能收发”的阶段非常高效。局限性也很明显它没有菜单式配置界面首次使用的用户容易误触快捷键不支持像minicom那样的zmodem文件传输串口参数如果和IP核不一致没有直观提示。另外如果rootfs里缺了termcap相关配置screen可能会显示异常这时候只能换回minicom或者其他工具。4. 方法三devmem与寄存器直读直写——直接与硬件对话4.1 devmem命令与寄存器访问原理前面两种方法都属于应用层工具最终都是通过Linux的tty核心操作串口驱动。如果驱动本身有问题或者设备树有误这两种方法都会“假装正常工作”或者“什么都不显示”让你很难判断问题出在哪一层。这时候就需要走到最底层直接用devmem读写物理寄存器。devmem是Linux内置的物理内存读写命令常见用法如下devmem ADDRESS [WIDTH [VALUE]]ADDRESS是物理地址WIDTH是访问宽度可以是8、16、32。不写VALUE就是读操作写上VALUE就是写操作。比如读AXI UART Lite的LSR状态devmem 0x42C00010 32读出来的值如果最低位是1说明接收端有数据bit5如果是1说明发送保持寄存器空闲可以写数据。这就是直连硬件的方式绕开了Linux驱动。为什么推荐用32位访问因为AXI UART Lite的寄存器是挂在AXI4-Lite总线上的虽然有效数据只在低8位但总线访问粒度是32位字。用devmem 32既稳妥又不会破坏高字节内容。4.2 通过寄存器发送与接收数据的实操发送一个字节必须遵循“先查状态再写数据”的顺序。直接写THR前先等THRE置位# 等待发送保持寄存器空 until [ $(( $(devmem 0x42C00010 32) 0x20 )) -ne 0 ]; do :; done # 发送0x55 devmem 0x42C00000 32 0x55接收数据同理先查LSR的bit0是否置1有数据再读RBRif [ $(( $(devmem 0x42C00010 32) 0x01 )) -ne 0 ]; then devmem 0x42C00000 32 fi我调试时经常先发一个0x55二进制01010101再发0xAA10101010这两个pattern在示波器和逻辑分析仪上看非常直观能迅速确认是否有信号翻转、波特率是否正确。如果寄存器操作能正常读写但minicom/screen不行那问题就锁定在驱动或设备树上硬件链路基本没问题。这个排查思路能节省大量时间。4.3 用Python mmap脚本做串口批量验证手动执行devmem适合验证单个地址但要做批量收发测试就太累了。这时可以写一个简单的Python脚本通过mmap映射/dev/mem实现连续读写#!/usr/bin/env python3 import mmap import struct BASE 0x42C00000 PAGE_SIZE 4096 PAGE_ALIGNED_BASE BASE ~(PAGE_SIZE - 1) MAP_SIZE PAGE_SIZE * 2 with open(/dev/mem, rb, buffering0) as f: mm mmap.mmap(f.fileno(), MAP_SIZE, offsetPAGE_ALIGNED_BASE) def read32(off): return struct.unpack(I, mm[off:off 4])[0] def write32(off, val): mm[off:off 4] struct.pack(I, val) offset BASE - PAGE_ALIGNED_BASE # 发送字符串 OK for ch in bOK: while not (read32(offset 0x10) 0x20): pass write32(offset 0x00, ch) # 回环接收一个字节 while not (read32(offset 0x10) 0x01): pass data read32(offset 0x00) 0xFF print(Received: 0x%02X % data) mm.close()这个脚本的本质就是自动化的寄存器操作非常适合用来验证回环、压力测试或量产自检。运行前确认你的用户有/dev/mem的读写权限通常需要root权限。5. 三种调试方式横向对比与选型建议5.1 功能、效率与门槛对照表把三种方法放在一起对比各自的定位就非常清晰了对比维度minicomscreendevmem寄存器操作安装依赖需额外安装到rootfs多数系统自带/busybox集成系统自带devmem配置复杂度中菜单化配置低一条命令高需要熟悉寄存器功能完整度高支持日志/文件传输中适合收发数据低裸数据读写定位问题层级应用层应用层驱动层/硬件层新手友好度高中低远程SSH表现一般优秀优秀适合场景日常交互调试快速验证/临时连接驱动异常/硬件链路排查从这个表能看出来三种方法并不矛盾反而是互补的。minicom适合“正经干活”screen适合“快速试探”devmem适合“底层证伪”。5.2 实战选型建议与组合用法以我自己的习惯遇到AXI UART Lite不通第一反应绝不是打开minicom而是先用devmem读一下LSR。如果LSR读出来全是0那可能是时钟没给上、复位没释放或者基地址错了这时候开终端工具纯属浪费时间。第二步用screen快速起一个会话发一个测试字符看回环是否正常。这时能确认Linux tty链路是否通了。如果screen能收能发说明串口本身没问题之前minicom不行大概率是配置问题。第三步才轮到minicom做完整的交互验证、日志记录、或者文件传输。这个组合下来从发现问题到定位问题通常不超过10分钟。关于选型没有绝对的最优工具只有最适合当前环节的工具。把三者都练熟能显著提升调试效率。6. 常见问题与排查技巧实录6.1 minicom乱码的常见原因与处理minicom乱码是最常见的串口问题几乎每个人都会遇到。乱码的根源其实很简单波特率、数据位、停止位、校验位只要有一项和硬件配置不一致就会显示为乱码或完全不可读。先从波特率入手查。AXI UART Lite的波特率是在Vivado IP配置时固定的很多默认工程会用9600或者115200。如果你不确定回到Vivado里查看IP配置或者直接用示波器测量TX引脚的信号宽度来反推波特率单bit宽度1/波特率。第二个原因是数据位/停止位不匹配。AXI UART Lite常见配置是8N1即8个数据位、无校验、1个停止位。如果硬件配置改成了7位甚至带奇偶校验minicom里的设置也要同步修改。第三个原因非常隐蔽硬件流控没关。前面强调过默认minicom配置里Hardware Flow Control是开启的如果你的板卡只接了TX、RX、GND那RTS/CTS流控信号是没有的数据会卡在发送端。处理方式统一在minicom -s的Serial port setup里改改完重启会话。如果依然乱码那就用devmem回环测试去排除硬件层问题。6.2 设备节点缺失或权限不足的排查很多情况下minicom/screen明明配置对了但程序提示无法打开设备文件。遇到这种情况先确认设备节点是否存在。ls -l /dev/ttyUL0 /dev/ttyS0 /dev/ttyUSB0 2/dev/null如果ttyUL0不存在先检查内核模块。执行lsmod | grep uartlite如果模块没有加载手动加载modprobe uartlite。如果模块加载了还是没有节点基本可以确定是设备树的问题需要回到Petalinux工程检查设备树里serial节点的状态是否为okay并且reg地址和Vivado里的地址一致。如果节点存在但提示Permission denied把当前用户加入dialout组sudo usermod -aG dialout $USER注意加组后必须重新登录或者新开一个SSH会话才生效。临时方案是sudo minicom直接以root运行但不推荐作为日常操作。6.3 devmem操作无反应的排查用devmem直接操作AXI UART Lite时最常见的现象是没有任何反应。这时候倒不一定是硬件坏了排查步骤非常关键。第一步确认基地址。很多板卡设计时Vivado会自动给IP分配地址同一套代码在不同版本Vivado下分配的地址可能不同。以Vivado的Address Editor为准别拿旧工程的地址硬套。第二步确认时钟。AXI UART Lite依赖s_axi_aclk时钟如果时钟没有使能寄存器读出来永远是0。在Vivado里查看时钟约束是否完整或者用devmem先读一下时钟控制器的寄存器确认对应的时钟输出是否正常。第三步确认复位。某些设计里PL侧外设的复位由PS端GPIO控制或者由Reset IP按特定顺序释放。如果复位信号一直拉低寄存器和总线访问都会超时或返回0xff。第四步做回环测试。把板卡的UART TX引脚和RX引脚直接用杜邦线短接然后用寄存器脚本发送数据并读取。如果能收到自己发的数据说明IP核本身工作正常问题在外部连接或其它电路上。6.4 PetaLinux构建与SD卡启动的补充提醒这篇文章侧重调试串口但如果你连系统都还没起来这些工具都用不了。所以我简单补充一下Petalinux构建和SD卡启动的流程尤其是较新的Petalinux 2025.1和经典Zynq平台的组合。常规构建顺序是petalinux-create -t project --template zynq --name myuartdebug cd myuartdebug petalinux-config --get-hw-description /path/to/xsa petalinux-config -c rootfs # 勾选minicom等调试工具 petalinux-build petalinux-package --boot --fsbl zynq_fsbl.elf --fpga system.bit --u-boot构建完成后会生成BOOT.BIN、image.ub以及常见的boot.scr。制作SD卡时把FAT32分区设置为启动分区放入BOOT.BIN、boot.scr和image.ub再准备一个ext4分区放rootfs镜像。需要注意新版本Petalinux对boot.scr的处理方式有些变化有些模板会自动生成boot.scr有些则直接编译进U-Boot脚本。如果SD卡启动后停在U-Boot界面先确认启动介质识别是否正常。启动起来后第一时间用dmesg确认ttyUL0是否注册成功再进入串口调试环节。最后一点私人心得我把这套流程跑了几年后最大的体会就是串口调试失败时永远先怀疑工具链而不是硬件。先用devmem读LSR用寄存器操作确认IP核是否在工作再用screen快速测试应用层通路最后才用minicom做完整的交互验证。这个方法让我躲过了无数次“白调半天最终发现只是终端配置问题”的尴尬。再分享一个小技巧调试前准备一张串口回环测试线TX和RX短接那种成本几块钱。它能在30秒内判断串口通路是否正常比任何高级工具都实用。AXI UART Lite本身不复杂复杂的往往是掩盖在表象下的驱动、时钟、设备树问题。把这三板斧练熟Zynq平台上的串口调试基本不会有能困住你的问题了。
返回列表