Update embedded app debugging workflow

This commit is contained in:
zoukai committed 2026-10-22 14:09:49 +08:00
1 parent d50be29246
commit 38807e5f97
13 files changed
+846 -122

No files matched your search

+22
View File
@@ -33,6 +33,13 @@ mount -t nfs <服务器IP>:/nfs/<用户名> /mnt/nfs -o nolock
7. NFS 已挂载时必须与本次确认的服务器和导出路径完全一致。源程序必须通过 ELF 架构和解释器检查;设备缺少 `readelf` 时默认停止,只有人工看过有限检查结果后才可显式放行。
8. 在线停止已有进程时必须提供从当前设备实查得到的失败恢复命令。脚本会在替换失败时尝试恢复原文件和原进程,并在设备 `/tmp/codex-module-<模块>-<动作>-<时间>.state` 记录事务阶段;出现命令超时、会话中断、掉电或 `ROLLBACK_FAILED` 时状态未知,禁止直接重试,必须重新核对设备身份后读取事务状态,检查进程、目标哈希和备份,不能宣称已自动恢复。
### NFS 联调的配置与运行证据
- 替换前记录现有程序路径、PID、启动参数、配置工作目录、必要环境开关、动态库来源和恢复方式。用户手工调整的上线条件、持续运行设置、服务器地址等配置保持不变;不能因重新部署二进制而用工程默认文件覆盖。仅在用户明确要求修改某字段时最小化更改该字段,记录配置哈希与差异,不连带修改其他设置。
- 新版本沿用当前任务确认的启动方式和配置目录;配置依赖相对路径时,不能只切换到 NFS 程序目录启动。核对动态加载器、库路径、必要 `.so` 和符号链接,不能因文件已复制或程序短暂出现就认为依赖齐全。
- 启动后记录 PID,并在可用时通过 `/proc/<pid>/exe`、`cmdline`、`cwd` 核对实际运行文件、参数和工作目录;计算对应部署文件的 SHA-256,必要时检查 `maps` 中实际加载的库来源。不能仅凭进程名、旧日志标记或启动命令返回 0 判断新程序已生效。
- 观察常驻进程持续存活及目标业务结果,区分构建、拷贝、启动和功能验证的结论。已有配置未要求变更时核对前后哈希一致;未验证的功能明确列为待验证,不扩张为整机或全部业务通过。只重启明确授权的模块,不把整机重启或其他关键服务重启作为默认联调步骤。
## DxMain 与 daemon.sh
不要在 `daemon.sh` 或其后台软件看门狗仍运行时停止 `DxMain`。守护逻辑可能重新启动 `DxMain`,关键服务丢失时还可能执行强制重启。
@@ -59,6 +66,21 @@ mount -t nfs <服务器IP>:/nfs/<用户名> /mnt/nfs -o nolock
5. 重启前串口必须已经打开并确实收到数据,同时给出可以通过串口执行的恢复命令。完成修改不等于取得重启授权;集中展示变更、备份和预期后等待明确的“确认重启”。
6. 重启后通过串口观察完整启动过程,核对目标进程、守护进程、工厂程序、异常退出、panic、看门狗和循环重启;网络恢复后再使用协议或 Telnet 辅助验证。
## 运行中恢复网络服务
网卡在开机阶段缺失时,依赖它的服务可能已经退出,也可能作为其他主进程内的线程存在。不要只用 `ps | grep <服务名>` 判断服务是否存在;同时检查启动日志、监听端口、Launcher 配置和当前工程实现。
在已经运行的整机上单独启动或重启 NetServer 等网络服务前,先读取 `daemon.sh`、WatchDog 逻辑和关键进程关系。消息总线重连、关键服务短暂断开或守护检测可能触发整机重启。未经明确授权不要用在线重启服务试探;需要恢复升级通道时,优先采用影响范围更小且可回退的临时步骤,例如加载已验证驱动、恢复已确认的产品 MAC、关联和 DHCP。
临时网络恢复也要遵守以下边界:
1. 先通过串口确认设备身份、当前版本和产品网络配置,再执行会改变接口状态的命令。
2. 加密网络 param 只在唯一 `/tmp` 副本上解密;从副本提取当前设备已有的 SSID、PSK 和 MAC,不把明文打印到终端摘要、任务消息或 skill。
3. 只创建临时 wpa_supplicant 配置,任务结束时删除;需要持久写回配置时按 param 修改流程重新取得授权。
4. 记录每个阶段的证据:驱动加载、接口创建、MAC、关联、租约、路由、监听端口和 PC 可达性。
5. 临时恢复后的升级仍必须通过标准协议身份预检;不得把串口身份作为跳过 `30101` 的理由。
6. 新固件升级后必须重启验证自动恢复;如果还需要任何手工步骤,修复不能判为通过。
## 烧录状态与工厂模式
未烧录设备可能自动进入产测流程;已烧录设备通常进入正常流程,只有强制工厂标志生效时才运行产测程序。具体判断可能使用 MAC/SN 文件、文件大小、加密烧录数据、环境变量或标志文件,必须从当前工程和设备的 `function.sh`、`appinit.sh`、`allstart.sh` 实查。
+12 -4
View File
@@ -1,13 +1,13 @@
# 远程打包与产物归档
仅在任务涉及编译新固件或下载远程产物时读取本文件。
仅在任务涉及远程编译(完整固件或单模块)或下载远程产物时读取本文件。
## 默认值与覆盖
| 项目 | 默认值 |
|---|---|
| SSH Host | `emb.eapil.com` |
| 工程搜索根 | 当前远程工作区、`~/work/develop/gitcode`、实际挂载点;`/CamTells` 仅作兼容候选 |
| 工程搜索根 | 当前远程工作区、`~/work/develop/gitcode`、实际挂载点;可把已知产品目录(例如 `/CamTells`)作为候选之一,不限于该目录 |
| Public 来源 | `~/work/develop/gitcode/EMX2.1` |
| 本地归档根目录 | `F:\tmp\embedded-app-pc-debug` |
@@ -16,10 +16,10 @@
## 工程定位
1. 先用现有 SSH/VS Code 配置解析 Host,不猜测用户名、端口或私钥路径。
2. 优先使用用户给出的绝对路径。只给项目名时,从 VS Code 最近工作区、`~/work/develop/gitcode`、`/CamTells` 和实际挂载点按目录名精确搜索;搜索深度至少覆盖从用户目录起 12 层,并为每个根设置独立合理超时。
2. 优先使用用户给出的绝对路径。只给项目名时,从 VS Code 最近工作区、`~/work/develop/gitcode`、实际挂载点和已知产品目录按目录名精确搜索;`/CamTells` 是可选候选,不代表其他产品工程的位置。搜索深度至少覆盖从用户目录起 12 层,并为每个根设置独立合理超时。
3. PowerShell 调用远端 Shell 时,避免让本地提前展开远端 `$HOME` 等变量。记录每个搜索根的退出码并明确区分:没有匹配、无权访问、路径未挂载、命令不存在和搜索超时。超时不等于项目不存在。
4. 如果有多个候选,列出远程绝对路径等待选择;不要凭目录修改时间挑选。
5. 确认工程目录包含待用脚本,再确定真实命令行参数。类似 `product/CamTells/EPM21C` 的深层产品目录不能因浅层 `find -maxdepth` 被排除。
5. 确认工程目录包含待用脚本,再确定真实命令行参数。产品目录可能较深,例如 `product/<产品线>/<项目>`;不能因浅层 `find -maxdepth` 排除有效工程。
## 构建顺序
@@ -31,6 +31,14 @@
6. 尊重构建脚本内部的校验与重建循环。脚本因随机命中、签名或封装检查而自动重建时,让脚本自行完成;不要在外层重复启动、重复改版本或把一次内部重建误报为多个发布版本。
7. 构建失败时不下载旧产物。若本次 ROM 已由脚本明确生成、校验通过,而随后仅全量烧录镜像或其他辅助目标失败,应分开报告:允许交付已验证 ROM 用于局域网升级,但完整发布包仍判为失败或不完整。
## 单模块交叉编译与 NFS 交付
用户只要求编译某个应用或库时,不强制执行完整固件的 `product.py`、`release.py` 流程。优先复用当前远程工程已验证的构建目录和目标,核对其源码目录、交叉工具链、目标架构及必要构建选项;缓存指向其他工程或工具链时先说明冲突,不直接覆盖或继续编译。
记录实际构建目标、命令、退出码、本次产物的绝对路径、大小、SHA-256 和 ELF 信息。按运行需求交付必要动态库及其链接关系,不把静态库、开发头文件或旧目录中的同名文件一概当成设备运行依赖。
用户指定 NFS 导出目录时,在该目录下使用独立的本次产物目录,保留旧程序和依赖;避免覆盖设备正在从 NFS 执行的二进制。拷贝后核对源与目标的哈希及执行权限,并明确区分“远端构建完成”“NFS 产物已就绪”“设备已运行”“功能验证通过”。设备验证步骤见 [应用模块调试](application-debugging.md),不能因完成拷贝就宣称验证通过。
## 打包任务交付清单
Linux 打包任务应一次性交付以下事实,供 Windows 设备任务直接使用:
+12
View File
@@ -23,6 +23,18 @@
- 读取不到任务正文时,先核对任务 ID 和主机 ID,再查看最新任务状态。只有任务工具确实不能返回内容时,才在已授权主机上读取对应会话记录或请用户转交摘要。
- 任务 ID、主机 ID、项目路径和远端临时目录都属于本次运行参数,不写成通用固定值。
用户给出 `codex://threads/<UUID>` 并要求直接向原会话发送时,优先使用会话消息能力。若本机执行 `codex queue --thread <UUID> --message <内容>` 返回 `no rollout found`,这只说明当前 app-server 的本地线程存储没有该 rollout,不代表 UUID 无效,也不能改为新建会话。
确认目标 rollout 实际驻留的已授权主机后,可以通过现有 SSH 配置在该主机执行同一条 `codex queue`:
```text
codex queue --thread <UUID> --message <完整任务消息>
```
只在命令明确返回 `Queued message <message-id> for thread <UUID>` 后报告送达,并保留 message ID。打开线程页面、导航成功、命令退出但无确认、读取结果为空或中继已收到,都不能冒充原会话已收到消息。消息入队只证明投递成功,不证明对方已执行、构建完成或产物可用;后续状态仍需从原会话或产物证据确认。
直接投递消息应包含工程路径、已确认事实、要求的修改与验证、产物交付字段和禁止操作边界。不要把某次线程 UUID、SSH 主机、设备身份或工程路径写成固定值,也不要在参数中暴露密码、PSK 或 Token。
## 最小交接消息
```text
+49 -25
View File
@@ -11,43 +11,65 @@
- `C:\Users\ZK\Downloads\设备端TCP文件传输类协议.md`
- `C:\Users\ZK\Downloads\工厂协议V1.md`
- `E:\CodeSpace\git-pro\eapil_qt_player_v2\EpProtocolDemo`
- `E:\CodeSpace\git-pro\eapil_public_library\EapilPanoC\src`(V1 命令、端口、数据结构和 Qt 客户端实现;以当前源码为实现依据,部署设备仍需实测)
## 协议资料总览
## V1 协议(EapilPanoC)
本技能覆盖的协议资料不止设备搜索和升级。按当前本机资料,范围包括:
V1 与 V2 使用不同端口和帧格式,不能把 `EPBP/EPTP/EPFP` 的 V2 帧头套用到 V1 通用配置接口。
| 协议族 | 资料范围 | 本技能的使用方式 |
| 功能 | 传输与端口 | 请求/响应格式 |
|---|---|---|
| V1 工厂协议 | 66 条工厂/产测命令;UDP 搜索与 TCP 控制 | `scripts/v1_discover.py` 搜索;`scripts/v1_command.py` 对文档中任意 CMD 发送 JSON 请求 |
| V2 广播发现 | EPBC/EPBD、UDP 8941/8951、cmd 60000 | `scripts/v2_discover.py` |
| V2 统一配置 | cmd 30101 起,覆盖基本信息、网络、音视频、音频、设备操作、SD 卡、夜视、时间、OSD、IO 等文档章节 | TCP 8942;当前脚本仅做身份查询,其他命令按文档单独实现/调用;不得把语义协议误当作固定传输协议 |
| V2 产测 | cmd 1–26,LED、按键、老化、带宽、PCBA、屏幕、MIC、SD、芯片、镜头等 | 文档定义命令语义;需使用匹配固件提供的传输封装 |
| TCP 文件传输 | EPFP,2001/2002/3001/4001,端口 8943 | `scripts/device_upgrade.py` 实现 4001 固件升级;其余命令保留文档语义,不由该脚本执行 |
| TCP 音视频播放 | 端口 8944,cmd 0x01–0x05 | 长连接心跳、解码器列表、播放控制及媒体帧;不是设备发现或升级通道 |
| V2 工厂整合协议 | 工厂扩展命令及设备信息接口 | 按资料版本与设备支持情况使用;与 V1 工厂命令空间不能混用 |
| 局域网搜索 | UDP `4942`,向广播地址 `4942` 发送并在本地 `4942` 接收 | `uint32 cmd + uint32 JSON长度 + UTF-8 JSON` |
| 通用配置获取/查询 | TCP 设备端 `4941` | `uint32 cmd + uint32 payload长度 + payload`;常见无参读取长度为 0;响应为 `uint32 cmd + uint32 JSON/数据长度 + payload` |
| 固件升级 | TCP 设备端 `4941` | `uint32 cmd + uint32 长度 + 32字节ASCII小写MD5十六进制文本 + ROM原始字节`;长度是 MD5 文本与 ROM 字节数之和 |
“覆盖”指协议字段、命令范围、边界和现有脚本能力都在参考文档中可查;不代表每种协议都有通用执行器,也不代表所有固件都启用了每条命令。新增写操作前须逐条查对应协议的请求、响应和副作用。
V1 多字节整数由源码中的 `QDataStream` 默认网络字节序编码(大端)。TCP 是字节流,必须先累积完整 8 字节响应头,再按头内长度读取完整 payload;不能假定一次 `recv` 返回一整帧。JSON 请求/响应的长度不包含 8 字节头。搜索响应也必须校验命令、长度和请求 `session`。
## V1 工厂协议
### V1 搜索
V1 使用独立于 V2 的报文,不带 `EPBP`/`EPTP`/`EPFP` 同步字:
源码:`EpSearchPanocsInLan.cpp`、`json/SerachCameraRequest.cpp`、`json/SerachCameraResponse.cpp`。
```text
uint32 CMD (network byte order)
+ uint32 Data length (network byte order)
+ Data bytes (normally UTF-8 JSON; optional)
请求命令 `0x5a0eff00`,响应命令 `0x5a0eff01`。请求 JSON 至少带随机 `session`:
```json
{"session":12345}
```
| 功能 | 传输 | 端口 | 命令 |
|---|---|---:|---|
| 设备发现请求/响应 | UDP 广播 | 设备 4942 | `0x5A0EFF00` / `0x5A0EFF01` |
| 工厂/产测控制 | TCP | 4941 | 按 V1 文档中各接口的 CMD |
响应常见字段:`session`、`ip`、`dev_type`、`sn`、`mac`、`firmware`、`hardware`、`dev_id`、`dev_ver`,部分设备另有 `ipv6`、`wifi_ssid`、`wifi_quality`。按回显 session 过滤本轮响应。搜索会列出广播域中的多台设备;不得把第一个响应当目标。升级或其他写操作仍要求完整 SN 与型号核验。若设备 SN 为空,只能将搜索结果用于只读信息查询;SN 空值不构成设备身份核验,不能据此绕过写操作的身份保护。
搜索请求 Data 为 `{"session":<随机整数>}`。只接受 `0x5A0EFF01` 且回显本次 session 的响应。设备响应 JSON 保留原始字段;协议版本之间字段可能不同,型号、SN、IP、MAC 等信息必须根据实际响应展示,缺失即标为不可用。多网卡或设备搜索工具已占用 UDP 4942 时,先确定本机接口/端口状态;不结束占用进程。V1 搜索用 `scripts/v1_discover.py`,对单个接口显式指定 `--interface <本机IPv4>`。
### V1 通用配置读取命令
`scripts/v1_command.py` 是通用 TCP 请求器:指定 IP、CMD 和 JSON Data;默认仅显示预检,不建立连接。只有显式 `--execute` 才发送。它校验 TCP 响应头、长度和响应 CMD,但不解释各命令的业务成功字段、不判断写操作安全性,也不执行设备身份核验。因此必须先将发现的设备与完整 SN/型号人工核对;对写配置、复位、格式化、烧号或其他有副作用命令,先核实请求字段及后果并取得本次操作确认。不得用该通用脚本发送 ROM。
以下命令来自 `EapilPanoCHead.h` 的 V1 `MessageCMDType`,对应 `EpPanoCConfigure.cpp` 的 getter/query 实现。大部分请求使用空 payload;按返回命令和 JSON `code` 判定设备是否支持,`code=0` 表示设备成功应答,不代表每个可选字段都存在。
V1 工厂协议文档列出的 66 条命令及字段定义是命令语义来源。传输层客户端可承载这些 CMD,但各命令是否被具体型号/固件实现,仍需用对应版本文档或设备响应确认。V1 示例工程只实现了搜索和前五个 TCP 示例命令,不代表其它 V1 命令已在设备上验证。
| 项目 | 命令 |
|---|---:|
| 获取 SN | `0x5a0e2100` |
| 获取模板 | `0x5a0e2102` |
| 获取基本信息 | `0x5a0e2104` |
| 获取圆心坐标 | `0x5a0e2110` |
| 查询视频参数范围 / 获取视频参数 | `0x5a0e2120` / `0x5a0e2121` |
| 查询音频参数范围 / 获取音频参数 | `0x5a0e2130` / `0x5a0e2131` |
| 查询 ISP 参数范围 / 获取 ISP 参数 | `0x5a0e2140` / `0x5a0e2141` |
| 获取缩略图 | `0x5a0e2150`(二进制 JPEG,不按 JSON 解析)|
| 获取 SD 卡信息 | `0x5a0e21a0` |
| 获取网络信息 | `0x5a0e21b0` |
| 获取 Wi-Fi 信息 | `0x5a0e21c0` |
| 获取时间信息 | `0x5a0e21d0` |
| 获取夜视信息 | `0x5a0e21e0` |
| 获取浪涛兼容 ID | `0x5a0e3100` |
| 获取大拿兼容 ID / danale.conf | `0x5a0e3200` / `0x5a0e3210` |
兼容平台接口可能返回“不支持平台/命令”;要记录为设备能力结果,不要当作传输层故障。`0x5a0e3210` 返回配置内容,可能包含敏感字段;仅在用户任务确需时调用,控制原始结果的保存、展示和转发范围。V1 还定义工厂/扩展类读命令(如 PTZ、MAC、IMEI、老化测试、设备密码等),不属于上述通用配置接口;有的需要特定参数,有的会暴露敏感信息。不要用零参数盲发或把它们当作通用 getter。先从目标型号对应实现核对参数、返回结构和敏感性,再按明确任务范围调用。绝不调用 SET 命令来“探测”支持能力。
### V1 固件升级
V1 升级命令为 `0x5a0e2170`,TCP 端口 `4941`。实现依据 `EpConnection::sendTcpFile`:计算 ROM MD5 并转为 32 字节 ASCII 十六进制文本,帧长度字段等于 `32 + ROM字节数`,随后发送 MD5 文本及 ROM 内容。响应仍按 V1 `cmd + length + payload` 解析,成功 JSON 示例为 `{"code":0,"desc":"update success"}`。这不是 V2 `EPFP/4001` 的状态轮询协议;不得把 V2 的 `status=2` 要求硬套到 V1。V1 成功应答后仍须检查串口重启、网络恢复、重新搜索与目标版本回查;缺项必须明确标为未验证。
执行升级前仍遵守本文“升级前保护”与主技能的用户确认要求。已有工具若只支持 V2,不能改参数伪装成 V1;应使用明确实现 V1 的客户端,并保留 ROM 路径、大小、MD5、SHA-256、目标 IP、型号、升级响应及升级后版本证据。完整 SN 缺失时不得以型号/IP 替代身份核验,也不得执行写操作。
### V1 现场验证样例(C4662)
2026-10-21 对一台 C4662 的实测仅作为该设备/固件的实例,不代表所有 V1 设备字段恒定:V1 搜索和基本信息返回 `dev_ver=2.0.20261021.1`、`firmware=1.0.4`、`dev_type=C4662`,但 SN 为空。常见 getter 中视频、音频、ISP、SD、网络、时间、夜视、缩略图和大拿 ID 接口有成功响应;模板、浪涛兼容接口和 danale.conf 在该设备返回失败或不支持。成功但无数据字段的响应(例如 Wi-Fi 信息)应如实记录,不推测配置值。
## V2 协议矩阵
@@ -74,7 +96,7 @@ V2 发现请求 JSON:
- `outer.type`
- `hardware.type`
非关键网络字段允许缺失。完整 SN 是升级身份核对的首要依据。V1 的端口与帧格式必须从 V1 文档或已验证的 `EpProtocolDemo/V1` 获取,不能套用 V2。
非关键网络字段允许缺失。完整 SN 是升级身份核对的首要依据。V1 的端口与帧格式见上文 V1 章节,并以目标设备对应的 V1 文档或源码复核;不能套用 V2。
执行发现时使用 `scripts/v2_discover.py`,并遵守以下规则:
@@ -137,6 +159,8 @@ uint8 status
- 多个 ROM 或设备候选时等待选择。搜索端口被占用或没有完成完整 SN 核对时不得升级。
- 确认后调用 `scripts/device_upgrade.py --execute`,不绕过其保护参数。
串口登录可以确认现场设备、读取版本并恢复网络,但不能替代升级前的 `30101` 身份响应。即使 COM 口已由用户确认且串口内的 SN、型号看似匹配,`30101` 超时、返回不完整或不匹配时仍不得发送 ROM。先检查设备端端口监听、接口 MAC、关联、DHCP、PC 多网卡选路和二层可达性;恢复后重新运行标准预检。
## 已知协议歧义
- 状态章节没有明确说明每次状态是否带 EPFP 外层头,因此客户端兼容完整帧和裸状态。
+25
View File
@@ -0,0 +1,25 @@
# 简道云固件发布记录
当用户要求预填、填写或核对“研发组 -> 固件发布”记录时使用本流程。以用户指定的固件包目录和当前项目工程为事实来源,不照抄上一次发布记录。用户若只授权预填,填写后核对字段即可;未经明确授权,不点击“提交”或“保存草稿”。
## 确定本次发布资料
1. 从用户提供的固件包路径检查当前版本目录及其现有资料,确认项目、版本、芯片/Sensor 等可以由资料直接核实的信息。不要用历史发布记录代替当前包内资料;有冲突时指出冲突,只询问无法从工程或发布资料查明的事项。
2. 定位对应项目工程和工厂发布目录。版本差异的起点从该工厂目录 `change.log` 中读取最新时间点,不从上一个表单记录或手工猜测日期。
3. 在项目工程目录运行系统环境可调用的 `git_history_by_date.py -d "<change.log 最新时间点>"`。脚本通常从 PATH 提供;不要假定脚本位于工程目录。保留脚本给出的扫描结果、项目目录标题、分组、顺序和提交说明。不得把按仓库目录组织的结果摊平、重排、遗漏扫描到的变更仓库,或用手工挑选记录代替扫描结果。
4. 将脚本原始输出作为“相比上个版本的所有 git 提交记录”的依据。保留仓库目录分组和原有提交记录顺序;可清理明显的显示格式问题,但不得改写提交事实或把不同仓库的记录合并成一个主题列表。无提交的项目不自行补入。
5. 填写 `git-repo版本信息` 等当前版本字段时,以当前工程和版本资料为准,并按该字段说明运行相应工程脚本(例如 `EmxGitInfo`);不要把历史表单中的仓库版本复制成本次版本。
## 归纳“所有影响到的功能项”
1. 检查当前项目对应的功能清单(表单提示的《功能清单》或项目工程内实际使用的清单),结合本次扫描到的提交说明和受影响文件/配置,列出所有有依据的功能范围。不得只参考上一条发布记录已有的影响范围,也不得把其他产品的功能清单套用到当前项目。
2. 把工程术语整理成测试人员可识别的功能名称和可观察行为。每项应能对应到本次提交或配置变化;提交说明只有配置默认值变化时,描述使用该默认值时受影响的行为,不扩大成未经证实的功能改动。产品特有的功能名称只在当前项目证据支持时使用,不写成通用规则。
3. 对配置、依赖、构建文件、发布元数据等非直接业务功能改动,说明它们实际影响的配置加载、运行依赖、版本追溯等范围;若证据不足以确定设备侧功能影响,就说明为“版本/发布记录维护”等有限范围,不能臆造业务影响。
4. 影响范围可按测试理解需要编号,但不能因此改变 Git 扫描记录原有的目录分组和顺序。检查是否覆盖每个相关仓库的功能改动,并排除扫描区间外的旧记录。
5. 对不能从工程、功能清单或提交证据确认的影响保持克制;将推断明确标成待核实,或不写入影响项。若用户要求先预填供审核,可填写有证据的基础范围并指出无法确认的事项,不阻断已能完成的字段。
## 填表与结束
- 仅编辑用户指定的字段;根据当前固件包和工程资料填写,不用历史版本的数值填充未知项。
- 输入多仓库 Git 记录时保留扫描器原始目录分组;注意长字段可能需要确认内容未被截断。
- 预填完成后重新读取表单字段,确认文本内容和换行完整。用户只授权预填时,不点击“提交”或“保存草稿”,并在回复中明确说明记录仍未提交/保存。
+75 -8
View File
@@ -4,22 +4,55 @@
## 串口准备
1. 每次串口任务先请用户确认当前 COM 口;可以枚举 Windows 串口及描述帮助确认,但不要沿用上一次的端口或自行挑选。
1. 新设备调试先取得本次用户确认的 COM 口,可以枚举 Windows 串口及描述帮助确认,但不自行挑选。同一调试任务、设备和参数未变时沿用已确认的端口,不因执行下一条命令或恢复页面而反复询问;更换设备、端口或目标不明确时重新确认,不从其他任务或历史记忆猜测端口。
2. 默认 `115200`、8 数据位、1 停止位、无校验、无流控,允许覆盖。
3. 打开失败、打开后没有输出、乱码或访问拒绝时立即停手,请用户核对 COM 口、波特率/校验/数据位/停止位/流控、端口是否已释放,必要时重新插拔或更换转接器。不要强制结束 SecureCRT、串口工具或其他进程。
4. 只读采集使用 `scripts/serial_monitor.ps1`;需要网页实时显示或网页命令输入时,使用 `scripts/serial_web_console.ps1`。确认 COM 口已打开并开始记录后,才传输 ROM。
3. 页面异常、打开失败、无输出或乱码时,先按下文“异常时的本地只读诊断”定位层次;确认端口打不开、占用或参数可疑后停手,请用户核对 COM 口和参数。不要强制结束 SecureCRT、串口工具或其他进程,不反复重连或自行重启设备。
4. 默认使用 `scripts/serial_web_console.ps1` 打开可见网页,即使只读查看也使用该控制台;需要用户明确选择的终端只读采集时可使用 `scripts/serial_monitor.ps1`。确认 COM 口已打开并开始记录后,才传输 ROM。
5. 串口网页控制台必须由同一个进程独占 COM 口并完成收、发和日志写入,不能再启动第二个采集或发送进程。服务只绑定 `127.0.0.1`,同时写本任务自己的文本日志和原始字节文件。调试信息不脱敏。
6. 不主动读取、复制或上传 SecureCRT 的历史日志。只有本 skill 在本次任务生成的文本和原始字节日志可以默认使用;其他工具日志需用户明确授权。
## 打开与复用
1. 先确认当前任务已有的服务地址、目标 COM 口和日志归档;读取已有服务的 `/api/status`,核对 `port`、`isOpen`、`lastError`,不因为 PowerShell 进程或浏览器标签存在就认定串口可用。启动脚本本身不负责发现与复用旧服务,助手必须先检查再决定是否启动。
2. 服务正常且端口匹配时继续使用同一个页面、服务和日志,不重复运行启动脚本,不另起发送/采集进程。需要显示已有页面时优先展示原标签,不每执行一条命令就新开窗口;服务属于其他任务或端口不匹配时不能直接接管。
3. 确认没有可复用的服务后,检查 `serial_web_console.ps1` 参数说明,以 `powershell.exe -NoProfile -ExecutionPolicy RemoteSigned -File <脚本绝对路径> -Port <已确认COM口> -LogPath <本任务日志绝对路径> -WebPort <本地端口>` 启动。使用 Windows PowerShell 5.1,不使用 `pwsh.exe`;不修改系统执行策略,后台辅助进程隐藏窗口。COM 口、网页端口和日志目录取当前任务配置,不固化本次设备的值。
4. 由助手将服务实际地址打开为可见网页,向用户给出地址和日志路径;已有标签指向该服务时复用原标签。只读检查 `/api/status` 的 `activeWebClients`、`liveWebClients`,再在设备有输出时观察 `receivedBytes`、`lastReceiveUtc` 和日志增长。`activeWebClients` 是已登记页面租约数,`liveWebClients` 是持续连接数,均不能证明用户正在看着窗口。
5. 自动化读取 `/api/status`、`/api/log` 时不附加 `client` 参数,不伪造页面持续连接或额外心跳。页面负责自己的在线登记,后台调试脚本不能阻止最后页面关闭后退出。网页持续连接只用于页面在线判断,不代表日志完全通过该连接推送。
6. 服务正常时不为验证而重启。服务确已退出且用户仍要求继续当前串口任务时,可按已确认参数重新启动并在原标签刷新,明确说明采集中断;不能在用户关闭最后页面后擅自重启或循环重连。重新启动使用新的日志文件,保留旧文本与原始字节文件。服务会在启动时读取 HTML 模板,只有已重启服务后刷新页面才会取得新模板和会话令牌;仅修改磁盘 HTML 后刷新旧服务不能加载更新。
## 实时输入与页面生命周期
只读串口脚本只负责监测。网页控制台允许用户直接输入命令,页面按 Enter 后固定追加 `CR` 并立即发送,不做危险命令二次确认。命令框为空时也发送 `CR`,表现为真实回车。服务接口仍支持无结尾、`CR`、`LF`、`CRLF`,供明确的自动化流程调用。AI 仍只能在用户明确要求或确认具体命令后代为发送,不得自行发送登录名、密码、Shell 命令、break、DTR 或 RTS 脉冲。所有写入数据都在文本日志中记录为 `[TX:来源]`,不可见字符显示为 `<CR>`、`<LF>` 等;RX 文本日志和原始字节日志保持不变。
网页输入区保持在日志下方,只保留快捷填入、命令框和发送按钮,不显示行尾选择、独立空回车、历史下拉、清空、密码开关、U-Boot 连续发送按钮及交互状态栏。页面首次打开时默认定位到最新日志;启用自动滚动后持续跟随最新输出,用户手动向上查看旧日志时不抢回位置,再次勾选自动滚动立即回到底部。Enter 发送、Shift+Enter 输入多行、上下方向键浏览当前页面的隐式历史、Esc 清空输入;处理中文输入法组合状态,确认候选时不能误发串口命令,并阻止长按 Enter 连续发送空回车。发送请求未完成时阻止重复提交,成功后立即刷新 TX 日志并保持输入焦点。页面识别 `Password:` 阶段并自动遮挡输入,而且密码不加入页面命令历史。按用户要求,实际发送内容仍会写入 TX 文本日志。
网页输入区保持在日志下方,只保留快捷填入、命令框和发送按钮,不显示行尾选择、独立空回车、历史下拉、清空、密码开关、U-Boot 连续发送按钮及交互状态栏。页面首次打开时默认定位到最新日志;启用自动滚动后持续跟随最新输出,用户手动向上查看旧日志时不抢回位置,无日志选区时再次勾选自动滚动立即回到底部。Enter 发送、Shift+Enter 输入多行、上下方向键浏览当前页面的隐式历史、Esc 清空输入;处理中文输入法组合状态,确认候选时不能误发串口命令,并阻止长按 Enter 连续发送空回车。发送请求未完成时阻止重复提交,成功后在选区保护允许时刷新 TX 日志并保持输入焦点。页面识别 `Password:` 阶段并自动遮挡输入,而且密码不加入页面命令历史。按用户要求,实际发送内容仍会写入 TX 文本日志。
每个网页标签维护独立客户端心跳。最后一个页面正常发送关闭通知后等待约 `2` 秒,若没有刷新后的新页面接管,则服务自动结束日志采集、写入结束标记并释放 COM 口;多个标签同时打开时,关闭其中一个不能停止其他页面。页面异常退出或内置浏览器不触发离页通知时,心跳超过 `3` 秒后清理失联页面,再进入 `2` 秒宽限期,因此最后页面关闭后最迟约 `5` 秒退出。此规则同样适用于升级期间:需要全程监测时必须保持至少一个页面打开。服务启动后尚未打开过网页时不要自动退出。
### 日志文本选择与复制
- 日志区允许浏览器原生拖选、双击选择和 `Ctrl+C` 复制,不拦截复制快捷键,也不因复制触发串口发送。
- 拖选从鼠标按下开始保护,即使此时选区仍为空;拖选结束后,只要非空选区与日志区相交,就不替换日志文本节点或执行自动滚动。选择其他区域不应暂停日志。鼠标释放、取消或窗口失焦时清除拖选状态,但仍保留非空选区的保护。
- 定时读取不能无条件重建整段正文:内容相同不改 DOM,存在选区时延后绘制。网络响应返回后、延迟布局帧执行前均重新检查选区,读取失败提示也不能覆盖选中的正文。否则用户在等待请求或布局期间开始选择,仍会被下一次更新打断。
- 选择期间只暂停日志区域绘制与自动滚动,状态读取、串口采集、文本/原始字节落盘及页面存活连接继续。取消选择后,下次刷新展示最新数据,并按原自动滚动与手动查看位置规则处理,不用关闭串口来冻结页面。
### 页面存活与关闭
每个网页标签维护独立的 EventSource 持续连接,服务端每秒写入一次探测;页面进入后台、定时轮询被节流时,不因缺少轮询而误停串口。最后一个页面正常发送关闭通知后等待约 `2` 秒,若没有刷新后的新页面接管,则服务自动结束日志采集、写入结束标记并释放 COM 口;多个标签同时打开时,关闭其中一个不能停止其他页面。页面异常退出或内置浏览器不触发离页通知时,由持续连接的写失败清理该页面,再进入 `2` 秒宽限期,实测验收仍要求最后页面关闭后约 `5` 秒内退出。不支持 EventSource 的页面退回原有 `3` 秒轮询心跳超时,日志必须明确写为心跳超时,不能直接断言用户关闭了页面。此规则同样适用于升级期间:需要全程监测时必须保持至少一个页面打开。服务启动后尚未打开过网页时不要自动退出。
关闭后的文本日志和原始字节文件保留在原路径,不自动移动、删除或截断。服务退出后原网址不可用,不部署常驻管理服务,也不在再次访问时自动打开串口;需要继续查看时重新运行启动脚本。关闭通知只接受回环地址请求,并校验本次随机会话令牌。
用户只要求实时显示串口时,到此为止:打开终端面板并持续监测,不附带设备搜索、协议登录、文件上传或升级。
日志和状态读取设置 `2500ms` 超时,包含读取响应体的等待;超时后页面可继续下一次刷新。这不是串口发送请求的统一超时,发送结果未知时不得直接重发命令。
用户只要求实时显示串口时,到此为止:保持同一可见网页只读采集,不附带设备搜索、协议登录、文件上传或升级;不为证明可写而发送空回车或其他探测数据。
## 异常时的本地只读诊断
先检查以下已有证据,不向设备发送登录名、密码、Shell 命令、空回车、break 或 DTR/RTS 脉冲:
- 服务层:检查状态接口是否可达、端口是否匹配且 `isOpen=true`、`lastError`、启动输出和本任务日志末尾的退出原因。接口不可达不能单独证明 COM 口故障;先区分服务未启动、已退出、监听端口冲突和启动命令错误。依据明确错误定位,不靠提升权限或重复执行碰运气。
- 页面层:状态可达而页面异常时,检查 `activeWebClients`、`liveWebClients` 与实际服务版本;不要仅凭轮询超时声称用户关闭了页面。新版页面支持持续连接时应登记对应连接;旧模板或旧令牌需要刷新现有标签,不能通过后台伪造页面保活来补救。助手无法直接操作页面时,仅请用户完成必要的一次刷新并说明原因,不要求其重新执行设备命令。
- 数据层:比较两个时点的 `receivedBytes`、`lastReceiveUtc`、文本和原始字节日志大小。设备静默且无错误时报告“端口已打开,尚未收到新数据”,不能断言故障或宣称收发均正常;数据增长而页面不更新时优先定位显示/请求层。
- 端口层:已有错误明确指向端口不存在、拒绝访问、占用或数据乱码且参数可疑时,停止打开/发送重试,向用户给出具体证据,请其核对 COM 口、波特率、校验、数据位、停止位、流控、占用工具及连接。需要重新插拔、关闭用户工具或更换转接器时由用户处理,不能强制结束其他进程。
保持问题发生时的日志,不为排查移动或截断原始证据。主动离页、持续连接断开和轮询超时是不同事件;只有时间与状态证据支持时才归因。恢复前不自动切换 Telnet、重启设备或重置串口硬件。
## U-Boot 与 A/B 分区手工操作
@@ -30,12 +63,36 @@
## Telnet 与交互命令
1. 先让用户选择串口或 Telnet。串口需要本次确认的 COM 口;Telnet 需要设备完整 SN 和型号,然后广播发现并精确核对 IP,不能沿用历史 IP。
1. 新设备调试且连接方式尚未明确时,让用户选择串口或 Telnet;已明确的选择不反复询问。串口需要本任务已确认的 COM 口;Telnet 需要设备完整 SN 和型号,然后广播发现并精确核对 IP,不能沿用历史 IP。
2. Telnet 登录名和密码从当前 Linux 工程的准确配置读取,优先检查 `product.json` 中的用户配置。不要从截图 OCR、相似机型、旧固件或历史记忆猜测,也不要把凭据写入 skill。
3. 当前配置认证失败或设备版本与配置不一致时再调查历史固件配置。限制失败登录次数;首次明确失败后先停手核实,不连续试猜密码。
4. 串口与 Telnet 是否共用密码必须由工程配置或用户确认,不能推断。
5. 用户明确要求 `ifconfig` 等命令时,若已有已验证且仍连接的会话,就只发送该命令并实时展示结果;登录验证只执行最少的只读命令,完成后退出。
## 网卡未启动的分层诊断
不要看到“没有 IP”就直接归因于 Wi-Fi 密码、DHCP 或硬件。按证据层级定位,前一层成立后再进入下一层:
1. **总线与硬件**:用 `lsusb`、sysfs 和 `dmesg` 确认设备枚举、VID/PID、接口和断连记录。USB 已枚举只能证明总线可见,不能证明驱动已绑定。
2. **驱动兼容性**:确认目标 ROM 中存在对应 `.ko`,核对模块名、`vermagic`、依赖和 USB alias。手动 `insmod` 后观察是否创建 `phy`、`rfkill` 和 `wlan0`;加载失败时保留完整内核错误。
3. **链路与射频**:执行 `ifconfig wlan0 up` 或等价命令,并用扫描结果区分“驱动可用但未关联”和“射频/硬件不可用”。能扫描到 AP 是驱动、设备绑定和基本射频链路成立的证据,不等于网络已连通。
4. **开机加载链**:从当前设备的 `appinit.sh`、模块加载脚本和工程打包映射反向追踪权威源文件、生成文件与 ROM 内最终文件。不能只修改生成目录;重新打包后要从 ROM 提取或挂载验证最终 `loadko` 内容、加载顺序和驱动哈希。
5. **关联与地址**:分别检查 wpa_supplicant、关联状态、DHCP 客户端、IPv4、默认路由和 DNS。不要把 DHCP 失败与驱动未加载混为一个故障。
6. **应用服务**:确认依赖网络设备的服务是否在网卡出现后自动启动或重试,并检查设备端 `8942/8943` 等任务相关端口是否监听。端口监听与 PC 可达是两项不同证据。
手动加载驱动、创建 `wlan0`、关联 AP 或取得临时 IP,只能作为诊断证据或为受控升级创造条件,不能判定开机问题已经修复。最终验收必须使用包含修复的新固件重启,并证明驱动、网卡、关联、DHCP、路由和目标服务无需人工干预即可恢复。
设备端已有 IP 且目标端口正在监听,但 Windows 无法建立 ARP 或 TCP 时,继续检查 PC 侧:
- 是否有多个物理或虚拟接口占用同一网段,实际选路是否使用预期源地址;
- 相关网卡是否真实连接,旧的 DHCP 地址是否已进入 `Deprecated` 状态;
- WLAN 软件无线电是否关闭、目标配置文件是否存在、AP 是否隔离有线与无线客户端;
- 必要时显式绑定源地址做只读连接测试,以区分错误选路和设备拒绝;不要未经授权修改默认路由或提升权限。
如果打开 WLAN、添加路由或改变接口状态需要管理员权限或用户交互,停止自动操作并请用户完成最小动作。不要通过不受控的键盘注入或高风险系统修改绕过权限。
产品配置 MAC、协议返回 MAC 与无线模块原始 MAC 可能不同。恢复网络前先比较三者;只有当前产品配置和设备身份均已确认,且网络准入、DHCP 租约或设备服务确实依赖产品 MAC 时,才在关联和 DHCP 之前临时恢复产品 MAC。不得把任何实测 MAC、SSID 或 PSK 写入 skill。
## 成功判据
完整成功需要组合证据:
@@ -67,6 +124,8 @@
日志中的 `error`、`failed`、`timeout` 字样不是自动失败判据。结合发生时间、是否重复、协议终态、设备功能、重启次数以及是否出现 panic、segfault、core dump 或看门狗循环判断。升级停止和启动阶段的一次性模块告警可以记录为警告;若同一 SN 已正常重启、网络恢复、版本正确并持续心跳,不应仅凭孤立字样推翻成功结论。
本地网卡、DHCP、路由、DNS、协议端口和 `30101` 都正常时,可以把“本地网络与升级闭环”判为通过。云平台激活、Token、绑定、网关发现或业务鉴权错误要单列为云业务警告或失败项;不能用它们推翻已取得的本地网络证据,也不能把本地网络通过扩张为整机云业务全部通过。
## 日志快照与远端协查
持续监测期间不要为了上传而关闭串口。复制本任务生成的活动文本日志和原始字节文件形成稳定快照,记录时间范围并计算 SHA-256,再上传到约定的远端临时目录,例如 `/tmp/<项目>-windows-logs/<时间戳>`。
@@ -89,12 +148,20 @@
更新串口服务或页面后至少完成以下检查:
此处指服务或页面实现变更;仅修改文档时校验技能结构、相对链接和规则一致性,不启动串口生命周期测试,不关闭或重启用户正在使用的控制台。实际设备发送、关闭最后页面等会影响调试的验收,需在用户授权范围内安排;未执行则列为待验收。
1. 使用 `serial_web_console.ps1 -ValidateOnly` 验证 C# 服务能够编译且网页资源存在,再运行 Skill 的 `quick_validate.py`。
2. 启动前确认目标 COM 口没有被第二个串口工具占用;启动后核对状态接口报告端口已打开,不能只根据 PowerShell 进程存在作结论。
3. 设备有输出时核对接收字节数和文本日志文件大小确实增长;设备静默时明确报告“尚未收到数据”,不能把空白页面说成实时采集正常。
4. 发送普通文本后,核对设备响应及对应 `[TX:命令]`;命令框为空时发送 Enter,日志必须出现 `[TX:命令] <CR>`。
5. 首次打开或刷新页面时应显示最新日志;勾选自动滚动后立即回到底部并持续跟随,用户向上查看历史时页面不能强制抢回滚动位置。
5. 首次打开或刷新页面时应显示最新日志;无日志选区时勾选自动滚动立即回到底部并持续跟随,用户向上查看历史时页面不能强制抢回滚动位置。有选区时以选区保护优先。
6. 核对 Enter 发送、Shift+Enter 换行、上下键隐式历史、Esc 清空、输入法候选确认不误发、长按 Enter 不连续空发,以及请求进行中不重复提交。
7. 出现 `Password:` 后输入框应自动遮挡,密码不加入页面历史;按当前调试策略,TX 文本日志仍保存实际发送内容。
8. 打开两个页面时关闭其中一个,服务应继续运行;关闭最后一个页面后,正常离页约 `2` 秒、未触发离页事件时最迟约 `5` 秒,状态接口应离线、宿主进程应退出,日志应写入结束标记且 COM 口应释放。刷新页面不能误停服务。
9. 自动停止后核对文本日志和原始字节文件仍位于原路径且未被截断;再次启动服务并确认能够重新打开同一 COM 口。升级期间关闭最后页面也按相同规则停止,不能宣称仍在后台监测。
10. 单独测试页面持续连接:不发送轮询请求至少 `10` 秒,串口仍应连接并持续接收;断开连接但不发送离页通知,仍应在约 `5` 秒内退出。同一客户端新连接接管后关闭旧连接不能误删新连接。请求缺少会话令牌时不能登记持续连接。自动化协议测试不能代替真实页面的后台/刷新可见性验收,无法实测的项需明确报告。
11. 在真实浏览器拖选或双击选中日志,跨越多轮刷新后确认选区和滚动位置保持;按 `Ctrl+C` 并核对复制内容与选区一致。同时确认后台接收字节数、文本及原始字节文件仍增长;取消选择后页面恢复更新。替身单测覆盖无变化不重建节点、拖选尚无选区、响应/布局帧竞态、错误分支保护及恢复绘制,但不能替代真实选择和剪贴板验收。此项不需要发送任何设备命令。
验收记录分别列出代码/编译检查、DOM/网络替身单测、真实串口 HTTP 生命周期测试和实际浏览器交互。某一层通过不代表其余层通过,不把持续连接数当作窗口可见性证明,也不把未发设备数据的生命周期测试当作普通命令与空回车 TX 验收。
维护时可运行 `node scripts/test_serial_console_page.cjs` 检查页面逻辑(DOM/网络替身,不是真实浏览器验收)。`python scripts/test_serial_web_console.py --execute --port <本次确认的COM口> --log-dir <新的测试日志目录>` 会在独立本机端口真实打开串口并测试生命周期,默认不发送任何设备数据;先停止本技能原控制台,其他工具占用时按串口准备规则停手,不能强制关闭。该测试会多次正常退出并重新打开自己的控制台,结束后释放串口,不维持生产页面保活。生产服务重新启动后需刷新现有页面加载新模板及新会话令牌。