Files
cnc_wams/wasm-port/working/02-项目程序开发详细步骤.md
2026-07-09 18:12:01 -04:00

151 lines
8.1 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.
# 02-项目程序开发详细步骤
## 阶段 0基线固定
1. 记录当前实现与 LinuxCNC 主循环差距。
2. 固定当前通过的 smoke
- `./tools/verify_task_hal_source_manifest.sh`
- `./tests/wasm/node/verify_motion_hal_sync.sh`
- `./tests/wasm/node/verify_task_hal_wasm.sh`
- `./tests/wasm/node/verify_task_hal_sdk.sh`
3. 记录当前已知阻塞和 readiness
- `./tests/native/verify_task_hal_phase0.sh` 曾因上游运行目录缺少 `xyzac-trt_cmds.hal` 失败T-016 已通过运行目录 machine overlay 修复该 probe 输入完整性。
- task-hal source manifest 仍显示 `task_hal_runtime_promoted=0`,不代表 full native task/HAL runtime 已 promoted。
## 阶段 1建立 task 周期内 motion snapshot
1.`linuxcnc_task_hal_wasm.cpp` 中新增 task runtime 内部 motion snapshot。
2.`linuxcnc_motion_runtime.h` 中定义 `LcmotStatusSnapshot`,字段至少覆盖:
- cycle、program_line、motion_id、status、in_position、paused、stepping、aborted
- queue_count、queue_capacity、queue_full、active_depth
- axis/joint command/feedback
- requested/current velocity
- switchkins/analog outputs。
3.`linuxcnc_motion_runtime.c` 暴露结构化读取函数,避免 task 周期内解析 JSON。
4.`linuxcnc_task_hal_wasm.cpp` 中新增 `wasm_emcMotionUpdate()`,把 `LcmotStatusSnapshot` 映射到 task 持有的 `EMC_STAT.motion` 等价结构。
5. 在每个 `lctask_run_cycles()` task 周期调用 motion snapshot update。
6. 将 status JSON 改为读取 task 内已更新的 snapshot而不是独立拼接最新 motion JSON。
7. 新增测试:
- 队列中 motion 状态变化必须在 `runCycles()` 后反映到 task status。
- 不调用 `runCycles()` 时,仅调用 status API 不应推进 task 周期语义。
- 直接调用 low-level `lcmot_step_servo()`task status 不应自动更新,直到下一次 `lctask_run_cycles()`
## 阶段 2重排 `lctask_run_cycles()` 周期顺序
目标顺序:
1. task heartbeat / cycle 自增。
2. command read从 staged command queue 或 C ABI command slot 取命令。
3. plan处理模式、run、pause、resume、mdi、home、abort 等 task plan 行为。
4. execute根据 task exec state 向 motion/io 发命令或等待 motion/io 完成。
5. motion update读取 motion runtime snapshot 到 task 状态。
6. subordinate sync处理 estop、motion error、io error、soft limit、abort cleanup 等。
7. task update刷新 task-specific status。
8. status write更新 C ABI 可读 status snapshot。
9. servo step按 standalone WASM 边界推进 deterministic servo cycles。
注意:上游 LinuxCNC 是 native process/realtime 拓扑WASM 内的 servo step 位置允许作为 standalone runtime 边界记录在决策里,但 task 对外语义必须说明与上游差异。
建议拆成内部函数,避免把所有逻辑堆回 `lctask_run_cycles()`
```cpp
static void task_cycle_begin(TaskRuntime &state);
static bool task_read_command(TaskRuntime &state);
static int wasm_emcTaskPlan(TaskRuntime &state);
static int wasm_emcTaskExecute(TaskRuntime &state);
static int wasm_emcMotionUpdate(TaskRuntime &state);
static void sync_subordinate_states(TaskRuntime &state);
static void wasm_emcTaskUpdate(TaskRuntime &state);
static void update_top_level_status(TaskRuntime &state);
static void write_status_snapshot(TaskRuntime &state);
```
每个函数必须在注释或文档中标明对应的上游 `emctaskmain.cc` 行为。
## 阶段 3引入 `EMC_STAT` 等价状态容器
1. 对齐 `EMC_STAT.task``EMC_STAT.motion``EMC_STAT.io` 中本阶段需要的字段。
2. 识别上游真实定义来源:
- enum 和函数声明主要在 `emc.hh`
- `EMC_STAT``EMC_TASK_STAT``EMC_MOTION_STAT``EMC_TRAJ_STAT` 真实字段在 `emc_nml.hh`
3. 优先复用 vendored `emc_nml.hh`/`emc.hh` 类型;如依赖过重,建立字段同名、语义同向的窄 `StandaloneEmcStatus`,并记录差异。
4.`TaskRuntime` 中重复字段逐步映射到 `EMC_STAT.task`
5.`lcmot` motion status 映射到 `EMC_STAT.motion`
6. 初始 IO 可用 shim 固定 `DONE`,但必须具备 `status``aux.estop``fault``reason` 字段。
7. 确保 JSON status 只是 `EMC_STAT` 或等价 status buffer 的导出视图。
## 阶段 4迁移 wait/execute 语义
1. 对标 `emcTaskExecute()` 的关键状态:
- `DONE`
- `WAITING_FOR_MOTION_QUEUE`
- `WAITING_FOR_MOTION`
- `WAITING_FOR_IO`
- `WAITING_FOR_MOTION_AND_IO`
- `WAITING_FOR_DELAY`
- `WAITING_FOR_SYSTEM_CMD`
- `ERROR`
2. 先迁移 motion 相关状态,不急于实现 system command/process。
3. `queueFull``motion.status``io.status` 的判断必须从周期 snapshot 读取。
4. pause/step/resume 的状态变化必须覆盖现有 smoke。
## 阶段 5逐步替换自有状态机
1. 把当前 JSON command 分派收缩为 host/C ABI 边界。
2. `lctask_send_command_json()` 不直接修改 `state/mode/interp/exec`,而是入队 command envelope。
3. 在 command read 阶段消费 envelope生成 LinuxCNC task command 等价物。
4. 把 task plan/execute 语义迁向 vendored/upstream `emctask.cc``taskintf.cc``emccanon.cc`
5. 为 native-only/runtime-edge 功能建立 shim
- NML transport
- file IO
- process spawning
- IO process
- realtime HAL/thread scheduling
6. 每替换一段,补一条 matrix 任务和验收证据。
具体源码替换顺序见 `08-上游task源码替换分解.md`。实施时按以下顺序推进:
1. `taskintf.cc` minimal bridge先替换 motion init/update/abort、traj pause/step/resume/linear move。
2. `emctask.cc` state/update/abort替换 task state/mode/abort/update。
3. `emctask.cc` plan wrapper接 interpreter open/read/execute/synch。
4. `emccanon.cc` straight motion`INIT_CANON()``FINISH()``STRAIGHT_TRAVERSE()``STRAIGHT_FEED()`
5. `emctaskmain.cc` execute 分支:用 `interp_list` 和 taskintf issue command。
6. `emccanon.cc` spindle/tool/io 子集dwell、switchkins、tool/spindle command。
## 阶段 6readiness 和文档收口
1. 修正文档、代码、测试中的 readiness 口径。
2. `nativeTaskReady` 只有在真实 vendored/native task 周期被采用后才能为 true。
3. `nativeHalSyncReady` 只有在 HAL 同步达到对应验收后才能为 true。
4. `fullLinuxCncProgramExecutionReady` 只有在完整 program execution 语义闭合后才能为 true。
5. 更新 `docs/source-reuse-map.md`,避免文档声称与实现不一致。
## 阶段 7后续 WASM 核心状态机完善
本阶段用于后续新增任务,不改变 T-001 到 T-049 的闭合状态。实施前必须先在 `04-任务矩阵.md` 新增任务编号、状态、验收标准和 gate。
1. 坚持 WASM/C++ 为核心状态机实现:
- task/motion 状态机、周期调度、状态聚合、命令执行进入 C/C++。
- `StandaloneEmcStatus` 或后续 `EMC_STAT` 等价容器是 status 事实源。
- `LcmotStatusSnapshot` 是 task 周期读取 motion 的结构化输入。
2. 保持 JS/SDK 为 host 边界:
- JS/SDK 可以加载 WASM、写入文件、入队 command、读取 status。
- JS/SDK 不实现 G-code、task、motion、planner 或 canon 语义。
3. 保持 JSON 为通信格式:
- command JSON 只描述 host command envelope。
- status JSON 只导出最后一次 status write。
- 不允许新增依赖 JSON 文本推进 task cycle 的路径。
- 新增 status 字段进入 `emcStatus` 对标对象,不再提供旧字段兼容视图。
4. 每次迁移新语义时优先查找 vendored LinuxCNC source
- 能接入 source-anchored subset 时接入 subset。
- 不能直接接入时建立窄 shim并在 `06-决策记录.md` 写明原因。
5. 每次新增状态字段时同步更新:
- C/C++ status 结构体。
- status JSON 导出。
- WASM smoke。
- SDK smoke。
- state matrix。
- source reuse/drift docs gate。
详细边界和检查清单见 `11-WASM核心状态机边界与后续完善路线.md`status JSON 字段映射、禁止链路和后续 SJ 批次见 `12-status-json-LinuxCNC对标方案.md`