172 lines
12 KiB
Markdown
172 lines
12 KiB
Markdown
# 原 COM6 设备:线上创建、烧录与初始化
|
||||
|
|
|
|||
|
|
现在可使用 [Windows 图形界面烧录助手](device-flasher-app-20261004.md),双击 EXE 后选择后台 JSON、检查预览并执行。下方保留完整命令行操作说明。
|
|||
|
|
|
|||
|
|
适用设备:之前那台 EchoEar ESP32-S3(EchoEar V1.2),16 MB Flash / 16 MB PSRAM,硬件 MAC `B4:3A:45:16:34:A8`。本次只读串口枚举确认当前仍为 COM6,USB VID:PID 为 `303A:1001`、序列标识与此 MAC 一致。重新插拔后串口号可能改变,工具会核对 MAC。
|
|||
|
|
|
|||
|
|
## 1. 这次为什么连接失败
|
|||
|
|
|
|||
|
|
10 月 4 日火山账号迁移的交付记录 `deliverables/volc-account-migration-20261004/上线与清空结果.json` 显示:云端设备、认证密钥、绑定、家庭、老人和供应商激活记录均已清空,只保留运维账号;实体设备的本地配置没有重置。
|
|||
|
|
|
|||
|
|
旧设备继续使用旧编号、旧认证密钥和旧语音配置时,新云端无法找到对应记录。这个证据足以解释认证失败,但本次没有读取真机串口,尚未确认设备屏幕上的错误具体落在哪一阶段。
|
|||
|
|
|
|||
|
|
项目已有初始化、重新配网和恢复出厂功能。但“恢复出厂”本身需要设备先通过云端认证,而且会保留出厂身份;云端已删除旧密钥时,不能靠此按钮重新生成身份。只换 Wi-Fi 也不会恢复已删除的云端登记。
|
|||
|
|
|
|||
|
|
本次建议:**线上重新创建设备 → USB 写新工厂身份并清理旧运行配置 → 家庭端重新配网绑定。保留当前实机固件即可。**
|
|||
|
|
|
|||
|
|
线上只读检查:2026-10-04 设备管理页面返回 HTTP 200,版本接口返回 `0.99.30-rc.captcha-off1`。这证明网页/版本接口可访问,不等于已经验证设备认证或语音通话。
|
|||
|
|
|
|||
|
|
## 2. 线上创建设备
|
|||
|
|
|
|||
|
|
1. 打开 [维护后台/设备管理](https://82.157.201.114/maintenance?area=devices),用保留下来的运维账号登录。
|
|||
|
|
2. 点“创建设备”,设备型号填 **ECHOEAR-S3**。
|
|||
|
|
3. 点“创建并下载烧录信息”。保存下载的 `KP01-……-burn-in-v1.json`。
|
|||
|
|
4. 检查下载文件里的 `origin` 为 `https://82.157.201.114`。如果后台仍导出旧地址,应先修正后台设备接入地址,再生成材料;不要把不同环境的设备密钥混用。
|
|||
|
|
|
|||
|
|
文件包含以下五项,由后台生成,不需自己编密钥:
|
|||
|
|
|
|||
|
|
| 字段 | 用途 |
|
|||
|
|
| --- | --- |
|
|||
|
|
| `factory_id` | 云端出厂编号,`KP01-` 开头。随机生成,不等于芯片 MAC。 |
|
|||
|
|
| `model` | 当前硬件使用 `ECHOEAR-S3`。 |
|
|||
|
|
| `origin` | 设备访问的平台 HTTPS 地址。 |
|
|||
|
|
| `key_version` | 这台设备的认证密钥版本。 |
|
|||
|
|
| `device_key_hex` | 32 字节设备认证密钥,由平台生成,必须与云端一致。 |
|
|||
|
|
|
|||
|
|
完整密钥只在创建或重置时提供。文件丢失后,设备行菜单“重置烧录信息”会立即废弃旧密钥,必须重新烧录新文件。设备编号、设备密钥要一机一份,不要复制给另一台机器。
|
|||
|
|
|
|||
|
|
## 3. 已补齐的程序
|
|||
|
|
|
|||
|
|
程序位于 `firmware/echoear-platform-agent/tools/`:
|
|||
|
|
|
|||
|
|
- `device_prepare.py`:直接接收后台下载的 JSON,生成该设备专属的 `ble_factory.bin`、`factory.csv`、`setup-label.json` 和校验清单 `manifest.json`。兼容现有后台的 `factory_id`,也兼容旧导出的 `device_id`。
|
|||
|
|
- `device_flash.py`:列串口、预览烧录计划、检查芯片/MAC/Flash/分区和镜像、完整备份、写入、校验。支持“只更新身份”和“完整固件烧录”。
|
|||
|
|
|
|||
|
|
工具不替你创建设备、不自动填 Wi-Fi,也不需要火山主账号的 AK/SK。真实烧录必须使用 `flash --execute`;`plan` 不连接设备。`ports` 只枚举串口。
|
|||
|
|
|
|||
|
|
准备工具会先设置输出目录权限,再写入秘密。`factory.csv`、`ble_factory.bin`、后台下载 JSON 和完整 Flash 备份均含设备秘密;放在本地私有目录,不提交 Git。下方默认放在项目已忽略的 `backups` 目录。
|
|||
|
|
|
|||
|
|
## 4. 这台旧设备的恢复操作(推荐)
|
|||
|
|
|
|||
|
|
### 4.1 打开 PowerShell,准备路径
|
|||
|
|
|
|||
|
|
这台电脑已安装 ESP-IDF Python、esptool 4.12.0、NVS 生成器 0.1.9,无需重复安装。
|
|||
|
|
|
|||
|
|
```powershell
|
|||
|
|
Set-Location 'E:\Codex\story\platform\firmware\echoear-platform-agent'
|
|||
|
|
$pythonPath = 'C:\Users\19926\.espressif\python_env\idf5.5_py3.12_env\Scripts\python.exe'
|
|||
|
|
$deviceMac = 'B4:3A:45:16:34:A8'
|
|||
|
|
$stamp = Get-Date -Format 'yyyyMMdd-HHmmss'
|
|||
|
|
$factoryDir = Join-Path $PWD "backups\factory-$stamp"
|
|||
|
|
$backupDir = Join-Path $PWD "backups\before-reinitialize-$stamp"
|
|||
|
|
$credentialPath = (Read-Host '请输入后台下载的 burn-in JSON 完整路径').Trim('"')
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 4.2 生成这台设备的初始化分区
|
|||
|
|
|
|||
|
|
```powershell
|
|||
|
|
& $pythonPath tools/device_prepare.py --credential $credentialPath --expect-mac $deviceMac --output $factoryDir
|
|||
|
|
if ($LASTEXITCODE -ne 0) { throw '初始化材料生成失败,请检查 JSON 和输出目录' }
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
成功显示 `prepared_not_flashed`。这一步只生成本地文件,没有写设备。工具拒绝覆盖已存在的输出目录。
|
|||
|
|
|
|||
|
|
### 4.3 查看串口与写入计划
|
|||
|
|
|
|||
|
|
用能传输数据的 USB 线连接设备,关闭串口监视器或其他占用串口的软件。
|
|||
|
|
|
|||
|
|
```powershell
|
|||
|
|
& $pythonPath tools/device_flash.py ports
|
|||
|
|
& $pythonPath tools/device_flash.py plan --factory-dir $factoryDir --identity-only --reset-runtime
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
确认计划只有两个区域:
|
|||
|
|
|
|||
|
|
| 区域 | 地址/大小 | 作用 |
|
|||
|
|
| --- | --- | --- |
|
|||
|
|
| 运行 NVS | `0x9000`/`0x6000` | 清除旧 Wi-Fi、配网任务、旧语音凭据、控制设置等本地运行状态。 |
|
|||
|
|
| 工厂身份 | `0xe4e000`/`0x6000` | 写入后台新创建的设备身份。 |
|
|||
|
|
|
|||
|
|
`--reset-runtime` 是这次云端清空后的重新初始化操作,会丢弃上述设备本地配置,需要重新配 Wi-Fi。它也会清除 NVS 中保存的 OTA 安装版本计数,使 `version_code` 回到 0;应用内固件版本字符串保留,下一次成功 OTA 会重建安装记录。它不执行云端解绑,也不是日常升级必需参数;只用于本次已清库设备或已完成云端解绑的重新制备。
|
|||
|
|
|
|||
|
|
应用、OTA 选择、语音模型和屏幕资源都保留。这可以保留此前已实机验收的 `.27` 固件。
|
|||
|
|
|
|||
|
|
### 4.4 真正执行
|
|||
|
|
|
|||
|
|
确认 `ports` 输出仍为 COM6;如果变了,把命令中的 COM6 改为实际串口。MAC 不能随意改。
|
|||
|
|
|
|||
|
|
```powershell
|
|||
|
|
& $pythonPath tools/device_flash.py flash --execute --port COM6 --expect-mac $deviceMac --factory-dir $factoryDir --identity-only --reset-runtime --backup-dir $backupDir
|
|||
|
|
if ($LASTEXITCODE -ne 0) { throw '烧录未完成:保留备份和输出,检查报错后再处理' }
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
工具会先核对物理设备、读取完整 16 MB Flash 并保存备份及校验记录,然后写入指定区域并校验。任何备份、布局或验证失败都不能当作完成。完成后手动按复位或断电重启,进入首次配网。
|
|||
|
|
|
|||
|
|
若无法自动进入下载模式,按住 BOOT,再点 RESET/重新连接 USB,然后松开 BOOT;使用板上的 BOOT/RESET,屏幕长按用于蓝牙配网,不能替代串口下载模式。若传输不稳定,先更换短数据线/USB 接口,并根据工具 `--help` 降低波特率。
|
|||
|
|
|
|||
|
|
## 5. 如果还要重烧完整固件
|
|||
|
|
|
|||
|
|
当前 `build/VolcRTCDemo.bin` 是 `1.7.0-controls.28`,构建通过,但交付记录明确其尚未安装、未进行真机验收。这次恢复身份无需升级它。
|
|||
|
|
|
|||
|
|
确实要重烧完整固件时,使用构建目录中的 `flasher_args.json` 和配套文件,不能只把一个应用 `.bin` 当作整机固件烧到地址 0,也不能照旧文档使用已变更的分区地址。
|
|||
|
|
|
|||
|
|
```powershell
|
|||
|
|
& $pythonPath tools/device_flash.py plan --build-dir build --factory-dir $factoryDir --reset-runtime
|
|||
|
|
# 核对计划中的固件版本、全部文件和区域后执行;使用新的备份目录。
|
|||
|
|
$fullBackupDir = Join-Path $PWD ('backups\before-full-flash-' + (Get-Date -Format 'yyyyMMdd-HHmmss'))
|
|||
|
|
& $pythonPath tools/device_flash.py flash --execute --port COM6 --expect-mac $deviceMac --build-dir build --factory-dir $factoryDir --reset-runtime --backup-dir $fullBackupDir
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
完整模式写 Bootloader、分区表、应用 ota_0、初始 otadata、语音模型和屏幕资源;重设 otadata 使 ota_0 启动,避免设备仍启动原 ota_1。提供 `--factory-dir` 才写工厂身份;不提供时保留原身份。
|
|||
|
|
|
|||
|
|
**完整 USB 烧录要求显式 `--reset-runtime`,之后要重新配网。** 原因是旧 NVS 内还有 `installed0` 等 OTA 版本及任务记录,只换应用和启动槽会使新固件继续上报旧版本。工具会拒绝保留这些旧记录的完整写入。默认 `plan` 可预览全部固件文件,但不能直接将未带此参数的计划执行。日常需保留 Wi-Fi/运行配置的升级,应走现有平台 OTA 流程。
|
|||
|
|
|
|||
|
|
需要从源码重新构建时,在固件工程目录执行:
|
|||
|
|
|
|||
|
|
```powershell
|
|||
|
|
$env:PYTHONUTF8 = '1'
|
|||
|
|
$env:PYTHONIOENCODING = 'utf-8'
|
|||
|
|
$env:Path = 'C:\Users\19926\.espressif\python_env\idf5.5_py3.12_env\Scripts;' + $env:Path
|
|||
|
|
. 'E:\Codex\toolchains\esp-idf-v5.5.1\export.ps1'
|
|||
|
|
idf.py -D CMAKE_NINJA_FORCE_RESPONSE_FILE=ON build
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
此工具针对当前 EchoEar 16 MB A/B 布局。它会拒绝不兼容的设备布局或镜像;不要通过强制参数绕过,也不要执行整片擦除。esptool 的读写和区域擦除行为见 [Espressif 官方烧录说明](https://docs.espressif.com/projects/esptool/en/latest/esp32s3/esptool/basic-commands.html)。
|
|||
|
|
|
|||
|
|
## 6. 烧录后配初始化信息
|
|||
|
|
|
|||
|
|
出厂身份在上面已写好;家庭 Wi-Fi、账号归属和老人资料通过正常使用流程配置。
|
|||
|
|
|
|||
|
|
1. 打开 [家庭端登录](https://82.157.201.114/login?returnTo=%2F),注册/登录客户账号。运维账号用于后台管理,不直接作为客户绑定账号。
|
|||
|
|
2. 在家庭管理创建家庭、添加老人信息。此次清库后这些数据需要重新建立。
|
|||
|
|
3. 打开设备页的“通过蓝牙添加设备”,或使用已配置为新平台地址的微信小程序设备添加入口。
|
|||
|
|
4. 设备首次启动进入配网;没有进入时长按圆屏**底部中央约 3 秒**。
|
|||
|
|
5. 搜索并选择 `vl-ECHOEAR-S3-xxxxxxxx`。后八位来自本次新云端编号,所以可能不再是之前的 `26091601`。
|
|||
|
|
6. 选择老人,填写有互联网的 **2.4 GHz WPA2 Wi-Fi** 及密码,发送后 **60 秒内轻触屏幕确认**。
|
|||
|
|
7. 等待明确成功提示,回设备页检查实际在线、固件版本,再发起一次聊天验证语音。
|
|||
|
|
|
|||
|
|
当前网页自动验证蓝牙身份,不需要自己填写设备密钥。支持 Web Bluetooth 的电脑或 Android Chrome/Edge 可走网页;iPhone 用微信小程序。新生成 `setup-label.json` 的密码用于兼容旧配网客户端,不是平台登录密码。
|
|||
|
|
|
|||
|
|
只“添加到我的账号”而不分配老人,可以先登记归属,但不能完成聊天初始化。火山语音实例、ProductKey、设备运行密钥和智能体配置由平台下发,**不要把火山主账号 AK/SK 写进设备**。
|
|||
|
|
|
|||
|
|
## 7. 常见结果怎么判断
|
|||
|
|
|
|||
|
|
| 现象 | 检查 |
|
|||
|
|
| --- | --- |
|
|||
|
|
| 后台创建成功但设备仍离线 | 云端记录创建不代表已经写入实体设备;检查是否执行了 flash,是否写入对应 JSON。 |
|
|||
|
|
| 校时/认证失败、无效设备 | 检查新编号、密钥版本、目标平台是否一致,是否误用已被“重置烧录信息”废弃的文件。 |
|
|||
|
|
| 能连 Wi-Fi 但仍使用旧语音配置/不进配网 | 本次清库恢复是否明确执行了 `--reset-runtime`。 |
|
|||
|
|
| 蓝牙发现后断开 | 断开不等于成功;看配网任务结果及云端绑定/在线状态。 |
|
|||
|
|
| 已绑定但不能聊天 | 是否分配老人,平台新火山账号的语音服务/智能体是否准备完成。 |
|
|||
|
|
| MAC 不匹配 | 选错串口或不是这台板;停止,核对设备。 |
|
|||
|
|
| 分区或镜像校验失败 | 构建文件不配套、设备布局不符或材料损坏;保留证据,不强刷。 |
|
|||
|
|
|
|||
|
|
本次交付包含工具与软件验证,尚未创建真实新设备、写入实体 Flash 或完成现场配网/通话验收。
|
|||
|
|
|
|||
|
|
软件验证:40 项烧录保护测试与 6 项初始化测试均通过;使用真实 NVS 生成器把模拟后台 JSON 生成为工厂镜像,并成功交给当前真实构建的身份写入计划。覆盖错误 MAC、重复 MAC 输出、镜像损坏、路径越界、备份失败、验证失败和完整 USB 烧录缺少运行态清理等情况。真实构建的六类固件文件及分区表通过离线校验。复现命令:
|
|||
|
|
|
|||
|
|
```powershell
|
|||
|
|
& $pythonPath -m unittest discover -s tools -p test_device_flash.py -q
|
|||
|
|
& $pythonPath -m unittest discover -s tests -p test_device_prepare.py -v
|
|||
|
|
```
|