海思HiTool烧写工具实战:从固件到板子的最后一公里
简介:海思HiTool烧写工具是一套面向嵌入式开发与机顶盒/电视主板维修人员的硬件烧录工具包,适合需要为海思系列芯片进行镜像烧写、寄存器调试与升级包制作的工程师使用。压缩包共1220个文件,约166.47MB,内含jar、cfg、chip、dll、svf、xml、tcl、exe等多种类型:cfg与chip文件对应芯片配置与型号支持,dll与jar支撑图形界面运行,svf与tcl多用于边界扫描与脚本控制,exe为可执行工具主体。工具集包含HiDebugger调试信息抓取与码流录制、HiLoader升级包制作、HiBurn镜像烧写与上载、HiReg图形化寄存器及内存读写、HiFastplay开机画面与瞬播镜像制作等模块,覆盖从调试到量产的常见环节。目前已有3231人学习下载,可帮助读者快速搭建烧录环境、理解分区表与镜像操作流程,并借助内置脚本与配置模板减少重复摸索,适合作为海思平台烧写与调试的实用参考工具包。
1. 海思HiTool烧写工具:从固件到板子的最后一公里
手里拿到一块基于海思芯片的开发板,固件编译完了,镜像文件躺在输出目录里,接下来要把它写进板子的 eMMC 或 SPI Flash。这个环节翻车的概率不低:分区表对不上、串口没反应、USB 识别不到设备、烧完起不来。海思 HiTool 就是干这件事的工具——它把串口、USB、网口三条烧写通道整合到一个界面里,支持分区表配置、镜像打包、批量烧录和读写回读校验。源码软件包里通常包含主程序、驱动、分区表模板和若干脚本。适合嵌入式驱动工程师、产线测试人员和做板级 Bring-up 的开发者。如果你正在找一款能稳定把镜像烧进海思板子、并且能排查烧写失败原因的工具,这篇拆解值得往下看。
2. HiTool 的烧写通道与分区表机制
2.1 三条烧写通道的选型逻辑
HiTool 支持串口、USB 和网口三种烧写方式,选哪条路取决于板子的启动模式和你的调试阶段。
串口烧写是最底层的兜底方案。板子上电后 BootROM 先跑,此时 CPU 从串口等待握手信号。HiTool 通过串口发送 DDR 初始化参数和烧写代理程序,代理程序跑起来之后再通过串口传输镜像数据。这条路的优点是几乎不依赖板子上已有的任何软件,裸板也能烧;缺点是速度慢,烧一个 200MB 的 rootfs 可能要十几分钟。我一般只在板子完全变砖、或者第一次 Bring-up 时用串口。
USB 烧写是日常调试的主力。板子进入 USB 烧写模式后,HiTool 通过 USB 批量传输端点发送数据,速度比串口快一个数量级。前提是板子的 USB 控制器和驱动已经配置好,且 BootROM 支持 USB 启动。常见做法是在分区表里把 fastboot 或烧写模式的分区留出来,上电时通过按键或 GPIO 拉低进入该模式。
网口烧写适合产线批量场景。板子跑一个 TFTP 客户端或者 HiTool 配套的烧写服务端,HiTool 通过 UDP 或 TCP 把镜像推过去。速度最快,但依赖网络环境和板端服务已经就绪。选型时记住一个原则:越底层的通道越可靠但越慢,越上层的通道越快但依赖越多。
2.2 分区表配置:烧写成败的第一道关
HiTool 烧写不是简单地把一个镜像写到固定地址,而是按照分区表把不同镜像写到 eMMC 或 Flash 的不同偏移位置。分区表通常是一个 XML 或文本文件,里面定义了每个分区的名称、起始地址、大小和对应的镜像文件。
一个典型的分区表结构如下:
<!-- 分区表模板:每个 partition 对应一个烧写区域 -->
<partition_table>
<!-- fastboot 分区:存放 bootloader,起始地址 0x0 -->
<partition name="fastboot" start="0x00000000" size="0x00100000">
<image file="fastboot.bin"/>
</partition>
<!-- boot 分区:存放内核和设备树 -->
<partition name="boot" start="0x00100000" size="0x00800000">
<image file="kernel.bin"/>
</partition>
<!-- rootfs 分区:存放根文件系统 -->
<partition name="rootfs" start="0x00900000" size="0x0F700000">
<image file="rootfs.ext4"/>
</partition>
</partition_table>
这段配置里, start 是相对于存储介质起始地址的偏移, size 是分区大小, image 指定要烧写的镜像文件。逻辑很直白:HiTool 读这张表,按顺序把每个镜像写到对应偏移。参数说明上, start 和 size 必须和板端实际存储布局一致,否则会出现覆盖或者空洞。常见坑是分区大小算错——比如 rootfs 实际 180MB,分区只给了 160MB,烧写时 HiTool 可能不报错但板子启动到挂载 rootfs 时失败。
2.3 镜像打包与烧写参数配置
HiTool 支持把多个镜像打包成一个 update.img ,产线烧写时只需要选一个文件。打包配置里需要指定每个分区的镜像路径、文件系统类型和烧写模式。
# 使用 HiTool 命令行模式打包镜像(常见做法)
# -t 指定存储类型为 emmc,-p 指定分区表文件
hitool_cli pack -t emmc -p partition.xml -o update.img
# 烧写时指定串口和波特率
hitool_cli burn -c com3 -b 115200 -f update.img
命令行模式下, -t 参数决定目标存储介质是 eMMC 还是 SPI Flash, -p 指定分区表, -o 是输出文件名。烧写命令里 -c 是串口号, -b 是波特率, -f 是镜像文件。参数改动的边界在于:波特率不是越高越好,有些板子的串口在高波特率下丢包,反而导致烧写失败。我一般先用 115200 跑通,再尝试 921600。
3. 从零完成一次 HiTool 烧写的完整流程
3.1 环境准备与驱动安装
在 Windows 上使用 HiTool,第一步是装 USB 驱动。海思芯片的 USB 烧写模式通常枚举为一个特定 VID/PID 的设备,驱动包里一般带一个 inf 文件。安装时如果系统提示签名问题,需要临时禁用驱动签名强制。Linux 下则简单得多,直接用 libusb 就能识别,但需要把 udev 规则配好,否则普通用户没权限访问设备。
# Linux 下添加 udev 规则,让普通用户能访问海思 USB 设备
# 创建规则文件
sudo tee /etc/udev/rules.d/99-hitool.rules << 'EOF'
# 海思 USB 烧写设备,VID 和 PID 根据实际枚举结果填写
SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", ATTR{idProduct}=="4ee0", MODE="0666"
EOF
# 重新加载 udev 规则
sudo udevadm control --reload-rules
sudo udevadm trigger
这段规则的作用是给指定 VID/PID 的 USB 设备赋予读写权限。 idVendor 和 idProduct 需要用 lsusb 命令查看板子进入烧写模式后的实际值。逻辑说明:udev 规则匹配到设备后设置 MODE="0666" ,这样非 root 用户也能打开设备节点。参数上,如果板子有多个 USB 配置,可能需要加 ATTR{bConfigurationValue}=="1" 来精确匹配。
3.2 串口烧写实操:裸板 Bring-up
串口烧写是验证板子是否活着的第一个测试。接线很简单:板子的调试串口 TX/RX/GND 接到 USB 转串口模块,注意 TX 和 RX 要交叉。
# 使用 HiTool 命令行进行串口烧写
# 第一步:进入烧写模式,板子上电时按住烧写按键
# 第二步:执行烧写命令
hitool_cli burn -c /dev/ttyUSB0 -b 115200 -f update.img --mode serial
# 如果烧写过程中断,查看日志
hitool_cli burn -c /dev/ttyUSB0 -b 115200 -f update.img --mode serial --log burn.log
--mode serial 指定走串口通道, --log 把烧写过程写入日志文件。逻辑上,HiTool 先通过串口发送握手包,板端 BootROM 回应后,HiTool 发送 DDR 初始化参数,然后分块传输镜像。参数说明: -b 波特率在串口模式下建议先用 115200,稳定后再试更高值。失败时看日志里有没有 timeout 或 checksum error ,前者通常是接线或波特率问题,后者是传输过程中数据损坏。
3.3 USB 烧写实操:日常调试首选
USB 烧写的前提是板子已经能进入 USB 烧写模式。常见做法是在 bootloader 里配置一个 GPIO 按键,上电时检测到按键按下就进入烧写模式,否则正常启动。
# USB 烧写命令
hitool_cli burn -u -f update.img --mode usb
# 指定只烧写特定分区
hitool_cli burn -u -f update.img --mode usb --partition rootfs
# 烧写后回读校验
hitool_cli burn -u -f update.img --mode usb --verify
-u 表示 USB 通道, --partition 可以只烧写某个分区,适合调试时只更新 rootfs。 --verify 会在烧写完成后把数据读回来做校验,产线场景建议加上。逻辑说明:USB 模式下 HiTool 通过批量端点发送数据,板端代理程序接收后写入存储介质。参数上, --verify 会增加烧写时间,但能提前发现存储介质坏块问题。
3.4 网口烧写实操:产线批量场景
网口烧写需要板端先跑一个烧写服务。HiTool 配套的 SDK 里通常有一个 hitool_server 程序,交叉编译后放到板子上,开机自启。
# 板端启动烧写服务
./hitool_server -p 5000 -d /dev/mmcblk0
# 主机端通过网口烧写
hitool_cli burn -n 192.168.1.100:5000 -f update.img --mode net
板端 hitool_server 的 -p 指定监听端口, -d 指定目标存储设备。主机端 -n 指定板子 IP 和端口。逻辑上,HiTool 把镜像分块通过 TCP 发给板端服务,板端服务负责写入存储。参数说明:网口烧写速度最快,但要求板端网络已经配置好,且烧写服务已经运行。产线场景下,通常把板端服务做成开机自启,主机端用脚本批量调用。
4. 烧写失败排查:五个高频踩坑记录
4.1 串口无响应,HiTool 一直等待握手
现象 :点击烧写后,HiTool 进度条不动,日志显示 waiting for handshake 。
原因 :串口 TX/RX 接反、波特率不匹配、板子没有进入烧写模式,或者串口被其他程序占用。
解决 :先用串口终端工具确认板子上电后有输出。如果没有输出,检查接线和波特率。如果有输出但 HiTool 连不上,确认板子是否在启动时按住了烧写按键。Linux 下用 lsof /dev/ttyUSB0 检查串口是否被占用。
4.2 USB 设备识别不到
现象 :板子进入烧写模式后,设备管理器里没有出现新设备,或者出现未知设备。
原因 :驱动没装、VID/PID 不匹配、USB 线质量差,或者板子 USB 控制器没初始化。
解决 :先用 lsusb 确认设备是否枚举。如果枚举了但驱动没装,手动指定 inf 文件安装。如果没枚举,换一根 USB 线,或者检查板子 USB 供电是否足够。有些板子需要外部供电才能稳定枚举。
4.3 烧写过程中断,报 checksum error
现象 :烧写到一半报校验错误,进度回退。
原因 :存储介质有坏块、USB 或串口传输丢包、镜像文件本身损坏。
解决 :先校验镜像文件的 MD5,确认文件完整。然后降低波特率或换 USB 口。如果是 eMMC 坏块,用 mmc extcsd read 查看坏块数量,必要时换板子。
4.4 烧写完成但板子起不来
现象 :HiTool 显示烧写成功,但板子上电后串口无输出或卡在某个阶段。
原因 :分区表地址和实际存储布局不一致、镜像类型不对、DDR 初始化参数不匹配。
解决 :核对分区表的 start 和 size 是否和板端一致。确认镜像格式是否正确,比如 eMMC 需要 ext4 镜像,SPI Flash 需要裸数据镜像。DDR 参数通常由 BootROM 自动检测,但有些板子需要手动指定。
4.5 网口烧写速度慢或超时
现象 :网口烧写速度远低于预期,或者频繁超时。
原因 :网络带宽不足、板端服务处理慢、MTU 不匹配。
解决 :先用 ping 测试网络延迟和丢包。如果网络正常,检查板端 hitool_server 的 CPU 占用,可能是写入速度跟不上。调整 MTU 到 1500 以下试试。产线场景建议用千兆交换机直连,避免经过路由器。
5. 进阶技巧:用脚本批量烧写与校验
产线场景下,手动点 HiTool 界面效率太低。我一般会写一个批处理脚本,把烧写、校验、日志记录串起来。
#!/bin/bash
# 批量烧写脚本:遍历所有连接的板子,依次烧写并校验
# 适用场景:产线一拖多烧写
# 串口列表,实际使用时根据枚举结果修改
PORTS=("/dev/ttyUSB0" "/dev/ttyUSB1" "/dev/ttyUSB2" "/dev/ttyUSB3")
IMAGE="update.img"
LOG_DIR="./burn_logs"
mkdir -p "$LOG_DIR"
for port in "${PORTS[@]}"; do
# 提取串口号作为日志文件名
port_name=$(basename "$port")
log_file="$LOG_DIR/${port_name}_$(date +%Y%m%d_%H%M%S).log"
echo "开始烧写 $port ..."
# 执行烧写并校验,日志写入文件
hitool_cli burn -c "$port" -b 115200 -f "$IMAGE" \
--mode serial --verify --log "$log_file"
# 检查上一条命令的退出码
if [ $? -eq 0 ]; then
echo "$port 烧写成功"
else
echo "$port 烧写失败,查看日志:$log_file"
fi
done
这段脚本的逻辑是:遍历串口列表,对每个串口执行烧写命令, --verify 开启回读校验, --log 把过程写入独立日志文件。 $? 检查上一条命令的退出码,非零则标记失败。参数上, PORTS 数组需要根据实际枚举的串口设备修改, IMAGE 指向打包好的镜像。这个脚本的边界在于:串口烧写本身是串行的,多个串口同时烧写会争抢 CPU 和 USB 带宽,实际产线建议用 USB 通道做并行。
另一个实用技巧是烧写前的镜像完整性检查。我习惯在烧写脚本开头加一段 MD5 校验:
# 烧写前校验镜像 MD5,避免因文件损坏导致批量失败
EXPECTED_MD5="a1b2c3d4e5f6..."
ACTUAL_MD5=$(md5sum "$IMAGE" | awk '{print $1}')
if [ "$EXPECTED_MD5" != "$ACTUAL_MD5" ]; then
echo "镜像 MD5 不匹配,终止烧写"
exit 1
fi
EXPECTED_MD5 是打包镜像时记录的 MD5 值, ACTUAL_MD5 是当前文件的 MD5。不匹配直接退出,避免把损坏的镜像烧进板子。这个习惯是从一次血泪经验来的:当时产线烧了 50 块板子,全部起不来,最后发现是镜像在拷贝过程中损坏了。从那以后我每次批量烧写前都强制走一遍 MD5 校验,再也没翻过车。希望帮到你。
更多推荐



所有评论(0)