feat: add embedded app PC debugging skill

This commit is contained in:
zoukai committed 2026-09-11 17:17:09 +08:00
commit 23e3a4910a
12 files changed
+2818

No files matched your search

+64
View File
@@ -0,0 +1,64 @@
# 远程打包与产物归档
仅在任务涉及编译新固件或下载远程产物时读取本文件。
## 默认值与覆盖
| 项目 | 默认值 |
|---|---|
| SSH Host | `emb.eapil.com` |
| 工程根目录 | `/CamTells` |
| Public 来源 | `~/work/develop/gitcode/EMX2.1` |
| 本地归档根目录 | `F:\tmp\embedded-app-pc-debug` |
用户提供的值优先。凭据只使用现有 SSH 配置、密钥代理或交互式认证,不把密码、私钥和 Token 保存到 skill 或任务日志。
## 工程定位
1. 先用现有 SSH/VS Code 配置解析 Host,不猜测用户名、端口或私钥路径。
2. 将用户给出的项目名视为 `/CamTells` 下的相对路径并精确匹配。
3. 如果有多个候选,列出远程绝对路径等待选择;不要凭目录修改时间挑选。
4. 确认工程目录包含待用脚本,再确定真实命令行参数。
## 构建顺序
1. 在当前工程目录执行 `EmxGitInfo`,将标准输出、标准错误和退出码保存为 `logs/EmxGitInfo.txt`。不先运行 Git 工作区检查。
2. 查看 `scripts/product.py`、`release.py` 的帮助、源码入口或项目说明,确认参数和要求的工作目录。不同工程的参数及启动目录可能不同,不能照搬其他项目命令;脚本位于 `scripts` 不代表应从工程根目录启动,也不代表一定应从 `scripts` 启动。
3. 只有实际缺少 `Public`、第三方库映射或脚本明确报资源缺失时,才检查并运行 `softLink.py`。创建前核对目标与默认来源 `~/work/develop/gitcode/EMX2.1`,避免覆盖已有有效链接。
4. 先运行 `product.py` 构建环境包,成功后运行 `release.py` 编译项目。
5. 每一步记录:工作目录、完整命令、开始/结束时间、退出码和关键输出。
6. 尊重构建脚本内部的校验与重建循环。脚本因随机命中、签名或封装检查而自动重建时,让脚本自行完成;不要在外层重复启动、重复改版本或把一次内部重建误报为多个发布版本。
7. 构建失败时不下载旧产物。若本次 ROM 已由脚本明确生成、校验通过,而随后仅全量烧录镜像或其他辅助目标失败,应分开报告:允许交付已验证 ROM 用于局域网升级,但完整发布包仍判为失败或不完整。
## 打包任务交付清单
Linux 打包任务应一次性交付以下事实,供 Windows 设备任务直接使用:
- 工程绝对路径、实际运行目录和构建命令;
- ROM 与 `devInfo.json` 的远程绝对路径;
- ROM 大小、MD5、SHA-256、目标内外层版本;
- 构建记录、警告以及哪些发布目标成功或失败;
- 产物是否已下载或排队到 Windows 任务。
Windows 任务已取得内容完整且自洽的交付清单后,不重复 SSH 到 Linux 重新计算同一组构建事实。只有交付缺字段、相互矛盾、文件校验不一致或用户明确要求复核时,才回到远端检查。
## 下载与归档
创建:
```text
F:\tmp\embedded-app-pc-debug\<项目名>\<YYYYMMDD-HHmmss>\
├─ firmware\
└─ logs\
```
下载前解析远程 ROM 的真实绝对路径。下载后核对交付清单中的远端大小与本地大小,并计算本地 SHA-256;已有远端 SHA-256 时必须比较。多个 ROM 候选时列出文件名、大小、时间和可解析版本;只有唯一候选才可自动选择。
建议日志:
- `build.log`
- `EmxGitInfo.txt`
- `download.log`
- `firmware.sha256`
不要自动提交、推送、清理或还原远程仓库。
+38
View File
@@ -0,0 +1,38 @@
# Linux 打包任务与 Windows 设备任务协作
仅在固件由 Linux 任务构建、由 Windows 任务下载并升级设备时读取本文件。
## 职责边界
- Linux 任务负责工程定位、构建、产物验证、版本与哈希、构建日志和警告。
- Windows 任务负责接收产物、本地完整性比较、广播发现、完整 SN/型号核对、串口监测、EPFP 升级和升级后验证。
- 已由上游任务验证并完整交付的事实,下游不重复计算。发现字段缺失、矛盾、哈希不一致或用户要求复核时再回到上游。
## 建议交接流程
1. Windows 任务通过可用的 Codex 任务工具联系或等待 Linux 任务;等待超时只表示尚未得到新状态,不要重复发送同一请求。
2. Linux 任务完成后用短消息交付路径、大小、哈希、版本和结论;ROM、`devInfo.json` 与大日志使用 SCP 或共享文件传递。
3. Windows 任务比较本地文件与交付清单,然后开始设备侧预检。校验一致时不再登录 Linux 重算哈希或重跑构建命令。
4. 升级出现异常时,Windows 任务上传本次 skill 生成的串口日志快照,并把精确时间线与诊断问题发回 Linux 任务。
5. Linux 任务回复源码/构建侧分析;Windows 任务负责将分析与设备现场证据合并成最终验证报告。
## 工具与降级原则
- 优先使用任务列表、读取、消息和等待能力;不同主机或版本的 Codex 工具能力可能不同,先确认工具实际返回结果。
- 不得把“文件页已打开/已排队”说成“消息已送达”,也不得在读取结果为空时编造对方结论。
- 读取不到任务正文时,先核对任务 ID 和主机 ID,再查看最新任务状态。只有任务工具确实不能返回内容时,才在已授权主机上读取对应会话记录或请用户转交摘要。
- 任务 ID、主机 ID、项目路径和远端临时目录都属于本次运行参数,不写成通用固定值。
## 最小交接消息
```text
项目:<绝对路径>
ROM:<绝对路径>
devInfo:<绝对路径>
大小:<bytes>
MD5:<md5>
SHA-256:<sha256>
目标版本:inner=<值>,outer=<值>
构建结论:<ROM成功/完整发布成功/仅ROM可用/失败>
警告:<无或摘要>
```
+108
View File
@@ -0,0 +1,108 @@
# 设备发现、基础信息与升级协议
仅在任务涉及设备网络发现、版本查询或 ROM 传输时读取本文件。优先使用用户提供的最新协议、现有已验证实现和抓包;文档歧义不得伪装成确定事实。
## 本机参考资料
存在时优先核对:
- `C:\Users\ZK\Documents\ChatGPT\日常开发\调试资料\设备端协议V2-工厂整合版本.md`
- `C:\Users\ZK\Documents\ChatGPT\日常开发\调试资料\设备端统一配置协议V2.md`
- `C:\Users\ZK\Downloads\设备端TCP文件传输类协议.md`
- `C:\Users\ZK\Downloads\工厂协议V1.md`
- `E:\CodeSpace\git-pro\eapil_qt_player_v2\EpProtocolDemo`
## V2 协议矩阵
| 功能 | 传输与端口 | 帧格式 |
|---|---|---|
| 设备发现请求 | UDP,客户端从本地 `8951` 向设备 `8941` 广播 | `EPBP + uint32长度 + UTF-8 JSON` |
| 设备发现响应 | UDP,客户端 `8951` 接收 | 同上,完整帧在一个数据报内 |
| 统一配置 | TCP,设备 `8942` | `EPTP + uint32长度 + UTF-8 JSON` |
| 固件升级 | TCP,设备 `8943` | `EPFP + uint32命令 + uint32长度 + 二进制数据` |
多字节整数使用网络字节序。配置 TCP 长度端序在整合文档中没有单独声明,但现有设备和客户端验证采用网络序。
## 发现与身份
V2 发现请求 JSON:
```json
{"cmd":60000,"session":12345}
```
响应必须回显相同 `cmd/session`。身份字段包括 `sn`、顶层烧录 `mac`、`inner`、`outer`、`hardware` 和 `net`。顶层 `mac` 与 `net.mac` 可能不同。型号判断同时展示:
- `inner.type`
- `outer.type`
- `hardware.type`
非关键网络字段允许缺失。完整 SN 是升级身份核对的首要依据。V1 的端口与帧格式必须从 V1 文档或已验证的 `EpProtocolDemo/V1` 获取,不能套用 V2。
执行发现时使用 `scripts/v2_discover.py`,并遵守以下规则:
1. 默认枚举已启用、已连接且具有有效 IPv4 的物理网卡;回环、断开、APIPA、VPN、VMware、Npcap 等接口要列出并注明排除原因。用户明确要求所有活动接口时才加入虚拟接口。
2. 每个接口分别绑定其本地 IPv4 和客户端端口 `8951`,同时发送有限广播 `255.255.255.255` 和按前缀计算的定向广播。不能把 `/22` 的广播地址按 `/24` 猜测。
3. 如果 UDP `8951` 被 EapilCameraConfigurer 或其他进程占用,报告占用者,不结束进程;请用户释放端口,或使用已有工具明确支持的搜索结果。
4. 从临时源端口发包只可作为诊断。设备可能只向 `8951` 回复,因此临时端口无响应不能证明设备离线。
5. 打印所有合法候选并按完整 SN 精确匹配;不得选择第一台。响应需校验 `EPBP`、长度、`cmd/session`。只有 SN、源 IP、MAC 和型号都一致的重复响应可以合并;同一 SN 对应不同身份信息时报告冲突并禁止自动选择。
6. 未提供完整 `--expected-sn` 时脚本只是列表模式,即使退出码为 0 也不代表身份核验成功。Telnet、升级及其他设备写操作必须提供完整 SN,并根据任务要求同时传入型号。
## 基础信息
通过 TCP `8942` 发送 `cmd=30101`。响应必须满足:同步头正确、长度合理、`cmd/session` 匹配且 `code=0`。读取:
- `sn`、`mac`
- `inner.type/version`
- `outer.type/version`
- `hardware.type/version`
`hardware.version` 不是固件版本。升级后应根据 ROM 类型比较 `inner.version` 或 `outer.version`。如果无法从 ROM 或构建记录确定应变化的字段,必须明确说明并让用户确认预期。
`30102` 可能返回密码和密钥,只在调试任务确实需要时调用。用户选择保留原始调试数据,因此响应可原样写入本次任务日志,但不得写入 skill 本体。
## 固件升级 4001
请求:
```text
EPFP
+ uint32 4001
+ uint32 ROM字节数
+ ROM原始字节
```
ROM 前没有 MD5 或目标路径业务前缀。不要把普通文件写入 `2001` 的 MD5 机制声称为升级 `4001` 自带校验。
状态业务数据为 21 字节:
```text
uint8 status
+ uint32 sessionId
+ uint32 downloadTotal
+ uint32 downloaded
+ uint32 flashTotal
+ uint32 flashed
```
状态:`0` 空闲、`1` 开始、`2` 完成、`3` 失败。`sessionId` 不等同于配置 JSON session,不要求匹配。解析器要兼容完整 `EPFP/cmd/length` 状态帧与设备实测出现的裸 21 字节状态,但完整帧必须校验响应命令为 `4001`。
只有 `status=2` 是协议成功终态;下载或 Flash 计数达到总量不能替代它。`status=3` 立即失败。连续 60 秒没有下载或 Flash 进度变化视为停滞,值允许覆盖。没有依据时不自动续传或重试。
设备报告的 `downloadTotal`、`flashTotal` 可能与 ROM 文件字节数不同,不能因为这种封装头、元数据或分区差异单独判失败。`status=2` 是协议成功终态;如果此时 `downloaded/flashed` 仍小于设备各自报告的非零总量,记录协议计数异常警告并纳入验证报告,但不自行推翻设备的成功终态。
## 升级前保护
- ROM 必须是普通文件,大小大于 0 且不超过无符号 32 位长度。
- 计算并记录 SHA-256;协议本身没有 ROM 签名或来源认证,不能声称 SHA-256 提供设备侧认证。
- 精确核对设备 SN。
- 同时展示当前型号和 ROM 目标型号。ROM 元数据无法解析时显示“无法验证型号”,并重新取得用户确认。
- 多个 ROM 或设备候选时等待选择。搜索端口被占用或没有完成完整 SN 核对时不得升级。
- 确认后调用 `scripts/device_upgrade.py --execute`,不绕过其保护参数。
## 已知协议歧义
- 状态章节没有明确说明每次状态是否带 EPFP 外层头,因此客户端兼容完整帧和裸状态。
- 没有规定分块大小、连接关闭方、断线恢复或统一总超时;使用可配置值并保存最后进度。
- 没有定义 ROM 与型号的自动匹配机制。
- TCP 是字节流,必须累积并按长度解析,不能把单次 `recv` 当作完整帧。
+100
View File
@@ -0,0 +1,100 @@
# 串口监测、验证与故障诊断
仅在任务涉及串口、设备重启或升级结果判断时读取本文件。
## 串口准备
1. 每次串口任务先请用户确认当前 COM 口;可以枚举 Windows 串口及描述帮助确认,但不要沿用上一次的端口或自行挑选。
2. 默认 `115200`、8 数据位、1 停止位、无校验、无流控,允许覆盖。
3. 打开失败、打开后没有输出、乱码或访问拒绝时立即停手,请用户核对 COM 口、波特率/校验/数据位/停止位/流控、端口是否已释放,必要时重新插拔或更换转接器。不要强制结束 SecureCRT、串口工具或其他进程。
4. 只读采集使用 `scripts/serial_monitor.ps1`;需要网页实时显示或网页命令输入时,使用 `scripts/serial_web_console.ps1`。确认 COM 口已打开并开始记录后,才传输 ROM。
5. 串口网页控制台必须由同一个进程独占 COM 口并完成收、发和日志写入,不能再启动第二个采集或发送进程。服务只绑定 `127.0.0.1`,同时写本任务自己的文本日志和原始字节文件。调试信息不脱敏。
6. 不主动读取、复制或上传 SecureCRT 的历史日志。只有本 skill 在本次任务生成的文本和原始字节日志可以默认使用;其他工具日志需用户明确授权。
只读串口脚本只负责监测。网页控制台允许用户直接输入命令,页面按 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 文本日志。
每个网页标签维护独立客户端心跳。最后一个页面正常发送关闭通知后等待约 `2` 秒,若没有刷新后的新页面接管,则服务自动结束日志采集、写入结束标记并释放 COM 口;多个标签同时打开时,关闭其中一个不能停止其他页面。页面异常退出或内置浏览器不触发离页通知时,心跳超过 `3` 秒后清理失联页面,再进入 `2` 秒宽限期,因此最后页面关闭后最迟约 `5` 秒退出。此规则同样适用于升级期间:需要全程监测时必须保持至少一个页面打开。服务启动后尚未打开过网页时不要自动退出。
关闭后的文本日志和原始字节文件保留在原路径,不自动移动、删除或截断。服务退出后原网址不可用,不部署常驻管理服务,也不在再次访问时自动打开串口;需要继续查看时重新运行启动脚本。关闭通知只接受回环地址请求,并校验本次随机会话令牌。
用户只要求实时显示串口时,到此为止:打开终端面板并持续监测,不附带设备搜索、协议登录、文件上传或升级。
## U-Boot 与 A/B 分区手工操作
1. 串口网页控制台不提供 U-Boot 持续按键、定时发送、提示符自动识别停止或一键切换 A/B 分区;不要通过隐藏接口或后台线程补回这些行为。
2. 需要在启动阶段输入 `eapil_uboot_key_str` 时,由用户在普通命令框中自行输入和发送;设备无法由电脑控制重启时,可以在控制台已经连接后请用户手动重启。
3. 进入 U-Boot 后仍由用户按需填入并主动发送命令。常见核对顺序为:`printenv systemSelect`、`setenv systemSelect A` 或 `setenv systemSelect B`、`saveenv`、再次 `printenv systemSelect`、`reset`。快捷按钮只能填入文本,不能自动发送或串联执行。
4. 分区恢复成功需要看到内核命令行中的 `systemSelect=...`、系统明确报告运行于目标 A/B 分区、核心应用恢复,并且没有 panic、看门狗或循环重启。网络恢复属于后续独立诊断,不作为这一步成功的必要条件。
## Telnet 与交互命令
1. 先让用户选择串口或 Telnet。串口需要本次确认的 COM 口;Telnet 需要设备完整 SN 和型号,然后广播发现并精确核对 IP,不能沿用历史 IP。
2. Telnet 登录名和密码从当前 Linux 工程的准确配置读取,优先检查 `product.json` 中的用户配置。不要从截图 OCR、相似机型、旧固件或历史记忆猜测,也不要把凭据写入 skill。
3. 当前配置认证失败或设备版本与配置不一致时再调查历史固件配置。限制失败登录次数;首次明确失败后先停手核实,不连续试猜密码。
4. 串口与 Telnet 是否共用密码必须由工程配置或用户确认,不能推断。
5. 用户明确要求 `ifconfig` 等命令时,若已有已验证且仍连接的会话,就只发送该命令并实时展示结果;登录验证只执行最少的只读命令,完成后退出。
## 成功判据
完整成功需要组合证据:
1. EPFP 返回明确 `status=2`。
2. 串口出现正常校验、烧录、启动过程,没有明确失败终态;如果存在设备已知成功标记,例如 `update successful`,记录其时间。
3. 设备完成重启。
4. 广播重新发现同一个完整 SN。
5. 网络恢复,目标 IP 可达;IP 变化时以同一 SN 为准更新目标。
6. `30101` 查询成功。
7. 应变化的 `inner.version` 或 `outer.version` 与目标构建一致。
缺少任一证据时不要补造“全部成功”。可以报告“协议升级完成,但尚未验证版本”或“设备已重启,但未收到协议终态”等部分结论。
## 失败分类
| 阶段 | 典型证据 | 后续检查 |
|---|---|---|
| 串口准备 | 端口不存在、拒绝访问、被占用 | 核对 COM 口和占用程序 |
| 设备发现 | 无响应、候选冲突 | 网卡、V1/V2、广播出口、防火墙、二层网络 |
| 身份预检 | SN 或型号不匹配 | 停止,不传 ROM,重新选择目标/固件 |
| TCP 连接 | 8942/8943 拒绝或超时 | IP、服务状态、设备网络、端口监听 |
| ROM 发送 | 连接断开、发送异常 | 最后发送量、串口错误、设备重启时点 |
| 下载阶段 | downloaded 不增长 | 网络、设备缓存、服务负载 |
| Flash 阶段 | flashed 不增长、status=3 | ROM 兼容性、分区、校验、Flash 错误 |
| 重启阶段 | 协议完成但串口无启动 | 启动加载器、内核、供电、看门狗 |
| 网络恢复 | 串口正常但未重发现 | DHCP/Wi-Fi、网线、IP 变化、服务启动 |
| 版本回查 | 设备在线但版本未变 | 比较字段选错、升级分区未切换、回滚 |
日志中的 `error`、`failed`、`timeout` 字样不是自动失败判据。结合发生时间、是否重复、协议终态、设备功能、重启次数以及是否出现 panic、segfault、core dump 或看门狗循环判断。升级停止和启动阶段的一次性模块告警可以记录为警告;若同一 SN 已正常重启、网络恢复、版本正确并持续心跳,不应仅凭孤立字样推翻成功结论。
## 日志快照与远端协查
持续监测期间不要为了上传而关闭串口。复制本任务生成的活动文本日志和原始字节文件形成稳定快照,记录时间范围并计算 SHA-256,再上传到约定的远端临时目录,例如 `/tmp/<项目>-windows-logs/<时间戳>`。
请求 Linux 任务协查时附带:完整 SN、型号、IP、COM/波特率、升级前后版本、问题时间窗口、症状和复现步骤、远端日志路径及 SHA-256、希望对方回答的问题。不要在任务消息里粘贴整份大日志。
## 超时和重试
- 有进度就继续等待,连续 60 秒无下载或烧写变化才判定疑似停滞。
- `status=3` 立即失败。
- TCP 断开但未收到 `status=2` 时不能直接成功;结合串口和重启证据报告“协议终态缺失”。
- 保存最后状态、进度、串口末尾片段和错误时间线。
- 不自动再次刷机。分析后重新展示预检信息,并等待新的明确确认。
## 验证报告
`verification.txt` 按以下顺序记录:项目与 ROM、目标设备身份、升级前后版本、协议结果、串口关键事件、网络与身份复查、未完成检查、最终结论。包含 SHA-256、升级前后 IP 和日志路径,不用把全部串口内容复制进摘要。
## 串口网页控制台变更验收
更新串口服务或页面后至少完成以下检查:
1. 使用 `serial_web_console.ps1 -ValidateOnly` 验证 C# 服务能够编译且网页资源存在,再运行 Skill 的 `quick_validate.py`。
2. 启动前确认目标 COM 口没有被第二个串口工具占用;启动后核对状态接口报告端口已打开,不能只根据 PowerShell 进程存在作结论。
3. 设备有输出时核对接收字节数和文本日志文件大小确实增长;设备静默时明确报告“尚未收到数据”,不能把空白页面说成实时采集正常。
4. 发送普通文本后,核对设备响应及对应 `[TX:命令]`;命令框为空时发送 Enter,日志必须出现 `[TX:命令] <CR>`。
5. 首次打开或刷新页面时应显示最新日志;勾选自动滚动后立即回到底部并持续跟随,用户向上查看历史时页面不能强制抢回滚动位置。
6. 核对 Enter 发送、Shift+Enter 换行、上下键隐式历史、Esc 清空、输入法候选确认不误发、长按 Enter 不连续空发,以及请求进行中不重复提交。
7. 出现 `Password:` 后输入框应自动遮挡,密码不加入页面历史;按当前调试策略,TX 文本日志仍保存实际发送内容。
8. 打开两个页面时关闭其中一个,服务应继续运行;关闭最后一个页面后,正常离页约 `2` 秒、未触发离页事件时最迟约 `5` 秒,状态接口应离线、宿主进程应退出,日志应写入结束标记且 COM 口应释放。刷新页面不能误停服务。
9. 自动停止后核对文本日志和原始字节文件仍位于原路径且未被截断;再次启动服务并确认能够重新打开同一 COM 口。升级期间关闭最后页面也按相同规则停止,不能宣称仍在后台监测。