3. TFTP客户端工具:从命令行到图形化,把文件传进板子
TFTP这玩意儿,说白了就是个“极简版的文件搬运工”。它不像FTP那样要登录、要列目录,也不像SCP那样要加密握手。它的设计哲学就一条:能传文件就行,别的别废话。在嵌入式Linux的烧录场景里,我们恰恰就需要这种简单粗暴——U-Boot里那点资源,跑个复杂的协议根本不现实。
我个人习惯把TFTP客户端分成三类:Linux原生命令行、Windows下的PuTTY套件、以及纯命令行版tftp.exe。今天咱们一个一个过,最后再聊聊传输效率和那些坑。
3.1 Linux下的tftp命令:最趁手的工具
大多数Linux发行版默认不带tftp客户端,得手动装一下:
# Debian/Ubuntu系
sudo apt install tftp-hpa
# Red Hat/CentOS系
sudo yum install tftp
装好之后,用法其实特别简单。我通常这么用:
# 交互模式
tftp 192.168.1.100
tftp> get uImage
tftp> put zImage
tftp> quit
# 一行命令搞定
tftp 192.168.1.100 -c get uImage
tftp 192.168.1.100 -c put local_file.txt
这里有个细节要注意——-c参数表示“立即执行命令”,不加的话就进交互模式。我在项目中遇到过好几次,脚本里忘了加-c,结果tftp卡在交互界面,整条流水线都停了。
tftp -c加timeout包裹。比如timeout 10 tftp 192.168.1.100 -c get uImage,防止网络异常时脚本死等。
3.2 Windows下的TFTP客户端:PuTTY套件与命令行
Windows用户的选择其实更多。我最早用Windows做开发时,试过好几个工具,最后固定下来两套方案。
方案一:PuTTY自带的PSFTP(其实不是TFTP)
这里先纠正一个常见误解:PuTTY自带的PSFTP是SFTP客户端,走的是SSH协议,不是TFTP。很多人搞混了,包括我刚开始也踩过这个坑。真正要用的,是PuTTY套件里的psftp.exe?不对,它还是SFTP。
Windows下真正的TFTP客户端,我推荐用这个:
| 工具 | 来源 | 特点 |
|---|---|---|
| tftp.exe | Windows自带(需启用) | 命令行,功能最基础 |
| TFTPD64 | 第三方免费工具 | 图形界面,支持服务端+客户端 |
| SolarWinds TFTP | 第三方免费工具 | 轻量,稳定,我用了好几年 |
启用Windows自带tftp.exe
Windows 10/11默认不开启TFTP客户端,需要手动打开:
# 方法一:控制面板
控制面板 → 程序和功能 → 启用或关闭Windows功能
→ 勾选"TFTP客户端" → 确定
# 方法二:管理员PowerShell
Enable-WindowsOptionalFeature -Online -FeatureName "TFTP"
启用后,用法和Linux几乎一样:
tftp 192.168.1.100 GET uImage
tftp 192.168.1.100 PUT local_file.txt
GET和PUT是大写的,而且参数顺序和Linux相反。我曾经在脚本里写错了大小写,排查了半天才发现是这个问题。
3.3 TFTP文件上传与下载实战:从板子到PC
光说不练假把式。咱们来一个完整的实战流程:把编译好的内核镜像从PC传到开发板。
场景:PC做服务端,开发板做客户端
这是最常见的烧录场景。开发板在U-Boot里,通过TFTP从PC拉文件。
第一步:PC端启动TFTP服务端
# Linux PC
sudo apt install tftpd-hpa
sudo systemctl start tftpd-hpa
# 默认根目录:/srv/tftp/
# Windows PC(以TFTPD64为例)
# 打开TFTPD64.exe → 选好网卡IP → 设置根目录 → 点Start
第二步:把文件放到服务端根目录
# Linux
sudo cp uImage /srv/tftp/
# Windows
# 直接把文件拖到TFTPD64设置的根目录文件夹
第三步:开发板U-Boot里执行tftp命令
# 先设好IP
setenv ipaddr 192.168.1.10
setenv serverip 192.168.1.100
# 拉文件到内存地址0x82000000
tftp 0x82000000 uImage
如果一切顺利,你会看到类似这样的输出:
Using FEC device
TFTP from server 192.168.1.100; our IP address is 192.168.1.10
Filename 'uImage'.
Load address: 0x82000000
Loading: #################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
done
Bytes transferred = 4194304 (4 MiB)
每个#号代表一个数据块(默认512字节)。看到这个,说明传输成功了。
3.4 TFTP传输超时与重传机制:为什么有时候会卡住?
TFTP的传输机制其实很原始。它基于停等协议——发一个数据块,等一个ACK,再发下一个。如果ACK没回来,就重传。
具体参数是这样的:
| 参数 | 默认值 | 说明 |
|---|---|---|
| 超时时间 | 5秒 | 发送数据块后等待ACK的最长时间 |
| 最大重传次数 | 5次 | 超过这个次数就放弃传输 |
| 数据块大小 | 512字节 | 标准TFTP固定值,可协商增大 |
为什么会超时?我总结了几种常见情况:
- 网络丢包——最典型的原因。特别是在无线网络或嘈杂的工业环境里。
- 服务端负载过高——服务端来不及处理请求,ACK发不出来。
- 防火墙拦截——TFTP使用UDP 69端口,很多防火墙默认不信任UDP。
- MTU不匹配——数据块太大,被分片后部分丢失。
我曾经在一个项目里遇到过:板子放在产线末端,TFTP烧录总是随机失败。排查了三天,最后发现是产线的交换机开启了UDP风暴抑制,把TFTP的重传包当成了攻击流量。关掉那个功能后,问题就解决了。
3.5 TFTP传输速率测试:到底能跑多快?
TFTP的传输速率,说实话,不快。但到底有多慢?咱们用数据说话。
我做了个简单测试:用同一个文件(4MB的uImage),在不同条件下传输,记录耗时。
| 网络环境 | 数据块大小 | 耗时 | 平均速率 |
|---|---|---|---|
| 百兆直连 | 512字节 | 约3.2秒 | 1.25 MB/s |
| 百兆直连 | 1468字节(协商) | 约1.1秒 | 3.64 MB/s |
| 千兆直连 | 512字节 | 约2.8秒 | 1.43 MB/s |
| 千兆直连 | 1468字节(协商) | 约0.8秒 | 5.0 MB/s |
看到没?数据块大小对速率影响巨大。默认512字节实在太保守了。好在TFTP支持块大小协商(RFC 2348),客户端和服务端可以商量用更大的块。
在U-Boot里,可以这样设置:
# 设置块大小为1468字节(以太网MTU 1500 - 20 IP头 - 8 UDP头 - 4 TFTP头)
setenv tftpblocksize 1468
# 然后正常tftp
tftp 0x82000000 uImage
在Linux客户端,可以用--blocksize参数:
tftp 192.168.1.100 -c get uImage --blocksize 1468
下面这张图总结了TFTP客户端工具的核心知识体系:
最后说一句:TFTP虽然慢,但胜在简单可靠。在嵌入式Linux的烧录场景里,它依然是U-Boot时代最主流的文件传输方式。掌握好这些客户端工具,你就能在板子和PC之间自由搬运文件了。