Files
story/docs/device-reinitialize-and-flash-20261004.md
T
Codex Local bf1233d5df
ci / verify (push) Canceled after 0s
feat: expand companion platform, device controls, and memoir workflows
Add customer and operator login, BLE provisioning, device fleet controls, call memory, memoir generation, and refreshed family and maintenance portals. Include API contracts, migrations, firmware sources, tests, assets, and deployment documentation.
2026-10-08 10:06:44 +08:00

172 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 原 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
```