# 原 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 ```