chore: close wasm status contract work
This commit is contained in:
122
wasm-port/working/01-项目功能内容.md
Normal file
122
wasm-port/working/01-项目功能内容.md
Normal file
@@ -0,0 +1,122 @@
|
||||
# 01-项目功能内容
|
||||
|
||||
## 项目目标
|
||||
|
||||
将 `wasm-port` 的 task/motion/HAL 运行时从当前 minimal adapter 推进到尽可能贴近 LinuxCNC 原生 `emctaskmain.cc` 的 task 主循环结构。
|
||||
|
||||
核心要求:
|
||||
|
||||
- 每个 task 周期都建立 LinuxCNC 式 motion 状态快照。
|
||||
- task 状态机使用该 motion 快照驱动等待、错误、estop、abort、queueFull、in-position、program line 等行为。
|
||||
- 周期顺序对标上游 `emctaskmain.cc`:command read -> plan -> execute -> motion update -> subordinate sync -> task update -> status write。
|
||||
- 当前 JSON 自有状态机逐步收缩为 host/runtime 边界,CNC/task 语义优先来自 LinuxCNC 源码。
|
||||
- 后续 WASM 程序定位为核心状态机实现的运行载体:task/motion 状态机、周期调度、状态聚合、命令执行位于 C/C++ WASM 侧;JS/SDK 和 JSON 只承担外部边界职责。
|
||||
|
||||
## 对标源
|
||||
|
||||
主要对标文件:
|
||||
|
||||
- `/home/mes123456/cnc_wams/linuxcnc/src/emc/task/emctaskmain.cc`
|
||||
- `/home/mes123456/cnc_wams/linuxcnc/src/emc/task/emctask.cc`
|
||||
- `/home/mes123456/cnc_wams/linuxcnc/src/emc/task/taskintf.cc`
|
||||
- `/home/mes123456/cnc_wams/linuxcnc/src/emc/task/emccanon.cc`
|
||||
- `/home/mes123456/cnc_wams/linuxcnc/src/emc/task/task.hh`
|
||||
- `/home/mes123456/cnc_wams/linuxcnc/src/emc/nml_intf/emc.hh`
|
||||
- `/home/mes123456/cnc_wams/linuxcnc/src/emc/nml_intf/emc_nml.hh`
|
||||
- `/home/mes123456/cnc_wams/linuxcnc/src/emc/motion/usrmotintf.h`
|
||||
- `/home/mes123456/cnc_wams/linuxcnc/src/emc/motion/motion.h`
|
||||
|
||||
当前 WASM 侧入口:
|
||||
|
||||
- `/home/mes123456/cnc_wams/wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_task_hal_wasm.cpp`
|
||||
- `/home/mes123456/cnc_wams/wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_motion_runtime.c`
|
||||
- `/home/mes123456/cnc_wams/wasm-port/runtime/sdk/src/linuxcnc-task-hal.js`
|
||||
|
||||
## 当前闭合状态
|
||||
|
||||
当前 `wasm-port` 已有:
|
||||
|
||||
- `lctask_*` C ABI。
|
||||
- `lcmot_*` minimal motion runtime。
|
||||
- HAL pin/snapshot runtime。
|
||||
- Node WASM task/motion/HAL smoke。
|
||||
- LinuxCNC 式 task 周期骨架:command read -> plan -> execute -> motion update -> subordinate sync -> task update -> status write。
|
||||
- 周期内 `LcmotStatusSnapshot` 到 `StandaloneEmcStatus.motion` 的映射。
|
||||
- `StandaloneEmcStatus` 作为当前阶段 `EMC_STAT` 等价容器,集中导出 task/motion/io/top status。
|
||||
- RUN 文件主路径通过 staged program plan read/command/execute、`emccanon.cc` command envelope 和 `taskintf.cc` motion issue 工作,不依赖 host JSON motion plan。
|
||||
- task 状态、模式、pause/resume/step/home/run gate、wait-for-motion、queueFull、motion error、soft-limit、IO error、RCS 聚合和 no-JSON RUN path 的 WASM/SDK/state-matrix 覆盖。
|
||||
|
||||
当前保守边界:
|
||||
|
||||
- 当前 shim `runtime/core/shims/nml_intf/emc.hh` 只暴露 `motion.traj.linearUnits`,远小于上游 `emc_nml.hh` 中 `EMC_STAT`、`EMC_TASK_STAT`、`EMC_MOTION_STAT`、`EMC_TRAJ_STAT` 的字段范围。
|
||||
- task-HAL WASM 构建接入的是 `emctask.cc`、`taskintf.cc`、`emccanon.cc` 的窄 source-anchored subset,不是完整上游 process/NML topology。
|
||||
- `tools/task-hal-source-manifest.txt` 仍是 Phase 0 references,`task_hal_runtime_promoted=0`。
|
||||
- `nativeTaskReady=false`、`nativeHalSyncReady=false`、`fullLinuxCncProgramExecutionReady=false` 仍是当前 readiness contract。
|
||||
|
||||
## WASM核心状态机边界
|
||||
|
||||
后续完善时按以下职责划分:
|
||||
|
||||
| 层 | 职责 |
|
||||
| --- | --- |
|
||||
| WASM/C++ | 核心状态机、LinuxCNC 语义复用、task cycle、motion snapshot、`StandaloneEmcStatus`、command read/plan/execute、RCS 聚合。 |
|
||||
| JS/SDK | 加载 WASM、传命令、读状态、管理 Emscripten FS/OPFS 和浏览器/Node 边界。 |
|
||||
| JSON | 作为外部通信格式,例如 command JSON 和 status JSON;不得作为核心状态机事实源。 |
|
||||
|
||||
因此,新增状态应优先进入 C/C++ 结构体、枚举、队列和周期函数;status JSON 只能从最后一次 status write 或 `StandaloneEmcStatus` 导出。
|
||||
|
||||
`status JSON` 的具体 LinuxCNC 对标方案详见 `12-status-json-LinuxCNC对标方案.md`。该方案要求 `emcStatus` 成为新增 LinuxCNC 对标字段的主对象,`task`、`motionStatus` 等旧字段只作为兼容视图。
|
||||
|
||||
## 功能范围
|
||||
|
||||
本阶段要实现或准备实现:
|
||||
|
||||
1. 在 WASM task runtime 内建立 `EMC_STAT` 等价状态容器。
|
||||
2. 将 minimal motion runtime 的状态导入 `EMC_STAT.motion` 等价快照。
|
||||
3. 重排 `lctask_run_cycles()`,使每个 task 周期符合上游主循环顺序。
|
||||
4. 把 wait-for-motion、motion queue、pause/step/resume、abort/error 逻辑改为依赖 motion 快照。
|
||||
5. 增加测试证明 task 周期内读取 motion,而不是只在 status API 读取时拼接 motion。
|
||||
6. 分阶段引入 vendored/upstream task 源码,减少自有状态机语义。
|
||||
|
||||
## 最小字段闭环
|
||||
|
||||
第一阶段必须优先闭合以下字段,原因是它们直接参与 `emctaskmain.cc` 主循环、`emcTaskExecute()` 或顶层 status 聚合:
|
||||
|
||||
| 领域 | 字段 | 用途 |
|
||||
| --- | --- | --- |
|
||||
| task | `state`、`mode` | state/mode gate、power/home/run 前置 |
|
||||
| task | `execState`、`interpState` | `emcTaskPlan()` 和 `emcTaskExecute()` 状态机 |
|
||||
| task | `currentLine`、`readLine`、`motionLine` | interpreter/motion line 对齐 |
|
||||
| task | `task_paused` | pause/resume/step |
|
||||
| motion | `status` | wait-for-motion、error、top-level status |
|
||||
| motion.traj | `enabled`、`inpos`、`queue`、`activeQueue`、`queueFull` | motion wait、queue gate、disable edge |
|
||||
| motion.traj | `id`、`paused`、`single_stepping` | stepping、motion id、pause |
|
||||
| motion.traj | `position`、`actualPosition`、`current_vel` | UI/status、interpreter sync |
|
||||
| motion | `on_soft_limit` | soft-limit error path |
|
||||
| io | `status`、`aux.estop` | subordinate sync、top-level status |
|
||||
|
||||
完整字段映射详见 `07-emctaskmain周期对标蓝图.md`。
|
||||
|
||||
后续 WASM 核心状态机完善路线详见 `11-WASM核心状态机边界与后续完善路线.md`。
|
||||
|
||||
## 非目标
|
||||
|
||||
本阶段不做:
|
||||
|
||||
- 驱动真实硬件。
|
||||
- 浏览器内复刻 LinuxCNC 原生多进程拓扑。
|
||||
- 移植 native GUI。
|
||||
- 用 JavaScript 重写 CNC/task/motion 语义。
|
||||
- 一次性完整移植 realtime motion controller。
|
||||
|
||||
## 完成定义
|
||||
|
||||
阶段完成至少满足:
|
||||
|
||||
- 文档记录 task 主循环对标范围、步骤、任务矩阵和验收证据。
|
||||
- 新增测试能区分“task 周期读取 motion”和“status API 拼接 motion”。
|
||||
- `lctask_run_cycles()` 内存在清晰的 LinuxCNC 式周期结构。
|
||||
- `nativeTaskReady`、`nativeHalSyncReady`、`fullLinuxCncProgramExecutionReady` 等 readiness 字段与真实能力一致。
|
||||
- 现有 WASM task/motion/HAL smoke 不回退。
|
||||
- `lctask_send_command_json()` 不再直接产生 LinuxCNC task 语义变化;语义变化必须由后续 `lctask_run_cycles()` 的 command read/plan/execute 阶段产生。
|
||||
- `lctask_read_status_json()` 不推进、不同步、不重新读取 motion;它只导出最后一次 status write 的快照。
|
||||
150
wasm-port/working/02-项目程序开发详细步骤.md
Normal file
150
wasm-port/working/02-项目程序开发详细步骤.md
Normal file
@@ -0,0 +1,150 @@
|
||||
# 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。
|
||||
|
||||
## 阶段 6:readiness 和文档收口
|
||||
|
||||
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`。
|
||||
2036
wasm-port/working/03-推进台账.md
Normal file
2036
wasm-port/working/03-推进台账.md
Normal file
File diff suppressed because it is too large
Load Diff
72
wasm-port/working/04-任务矩阵.md
Normal file
72
wasm-port/working/04-任务矩阵.md
Normal file
@@ -0,0 +1,72 @@
|
||||
# 04-任务矩阵
|
||||
|
||||
## 状态说明
|
||||
|
||||
- `待办`:尚未开始。
|
||||
- `进行中`:已有修改但未验收闭合。
|
||||
- `完成`:代码/文档/测试/证据均已闭合。
|
||||
- `阻塞`:需要外部文件、上游能力或明确决策后才能继续。
|
||||
|
||||
## 任务列表
|
||||
|
||||
| 编号 | 任务 | 状态 | 验收标准 |
|
||||
| --- | --- | --- | --- |
|
||||
| T-001 | 创建 `wasm-port/working` 推进文档 | 完成 | README、01-06 文档存在;任务矩阵、台账、验收证据、决策记录具备初始内容。 |
|
||||
| T-002 | 固定当前 task/motion/HAL 基线证据 | 完成 | `verify_task_hal_source_manifest.sh`、`verify_motion_hal_sync.sh`、`verify_task_hal_wasm.sh`、`verify_task_hal_sdk.sh` 结果写入 `05-验收证据.md`。 |
|
||||
| T-003 | 设计 task 周期内 motion snapshot C ABI | 完成 | 有设计记录;避免 task 周期内解析 JSON;明确字段映射到 `EMC_STAT.motion` 等价结构。 |
|
||||
| T-004 | 实现 minimal motion snapshot 结构化读取 | 完成 | `linuxcnc_motion_runtime.c` 提供结构化 snapshot 读取;现有 motion smoke 不回退。 |
|
||||
| T-005 | 在 `lctask_run_cycles()` 每个 task 周期读取 motion snapshot | 完成 | 新测试证明 task status 来自周期 snapshot;status API 不再是 task motion 事实源。 |
|
||||
| T-006 | 重排 `lctask_run_cycles()` 为 LinuxCNC 式周期骨架 | 完成 | 代码中有 command read、plan、execute、motion update、subordinate sync、task update、status write 的清晰阶段;现有 smoke 通过。 |
|
||||
| T-007 | 建立 `EMC_STAT` 等价状态容器 | 完成 | task/motion/io 必需字段集中管理;JSON status 从该状态导出。 |
|
||||
| T-008 | 迁移 wait-for-motion 和 queueFull 语义 | 完成 | `WAITING_FOR_MOTION`、`WAITING_FOR_MOTION_QUEUE` 依赖周期 motion snapshot;新增覆盖测试。 |
|
||||
| T-009 | 迁移 motion/io error 和 abort cleanup 语义 | 完成 | motion error/io error 能驱动 task abort/error;测试覆盖不回退。 |
|
||||
| T-010 | 迁移 pause/resume/step 到 snapshot 驱动 | 完成 | `pause_freezes_motion_queue`、`resume_restores_interp_resume_state`、`step_returns_to_paused` 继续通过,并新增周期 snapshot 断言。 |
|
||||
| T-011 | 收缩 JSON command 自有状态机 | 完成 | JSON 只作为 C ABI host 边界;task 语义转入 LinuxCNC 式 plan/execute 层。 |
|
||||
| T-012 | 引入 vendored/upstream `emctask.cc` 可编译子集 | 完成 | build 脚本纳入对应源或 shim;新增 source reuse 验证。 |
|
||||
| T-013 | 引入 vendored/upstream `taskintf.cc` 可编译子集 | 完成 | motion command issuing 更接近上游;adapter 边界有文档说明。 |
|
||||
| T-014 | 引入 vendored/upstream `emccanon.cc` 可编译子集 | 完成 | canonical task/motion command 生成减少自有语义;测试通过。 |
|
||||
| T-015 | 修正 readiness 文档和实现口径 | 完成 | `nativeTaskReady`、`nativeHalSyncReady`、`fullLinuxCncProgramExecutionReady` 与实际能力一致;`docs/source-reuse-map.md` 不再与代码矛盾。 |
|
||||
| T-016 | 处理 `verify_task_hal_phase0.sh` native probe 阻塞 | 完成 | 缺失 `xyzac-trt_cmds.hal` 问题有明确来源修复或任务降级决策;phase0 gate 口径稳定。 |
|
||||
| T-017 | 建立 `emctaskmain.cc` 周期对标蓝图 | 完成 | `07-emctaskmain周期对标蓝图.md` 存在,包含上游代码锚点、WASM 周期骨架、字段映射、command/plan/execute/motion update/status write 对标要求。 |
|
||||
| T-018 | 定义 `LcmotStatusSnapshot` 结构 | 完成 | header 中有结构化 snapshot 类型;字段覆盖 queue、inpos、paused、motion id、axis/joint、velocity、switchkins;不解析 JSON。 |
|
||||
| T-019 | 实现 `lcmot_read_status_snapshot()` | 完成 | 函数只复制 motion runtime 状态,不 step servo、不消费队列;新增 low-level 单测。 |
|
||||
| T-020 | 实现 `wasm_emcMotionUpdate()` 映射层 | 完成 | `LcmotStatusSnapshot` 映射到 `EMC_STAT.motion` 或 `StandaloneEmcStatus.motion`;字段映射有测试。 |
|
||||
| T-021 | 建立 task status buffer 等价物 | 完成 | `lctask_read_status_json()` 只导出最后一次 task status write,不直接读取/同步 motion runtime。 |
|
||||
| T-022 | 建立 command buffer/slot | 完成 | `lctask_send_command_json()` 入队 command;不调用 `runCycles()` 时 task 语义状态不变化。 |
|
||||
| T-023 | 拆分 `lctask_run_cycles()` 周期函数 | 完成 | 内部函数覆盖 cycle begin、command read、plan、execute、motion update、subordinate sync、task update、top-level status、status write。 |
|
||||
| T-024 | 迁移当前 state/mode/home/run gate 到 plan 阶段 | 完成 | 现有 state matrix 通过;command 语义由 `runCycles()` 触发。 |
|
||||
| T-025 | 迁移 MDI/JOG/HOME motion issue 到 execute 阶段 | 完成 | MDI/JOG/HOME 不在 send command 时直接 forward motion;现有 smoke 通过。 |
|
||||
| T-026 | 新增 task 周期 snapshot 行为测试 | 完成 | 覆盖 status read 不推进、不同步;low-level motion step 后 task status 等待下一 task cycle 才更新。 |
|
||||
| T-027 | 新增 motion error/soft-limit 注入测试 | 完成 | motion ERROR 和 soft-limit 能通过 subordinate sync 改变 task/top-level status。 |
|
||||
| T-028 | 对齐 top-level `RCS_STATUS` 聚合 | 完成 | task/motion/io 三方 DONE/EXEC/ERROR 聚合逻辑与 `emctaskmain.cc` 对齐;JSON status 反映聚合值。 |
|
||||
| T-029 | 评估 vendored `emc_nml.hh` 直接复用可行性 | 完成 | 形成记录:直接 include、窄 shim、或分阶段 typedef 的选择和依赖清单。 |
|
||||
| T-030 | 更新 source reuse map 与 drift 文档 | 完成 | `docs/source-reuse-map.md`、drift/compatibility 文档反映 task 主循环迁移阶段和 readiness 真实状态。 |
|
||||
| T-031 | 建立上游 task 源码替换分解文档 | 完成 | `08-上游task源码替换分解.md` 存在,覆盖 `emctask.cc`、`taskintf.cc`、`emccanon.cc` 的函数族、shim、验收和批次。 |
|
||||
| T-032 | `taskintf.cc` usrmot shim 设计 | 完成 | 明确 `usrmot*` 到 `lcmot_*` 的映射,包含 command write、status read、config read、error read。 |
|
||||
| T-033 | `taskintf.cc` motion init/update/abort 子集 | 完成 | `emcMotionInit()`、`emcMotionUpdate()`、`emcMotionAbort()` 通过 WASM bridge 工作;task cycle snapshot 测试通过。 |
|
||||
| T-034 | `taskintf.cc` traj control 子集 | 完成 | `emcTrajEnable/Disable/Abort/Pause/Step/Resume/SetMotionId` 接入 `lcmot`,现有 pause/step/resume smoke 不回退。 |
|
||||
| T-035 | `taskintf.cc` linear move issue 子集 | 完成 | `emcTrajLinearMove()` 替换 task JSON linear move 拼接;G0/G1 smoke 通过。 |
|
||||
| T-036 | `taskintf.cc` jog/home/switchkins 子集 | 完成 | `emcJogIncr()`、`emcJointHome/Unhome()`、`emcMotionSetAout()` 接入;Home/Jog/M428-M430 验收通过。 |
|
||||
| T-037 | `emctask.cc` abort/state/mode 子集 | 完成 | `emcTaskAbort()`、`emcTaskSetMode()`、`emcTaskSetState()` 替换当前自有逻辑;语义由 task cycle 触发。 |
|
||||
| T-038 | `emctask.cc` determine/update 子集 | 完成 | `determineMode()`、`determineState()`、`emcTaskUpdate()` 从 motion/io snapshot 推导 task status。 |
|
||||
| T-039 | `emctask.cc` plan wait/synch/open/close 子集 | 完成 | `PlanSetWait/IsWait/ClearWait/Synch/Open/Close/Reset` 接入 vendored interpreter 和 staged FS。 |
|
||||
| T-040 | `emctask.cc` plan read/execute 子集 | 完成 | `PlanRead/Execute/Line/Level/Command` 驱动 `interp_list`;不依赖 JSON motion plan。 |
|
||||
| T-041 | `emccanon.cc` canon init/finish/unit 子集 | 完成 | `INIT_CANON()`、`ON_RESET()`、`FINISH()`、单位/endpoint getter 接入 `EMC_STAT`。 |
|
||||
| T-042 | `emccanon.cc` straight traverse/feed 子集 | 完成 | `STRAIGHT_TRAVERSE()`、`STRAIGHT_FEED()` 生成 LinuxCNC `EMC_TRAJ_LINEAR_MOVE` 到 `interp_list`。 |
|
||||
| T-043 | `emccanon.cc` dwell/path-control 子集 | 完成 | `DWELL()` 和 `SET_MOTION_CONTROL_MODE()` 进入 task delay/path mode 语义。 |
|
||||
| T-044 | `emccanon.cc` spindle/tool command 子集 | 完成 | spindle/tool commands append 到 `interp_list`,runtime boundary 和 readiness 保守记录。 |
|
||||
| T-045 | `emccanon.cc` motion output/switchkins 子集 | 完成 | M62-M68/M428-M430 通过 canon motion output 到 `emcMotionSetAout()`,移除字符串 special-case。 |
|
||||
| T-046 | 移除主路径 JSON motion plan 依赖 | 完成 | RUN 文件主路径由 `Interp::open/read/execute` + `emccanon.cc` + `interp_list` + `emcTaskExecute()` 驱动;`loadProgramMotionPlan()` 降为调试/兼容入口或删除。 |
|
||||
| T-047 | 收口 working 索引与闭合 gate | 完成 | README、功能内容、NML 评估和矩阵闭合口径与 T-007/T-046 当前实现一致;有 gate 验证无待办/进行中/阻塞任务。 |
|
||||
| T-048 | 将 working closure gate 纳入全局文档一致性验证 | 完成 | `source-reuse-map.md`、`compatibility-validation.md` 和 `verify_task_source_reuse_drift_docs.sh` 均记录并检查 `verify_task_working_closure.sh`。 |
|
||||
| T-049 | 建立 task-HAL 全量闭合验证入口 | 完成 | `tools/verify_task_full_closure.sh` 一次性执行 build、WASM smoke、SDK、state matrix、motion sync、T-007/T-046/T-047/T-048/docs/readiness gates。 |
|
||||
| T-050 | 建立 status JSON LinuxCNC 对标方案 | 完成 | `12-status-json-LinuxCNC对标方案.md` 存在;README、功能内容、开发步骤、台账、证据和决策记录均记录 `StandaloneEmcStatus -> status JSON` 方案;working closure gate 不回退。 |
|
||||
| T-051 | SJ-1 规范 `emcStatus.motion.traj` | 完成 | `emcStatus.motion.traj` 导出 enabled/inpos/queue/activeQueue/queueFull/id/paused/singleStepping/position/actualPosition/currentVel;WASM/SDK/state matrix 和 status JSON contract gate 断言其与兼容 `motionStatus` 同源。 |
|
||||
| T-052 | SJ-2 规范 task line 和 interpreter 字段 | 完成 | `StandaloneEmcTaskStatus` 集中 currentLine/readLine/motionLine/callLevel;`task` 兼容视图和 `emcStatus.task` 同源;staged RUN 后 contract gate 验证 line 字段。 |
|
||||
| T-053 | SJ-3 规范 `emcStatus.motion.axis[]` 和 `joint[]` | 完成 | `StandaloneEmcMotionStatus` 保存 axis command/feedback 与 joint command/feedback 数组;`emcStatus.motion.axis[]`、`joint[]` 导出至少 6 轴/关节,旧 `motionStatus.axis`、`joint0` 与新数组一致。 |
|
||||
| T-054 | SJ-4 规范 IO/aux/tool/coolant 边界 | 完成 | `emcStatus.io` 导出 status/error/fault/reason/aux.estop;tool/coolant 以 `supported=false` 和 shim reason 显式标记未接 native IO;readiness 仍为 false。 |
|
||||
| T-055 | SJ-5 引入 status JSON contract gate | 完成 | 新增 `tools/verify_task_status_json_contract.sh` 和 Node contract 测试;检查 `statusSource=StandaloneEmcStatus`、`lctask_read_status_json()` 不调用 motion JSON、SDK 不实现 task/motion 语义;该 gate 纳入 full closure。 |
|
||||
|
||||
## 当前推进指针
|
||||
|
||||
下一条优先任务:无。任务矩阵当前已闭合;`11-WASM核心状态机边界与后续完善路线.md` 和 `12-status-json-LinuxCNC对标方案.md` 中 SJ-1 到 SJ-5 已补入 T-051 到 T-055 并闭合。后续新增对标项需先补入本矩阵。
|
||||
2925
wasm-port/working/05-验收证据.md
Normal file
2925
wasm-port/working/05-验收证据.md
Normal file
File diff suppressed because it is too large
Load Diff
1160
wasm-port/working/06-决策记录.md
Normal file
1160
wasm-port/working/06-决策记录.md
Normal file
File diff suppressed because it is too large
Load Diff
218
wasm-port/working/07-emctaskmain周期对标蓝图.md
Normal file
218
wasm-port/working/07-emctaskmain周期对标蓝图.md
Normal file
@@ -0,0 +1,218 @@
|
||||
# 07-emctaskmain 周期对标蓝图
|
||||
|
||||
## 对标目标
|
||||
|
||||
本蓝图把 LinuxCNC `emctaskmain.cc` 的 task 主循环拆成 `wasm-port` 可逐步实现的周期阶段。后续实现不得只在 JSON status 层拼接 motion,而必须让 task 周期本身读取并消费 motion snapshot。
|
||||
|
||||
## 上游周期源代码锚点
|
||||
|
||||
| 上游位置 | 行为 | WASM 对标要求 |
|
||||
| --- | --- | --- |
|
||||
| `emctask_startup()` motion 初始化 | `emcMotionInit()` 后立即 `emcMotionUpdate(&emcStatus->motion)`,失败则启动失败 | `lctask_init_session()` 必须初始化 motion runtime,并建立第一份 task 持有的 motion snapshot |
|
||||
| 主循环 `task_beat++` | task heartbeat 每周期递增 | `lctask_run_cycles()` 每个 task cycle 增加 task heartbeat/cycle |
|
||||
| `check_ini_hal_items()` | 周期检查 INI/HAL 项 | standalone 可先记录为 shim 阶段,后续接 HAL/INI 检查 |
|
||||
| `emcCommandBuffer->read()` | 读取新 task command,成功后清 `taskPlanError/taskExecuteError` | JSON C ABI command 应先进入 command buffer/slot,再由 task cycle 消费 |
|
||||
| `emcTaskPlan()` | 处理 task state/mode/interpreter/read-ahead/MDI 队列 | 当前 `lctask_send_command_json()` 的状态变化要迁到 plan 阶段 |
|
||||
| `emcTaskExecute()` | 根据 `execState` issue command 或等待 motion/io | 当前直接 forward motion command 的逻辑要迁到 execute 阶段 |
|
||||
| `emcMotionUpdate(&emcStatus->motion)` | 每周期读取 motion 状态 | 每个 `lctask_run_cycles()` 周期必须执行结构化 `lcmot_read_snapshot()` 等价调用 |
|
||||
| volatile home sync | motion enabled -> disabled 时 unhome volatile joints | standalone 先保留字段/事件,后续接 joints/homing |
|
||||
| estop subordinate sync | io estop 时 disable traj、abort task/io/spindle、synch plan | 需要 task 周期内根据 `emcStatus.io` 和 `emcStatus.motion` 统一处理 |
|
||||
| motion/io error sync | soft-limit、motion error、io hard fault 驱动 abort cleanup | 必须新增 motion error 注入测试 |
|
||||
| `emcTaskUpdate(&emcStatus->task)` | 刷新 task status | WASM status snapshot 要从 `emcStatus.task` 等价结构导出 |
|
||||
| top-level status aggregation | 根据 task/motion/io 状态设置 `emcStatus.status` 和 `task.status` | JSON status 中的 task top-level status 必须由聚合结果生成 |
|
||||
| `emcStatusBuffer->write(emcStatus)` | 写出完整状态 | WASM 中写入 last status snapshot,SDK read 只读该 snapshot |
|
||||
|
||||
## WASM 周期骨架
|
||||
|
||||
目标伪代码:
|
||||
|
||||
```cpp
|
||||
int lctask_run_cycles(long task_period_ns, long servo_period_ns, int task_cycles)
|
||||
{
|
||||
for each task cycle:
|
||||
task_heartbeat++;
|
||||
|
||||
task_cycle_begin();
|
||||
check_ini_hal_items_shim();
|
||||
|
||||
command_read_result = wasm_task_command_buffer_read();
|
||||
if (command_read_result.new_command) {
|
||||
taskPlanError = false;
|
||||
taskExecuteError = false;
|
||||
}
|
||||
|
||||
if (wasm_emcTaskPlan() != 0) {
|
||||
taskPlanError = true;
|
||||
}
|
||||
|
||||
if (wasm_emcTaskExecute() != 0) {
|
||||
taskExecuteError = true;
|
||||
}
|
||||
|
||||
wasm_emcMotionUpdate(&emcStatus.motion);
|
||||
wasm_sync_subordinate_states();
|
||||
wasm_emcTaskUpdate(&emcStatus.task);
|
||||
wasm_update_top_level_status();
|
||||
wasm_status_buffer_write(emcStatus);
|
||||
|
||||
lcmot_step_servo(servo_period_ns, servo_per_task);
|
||||
}
|
||||
```
|
||||
|
||||
说明:
|
||||
|
||||
- 上游 motion 是独立 realtime 子系统,task 读的是 motion 已产生的状态。
|
||||
- WASM standalone 需要 deterministic servo step。若先 step servo 再 motion update 才能模拟“读取最新子系统状态”,必须在 `06-决策记录.md` 明确差异,并用测试固定语义。
|
||||
- 无论 servo step 放在周期前还是周期后,`emcTaskExecute()` 的判断必须读取 task 持有的上一份/本份 motion snapshot,不允许临时解析 status JSON。
|
||||
|
||||
## `EMC_STAT` 字段映射优先级
|
||||
|
||||
第一优先级字段用于让 task 主循环能按 LinuxCNC 结构运行:
|
||||
|
||||
| LinuxCNC 字段 | 上游定义 | 当前/目标 WASM 来源 | 用途 |
|
||||
| --- | --- | --- | --- |
|
||||
| `EMC_STAT.task.state` | `EMC_TASK_STAT.state` | 当前 `TaskRuntime.state` -> `emcStatus.task.state` | ESTOP/OFF/ON gate |
|
||||
| `EMC_STAT.task.mode` | `EMC_TASK_STAT.mode` | 当前 `TaskRuntime.mode` -> `emcStatus.task.mode` | MANUAL/MDI/AUTO gate |
|
||||
| `EMC_STAT.task.execState` | `EMC_TASK_STAT.execState` | 当前 `exec_state` -> enum | execute 状态机 |
|
||||
| `EMC_STAT.task.interpState` | `EMC_TASK_STAT.interpState` | 当前 `interp_state` -> enum | read-ahead/pause/run |
|
||||
| `EMC_STAT.task.currentLine` | `EMC_TASK_STAT.currentLine` | motion plan/interp list line | motion id、UI line |
|
||||
| `EMC_STAT.task.readLine` | `EMC_TASK_STAT.readLine` | interpreter read line | read-ahead 对标 |
|
||||
| `EMC_STAT.task.motionLine` | `EMC_TASK_STAT.motionLine` | motion snapshot `programLine/id` | 当前 motion line |
|
||||
| `EMC_STAT.task.task_paused` | `EMC_TASK_STAT.task_paused` | pause/step state | pause/resume/step |
|
||||
| `EMC_STAT.motion.status` | base `RCS_STAT_MSG.status` | `lcmot` snapshot status | wait/error/status aggregation |
|
||||
| `EMC_STAT.motion.traj.enabled` | `EMC_TRAJ_STAT.enabled` | state ON/off + motion runtime | estop/disable edge |
|
||||
| `EMC_STAT.motion.traj.inpos` | `EMC_TRAJ_STAT.inpos` | `lcmot.in_position` | wait-for-motion |
|
||||
| `EMC_STAT.motion.traj.queue` | `EMC_TRAJ_STAT.queue` | `lcmot.queue_count` | queue/status aggregation |
|
||||
| `EMC_STAT.motion.traj.activeQueue` | `EMC_TRAJ_STAT.activeQueue` | active motion depth | queue/status aggregation |
|
||||
| `EMC_STAT.motion.traj.queueFull` | `EMC_TRAJ_STAT.queueFull` | queue capacity check | `WAITING_FOR_MOTION_QUEUE` |
|
||||
| `EMC_STAT.motion.traj.id` | `EMC_TRAJ_STAT.id` | `lcmot.motion_id` | stepping/current line |
|
||||
| `EMC_STAT.motion.traj.paused` | `EMC_TRAJ_STAT.paused` | `lcmot.paused` | pause/step |
|
||||
| `EMC_STAT.motion.traj.single_stepping` | `EMC_TRAJ_STAT.single_stepping` | `lcmot.stepping` | step |
|
||||
| `EMC_STAT.motion.traj.actualPosition` | `EMC_TRAJ_STAT.actualPosition` | `lcmot.axis_fb` mapped pose | interpreter sync/start line |
|
||||
| `EMC_STAT.motion.traj.position` | `EMC_TRAJ_STAT.position` | `lcmot.axis_cmd` mapped pose | UI/canon endpoint |
|
||||
| `EMC_STAT.motion.on_soft_limit` | `EMC_MOTION_STAT.on_soft_limit` | future injection/runtime flag | soft-limit path |
|
||||
| `EMC_STAT.io.status` | `EMC_IO_STAT.status` | initial shim `DONE`/future IO runtime | wait/error aggregation |
|
||||
| `EMC_STAT.io.aux.estop` | `EMC_IO_STAT.aux.estop` | task state/IO shim | estop subordinate sync |
|
||||
|
||||
第二优先级字段在 program execution 更深入时补齐:
|
||||
|
||||
- `activeGCodes`、`activeMCodes`、`activeSettings`
|
||||
- `g5x_offset`、`g92_offset`、`rotation_xy`、`toolOffset`
|
||||
- `synch_di`、`synch_do`、`analog_input`、`analog_output`
|
||||
- spindle orient state/fault
|
||||
- toolchanger fault/reason
|
||||
|
||||
## command read 对标
|
||||
|
||||
当前 `lctask_send_command_json()` 直接修改 task state 或 forward motion。目标结构:
|
||||
|
||||
1. `lctask_send_command_json()` 只把 JSON 解析成 task command envelope,写入 WASM command buffer。
|
||||
2. `lctask_run_cycles()` 内的 command read 阶段消费一条 command。
|
||||
3. command read 成功后清 `taskPlanError` 和 `taskExecuteError`。
|
||||
4. command 的语义处理转入 `wasm_emcTaskPlan()` 或 `wasm_emcTaskIssueCommand()`。
|
||||
|
||||
验收:
|
||||
|
||||
- 调用 `sendCommand()` 后不调用 `runCycles()`,task state 不发生 LinuxCNC 语义变化。
|
||||
- 调用一次 `runCycles()` 后,command 被计划/执行,状态变化出现。
|
||||
|
||||
## plan 对标
|
||||
|
||||
第一阶段 plan 只迁移现有已支持命令:
|
||||
|
||||
- `EMC_TASK_SET_STATE`
|
||||
- `EMC_TASK_SET_MODE`
|
||||
- `EMC_TASK_PLAN_RUN`
|
||||
- `EMC_TASK_PLAN_PAUSE`
|
||||
- `EMC_TASK_PLAN_RESUME`
|
||||
- `EMC_TASK_PLAN_STEP`
|
||||
- `EMC_TASK_ABORT`
|
||||
- `EMC_TASK_PLAN_EXECUTE`
|
||||
- `EMC_JOINT_HOME`
|
||||
- `EMC_JOG_INCR`
|
||||
|
||||
要求:
|
||||
|
||||
- plan 只决定 task/interp/exec 状态和待执行命令,不直接 step motion。
|
||||
- AUTO run 必须通过 state/mode/home/program/motion-plan gates。
|
||||
- MDI/JOG/HOME 只生成后续 execute 要 issue 的 command。
|
||||
|
||||
## execute 对标
|
||||
|
||||
第一阶段 execute 对标 `emcTaskExecute()` 的 motion 相关分支:
|
||||
|
||||
- `DONE`:从 interp/MDI/jog/home pending command 取命令,检查 `motion.traj.queueFull`,issue command 或进入 wait。
|
||||
- `WAITING_FOR_MOTION_QUEUE`:直到 `motion.traj.queueFull == false` 才继续。
|
||||
- `WAITING_FOR_MOTION`:`motion.status == ERROR` 进入 `ERROR`,`motion.status == DONE` 进入 `DONE`。
|
||||
- `WAITING_FOR_MOTION_AND_IO`:motion/io 都 DONE 才完成,任一 ERROR 则 ERROR。
|
||||
- `ERROR`:执行 abort cleanup,清 pending command/interp list,重置 interp/exec state。
|
||||
|
||||
暂缓:
|
||||
|
||||
- `WAITING_FOR_SYSTEM_CMD`:外部进程 runtime boundary。
|
||||
- spindle orient 深度行为:先保留字段和测试入口,后续接 spindle snapshot。
|
||||
- toolchanger fault 深度行为:先由 IO shim 固定 DONE。
|
||||
|
||||
## motion update 对标
|
||||
|
||||
必须新增结构化边界,建议名称:
|
||||
|
||||
```c
|
||||
typedef struct LcmotStatusSnapshot { ... } LcmotStatusSnapshot;
|
||||
int lcmot_read_status_snapshot(LcmotStatusSnapshot *out);
|
||||
```
|
||||
|
||||
要求:
|
||||
|
||||
- `lcmot_read_status_snapshot()` 不推进 servo,不消费队列,只复制当前 motion runtime 状态。
|
||||
- `wasm_emcMotionUpdate(&emcStatus.motion)` 只把 `LcmotStatusSnapshot` 映射到 `EMC_MOTION_STAT` 等价结构。
|
||||
- `lctask_read_status_json()` 只导出最后一次 `wasm_status_buffer_write()` 的结果。
|
||||
|
||||
验收:
|
||||
|
||||
- 先写入 motion command,不跑 task cycle,status 不应被 task semantic 更新。
|
||||
- 跑 task cycle 后,task-held `motion.traj.queue/queueFull/id/inpos/position` 更新。
|
||||
- 直接调用 low-level `lcmot_step_servo()` 后,除非再跑 task cycle,否则 task status snapshot 仍保持上一周期。
|
||||
|
||||
## subordinate sync 对标
|
||||
|
||||
第一阶段需要覆盖:
|
||||
|
||||
1. `motion.traj.enabled` 从 true 到 false 时,清 homed 或记录 volatile-home TODO。
|
||||
2. `io.aux.estop == true` 且 motion enabled 时,执行 traj disable、task abort、io abort、spindle abort shim、plan synch。
|
||||
3. `motion.status == ERROR && motion.on_soft_limit` 时,进入 soft-limit reporting path。
|
||||
4. `motion.status == ERROR` 或 hard IO error 时,执行 abort cleanup。
|
||||
5. 根据 task/motion/io 三方状态聚合 top-level `RCS_STATUS::ERROR/DONE/EXEC`。
|
||||
|
||||
## status write 对标
|
||||
|
||||
WASM 需要引入 task status buffer 等价物:
|
||||
|
||||
- `TaskRuntime.last_status_snapshot`
|
||||
- 或 `StandaloneEmcStatus emcStatus`
|
||||
- `lctask_read_status_json()` 从该 snapshot 序列化
|
||||
|
||||
要求:
|
||||
|
||||
- status read 不改变 task/motion/io 状态。
|
||||
- status read 不直接调用 `lcmot_read_status_json()` 改变观察口径。
|
||||
- debug/event log 可以单独存在,但不能替代 status buffer。
|
||||
|
||||
status JSON 只是 status buffer 的 host/browser 序列化格式。后续新增 LinuxCNC 对标字段时,字段应先进入 `StandaloneEmcStatus` 或后续 `EMC_STAT` 等价容器,再导出到 `emcStatus` JSON 对象;旧 `task`、`motionStatus` 字段只作为兼容视图。具体字段映射和 SJ 批次见 `12-status-json-LinuxCNC对标方案.md`。
|
||||
|
||||
## 替换上游源码路线
|
||||
|
||||
| 阶段 | 引入源 | 目标 |
|
||||
| --- | --- | --- |
|
||||
| R1 | `emc_nml.hh` 必需 enum/status 子集或 vendored include | 用 LinuxCNC 状态类型替换字符串状态 |
|
||||
| R2 | `emctaskmain.cc` 周期骨架等价函数 | 建立 task main loop 结构 |
|
||||
| R3 | `taskintf.cc` motion issuing 可编译子集 | 用上游 task interface 发 motion command |
|
||||
| R4 | `emctask.cc` state/mode/task update 可编译子集 | 减少自有 task state logic |
|
||||
| R5 | `emccanon.cc` canonical motion command 子集 | interpreter/canon 到 motion 命令更接近上游 |
|
||||
|
||||
每一阶段必须满足:
|
||||
|
||||
- source reuse map 更新。
|
||||
- build 脚本增量编译。
|
||||
- Node WASM smoke 不回退。
|
||||
- 新增至少一个对标断言。
|
||||
262
wasm-port/working/08-上游task源码替换分解.md
Normal file
262
wasm-port/working/08-上游task源码替换分解.md
Normal file
@@ -0,0 +1,262 @@
|
||||
# 08-上游 task 源码替换分解
|
||||
|
||||
## 目标
|
||||
|
||||
本文件把上游 `emctask.cc`、`taskintf.cc`、`emccanon.cc` 的替换路线拆成可实施步骤。目标不是把三个文件一次性塞进 WASM 构建,而是按 LinuxCNC 语义依赖顺序逐步替换当前 `linuxcnc_task_hal_wasm.cpp` 中的 JSON 自有状态机。
|
||||
|
||||
总原则:
|
||||
|
||||
- 先建立 `EMC_STAT`、motion snapshot、status buffer、command buffer。
|
||||
- 再迁 `emctask.cc` 的 task/interpreter/status 管理。
|
||||
- 再迁 `taskintf.cc` 的 task->motion command issue 和 motion update。
|
||||
- 最后迁 `emccanon.cc` 的 canon->interp_list command 生成。
|
||||
- 每迁一个函数族,都必须有 source reuse、shim 边界和 WASM 测试证据。
|
||||
|
||||
## 文件职责总览
|
||||
|
||||
| 文件 | 上游职责 | WASM 替换目标 |
|
||||
| --- | --- | --- |
|
||||
| `emctask.cc` | task mode/state、abort cleanup、interpreter plan open/read/execute/synch、`emcTaskUpdate()` | 替换当前 `TaskRuntime` 中 state/mode/interp/exec 字符串状态和 open/run/MDI 自有逻辑 |
|
||||
| `taskintf.cc` | task 到 motion 的接口;`emcTraj*`、`emcJoint*`、`emcSpindle*`、`emcMotionInit/Update/Abort` | 替换当前直接 `forward_motion_command()` 和 `lcmot_read_status_json()` 拼接路径 |
|
||||
| `emccanon.cc` | canonical API;单位/偏置/速度加速度转换;生成 `EMC_TRAJ_*`、spindle/tool/io command 到 `interp_list` | 替换当前按字符串/G-code line 生成 motion plan/linear move 的自有行为 |
|
||||
|
||||
## 迁移依赖链
|
||||
|
||||
```text
|
||||
emctaskmain cycle
|
||||
-> emcTaskPlan()/emcTaskExecute()
|
||||
-> interp_list
|
||||
-> emcTaskIssueCommand()
|
||||
-> taskintf.cc emcTraj*/emcMotion*/emcJoint*/emcSpindle*
|
||||
-> lcmot/lchal runtime boundary
|
||||
-> emccanon.cc canonical functions append commands to interp_list
|
||||
```
|
||||
|
||||
因此迁移顺序必须是:
|
||||
|
||||
1. `EMC_STAT`/`interp_list`/command buffer 基础。
|
||||
2. `taskintf.cc` 的 minimal motion command bridge。
|
||||
3. `emctask.cc` 的 abort/state/mode/update 和 plan wrapper。
|
||||
4. `emccanon.cc` 的 linear/traverse/feed/dwell/spindle/tool 子集。
|
||||
5. 更完整的 interpreter file run 和 MDI 行为。
|
||||
|
||||
## `emctask.cc` 分解
|
||||
|
||||
### E1:状态和 abort 基础
|
||||
|
||||
优先函数:
|
||||
|
||||
| 函数 | 上游行为 | WASM 实施 |
|
||||
| --- | --- | --- |
|
||||
| `emcTaskQueueTaskPlanSynchCmd()` | 向 task command queue 追加 `EMC_TASK_PLAN_SYNCH` | 需要 command queue 支持内部 command |
|
||||
| `emcTaskAbort()` | `emcMotionAbort()`、清 `emcTaskCommand`、清 `interp_list`、重置 interp/exec/line、queue synch | 替换当前 `EMC_TASK_ABORT` 直接设置字符串状态 |
|
||||
| `emcTaskSetMode()` | MANUAL/MDI/AUTO 切换并设置 traj mode、abort/synch | 替换当前 SET_MODE 自有逻辑 |
|
||||
| `emcTaskSetState()` | OFF/ON/ESTOP_RESET/ESTOP 驱动 motion/io/spindle/task abort | 替换当前 SET_STATE 自有逻辑 |
|
||||
| `determineMode()` | 由 `motion.traj.mode` 和 `mdiOrAuto` 推导 task mode | 用 snapshot 推导 status,而不是保存字符串 |
|
||||
| `determineState()` | 由 `io.aux.estop` 和 `motion.traj.enabled` 推导 task state | 用 snapshot 推导 status |
|
||||
| `emcTaskUpdate()` | 更新 mode/state/motionLine/file/active modes | 替换当前 `status_json()` 手写 task 字段 |
|
||||
| `emcAbortCleanup()` | abort 后清理/消息 | 初期保留 shim,后续接 LinuxCNC 行为 |
|
||||
|
||||
依赖 shim:
|
||||
|
||||
- `emcMotionAbort()`、`emcTrajSetMode()`、`emcTrajEnable()`、`emcTrajDisable()`。
|
||||
- `emcIoAbort()`、`emcAuxEstopOn/Off()`、coolant/spindle shim。
|
||||
- `interp_list.clear()`、`emcTaskCommand`。
|
||||
- `emcStatus` 全局或等价容器。
|
||||
|
||||
验收:
|
||||
|
||||
- SET_STATE/SET_MODE 发送后不立即改变 task 语义;一次 task cycle 后通过 `emcTaskSetState/Mode` 路径改变。
|
||||
- `emcTaskAbort()` 后 `interpState=IDLE`、`execState=DONE`、line 清零、motion abort command 已发出。
|
||||
- `emcTaskUpdate()` 的 `state/mode/motionLine` 来自 `EMC_STAT.motion/io` snapshot。
|
||||
|
||||
### E2:plan/interpreter wrapper
|
||||
|
||||
优先函数:
|
||||
|
||||
| 函数 | 上游行为 | WASM 实施 |
|
||||
| --- | --- | --- |
|
||||
| `emcTaskPlanInit()` | 创建/初始化 interpreter、执行 startup code | 先接现有 vendored interpreter init;动态 shlib 路径作为非目标 shim |
|
||||
| `emcTaskPlanSetWait/IsWait/ClearWait()` | 控制 read-ahead waitFlag | 直接迁移 |
|
||||
| `emcTaskPlanSynch()` | `interp.synch()`,失败 abort | 用 task-held motion position/status 支撑 |
|
||||
| `emcTaskPlanOpen()` | 打开文件并清 motion/current/read line | 替换 `lctask_open_program()` 中自有 open 状态 |
|
||||
| `emcTaskPlanRead()` | `interp.read()`,必要时 reopen file | 替换 motion plan 预加载路线 |
|
||||
| `emcTaskPlanExecute()` | `interp.execute()`,MDI 时 `FINISH()` | 接 `emccanon.cc` 后形成 `interp_list` |
|
||||
| `emcTaskPlanClose/Reset/Line/Level/Command()` | interpreter 状态读写 | 直接对接 vendored interpreter |
|
||||
|
||||
依赖 shim:
|
||||
|
||||
- vendored `Interp` 可编译子集已在 interpreter WASM 中存在,但 task-hal 模块需要链接或抽取共享。
|
||||
- `FINISH()` 来自 `emccanon.cc`。
|
||||
- `rs274ngc_startup_code`、INI lookup、file staging。
|
||||
|
||||
验收:
|
||||
|
||||
- `open -> runCycles(read/execute)` 通过 LinuxCNC `Interp::open/read/execute`,不是 JS/JSON motion plan。
|
||||
- `readLine/currentLine/callLevel/command` 与 upstream interpreter 返回一致。
|
||||
- MDI command 通过 `emcTaskPlanExecute(command)` 进入 `interp_list`。
|
||||
|
||||
## `taskintf.cc` 分解
|
||||
|
||||
### TIF1:motion runtime bridge
|
||||
|
||||
优先函数:
|
||||
|
||||
| 函数 | 上游行为 | WASM 实施 |
|
||||
| --- | --- | --- |
|
||||
| `emcMotionInit()` | `emcTrajInit()`、joint/axis/spindle init、position load | 调用 `lcmot_init_from_ini()` 和 HAL init;建立 config defaults |
|
||||
| `emcMotionAbort()` | jog abort + traj abort | 发 `EMCMOT_ABORT` 到 `lcmot` |
|
||||
| `emcMotionHalt()` | halt/disable/save/exit | standalone shim,不能真实硬件 |
|
||||
| `emcMotionUpdate()` | `usrmotReadEmcmotStatus()` 后更新 traj/joint/axis/spindle/synch IO/heartbeat | 改为 `lcmot_read_status_snapshot()` -> `EMC_MOTION_STAT` |
|
||||
| `emcTrajUpdate()` | 映射 emcmot status 到 `EMC_TRAJ_STAT` | 复刻字段映射到 snapshot |
|
||||
| `emcJointUpdate()` | 映射 joint status | 第一阶段只映射 homed/pos/ferror 必需字段 |
|
||||
| `emcAxisUpdate()` | 映射 axis status | 第一阶段映射 pos cmd/fb |
|
||||
| `emcSpindleUpdate()` | 映射 spindle status | 初期单 spindle shim,后续 orient/atspeed |
|
||||
|
||||
依赖 shim:
|
||||
|
||||
- `usrmot*` 系列函数替换为 `lcmot_*` C ABI。
|
||||
- `emcmot_command_t` 可复用上游 motion headers,或建立命令转换层。
|
||||
- INI axis/joint/spindle 初始化先使用已有 INI/WASM runtime 或默认值。
|
||||
|
||||
验收:
|
||||
|
||||
- `emcMotionUpdate(&emcStatus.motion)` 每个 task cycle 调用一次。
|
||||
- status read 不调用 `emcMotionUpdate()`。
|
||||
- low-level `lcmot_step_servo()` 后 task status 不变,直到 task cycle 调用 `emcMotionUpdate()`。
|
||||
|
||||
### TIF2:traj command issue
|
||||
|
||||
优先函数:
|
||||
|
||||
| 函数 | 上游行为 | WASM 实施 |
|
||||
| --- | --- | --- |
|
||||
| `emcTrajSetMotionId()` | 设置下一个 motion id | 映射到 `lcmot` command id 或 task pending id |
|
||||
| `emcTrajEnable/Disable/Abort()` | 发 ENABLE/DISABLE/ABORT | 替换当前 state ON/OFF 手写状态 |
|
||||
| `emcTrajPause/Step/Resume()` | 发 PAUSE/STEP/RESUME | 替换当前 pause/step/resume direct JSON |
|
||||
| `emcTrajLinearMove()` | 构造 `EMCMOT_SET_LINE` | 替换 `enqueue_linear_move_from_line()` |
|
||||
| `emcTrajCircularMove()` | 构造 `EMCMOT_SET_CIRCLE` | 后续接 arc/canon |
|
||||
| `emcTrajDelay()` | task controller 处理 delay | 映射到 `WAITING_FOR_DELAY` |
|
||||
| `emcTrajSetOffset/G5X/G92/Rotation` 相关 | motion/task offsets | 后续接 `emccanon.cc` offsets |
|
||||
|
||||
验收:
|
||||
|
||||
- `EMC_TRAJ_LINEAR_MOVE` 由 `emcTrajLinearMove()` 路径进入 `lcmot`,而不是 task JSON 自行拼接。
|
||||
- pause/resume/step 仍通过现有 WASM smoke。
|
||||
- queueFull 时 `emcTaskExecute()` 进入 `WAITING_FOR_MOTION_QUEUE`。
|
||||
|
||||
### TIF3:joint/jog/spindle/io 命令
|
||||
|
||||
优先函数:
|
||||
|
||||
| 函数组 | 范围 | 首阶段处理 |
|
||||
| --- | --- | --- |
|
||||
| `emcJointHome/Unhome` | homing/unhome | 保留当前 homing smoke,但通过 taskintf shim |
|
||||
| `emcJogIncr/Cont/Abs/Stop` | manual jog | 先迁 `emcJogIncr()` |
|
||||
| `emcSpindleOn/Off/Speed/Orient` | spindle | 初期 command/event shim,后续 snapshot |
|
||||
| `emcMotionSetAout/Dout` | M62-M68/switchkins | 优先保留 `M428/M429/M430` switchkins 验收 |
|
||||
|
||||
验收:
|
||||
|
||||
- Home/Jog/switchkins 现有 tests 通过。
|
||||
- `motion.switchkins-type` 仍同步 HAL。
|
||||
- spindle/tool 未实现项明确标为 runtime boundary,不假装 ready。
|
||||
|
||||
## `emccanon.cc` 分解
|
||||
|
||||
### C1:canon 基础状态和单位转换
|
||||
|
||||
优先函数/变量:
|
||||
|
||||
| 函数/组 | 上游行为 | WASM 实施 |
|
||||
| --- | --- | --- |
|
||||
| `INIT_CANON()`、`ON_RESET()`、`FINISH()` | 初始化 canon、丢弃/flush segments | 先直接迁移或抽取 |
|
||||
| `get_canon()`、`CanonConfig_t canon` | canon 全局状态 | 使用 vendored类型,避免自建 motion plan |
|
||||
| `GET_EXTERNAL_LENGTH_UNITS()`、`GET_EXTERNAL_ANGLE_UNITS()` | 从 motion/task status 取单位 | 接 `EMC_STAT.motion.traj.linearUnits/angularUnits` |
|
||||
| `CANON_UPDATE_END_POINT()` | 更新 canon endpoint | 接 task/motion snapshot |
|
||||
| `SET_G5X_OFFSET()`、`SET_G92_OFFSET()`、`SET_XY_ROTATION()` | 偏置/旋转 | 先保留字段,后续生成 task commands |
|
||||
|
||||
验收:
|
||||
|
||||
- interpreter 执行时 canon endpoint 与 motion snapshot 可同步。
|
||||
- 单位换算不再由 JS/JSON motion plan 决定。
|
||||
|
||||
### C2:直线/圆弧/探测 motion command 生成
|
||||
|
||||
优先函数:
|
||||
|
||||
| 函数 | 上游行为 | WASM 实施 |
|
||||
| --- | --- | --- |
|
||||
| `STRAIGHT_TRAVERSE()` | 生成 `EMC_TRAJ_LINEAR_MOVE` traverse 到 `interp_list` | 第一优先级 |
|
||||
| `STRAIGHT_FEED()` | 通过 segment queue 生成 feed move | 第一优先级 |
|
||||
| `generate_fast_move()`、`generate_move()` | flush 后 append linear move | 作为 STRAIGHT 基础 |
|
||||
| `ARC_FEED()` | 生成 circular move/segments | 第二阶段 |
|
||||
| `STRAIGHT_PROBE()` | 生成 `EMC_TRAJ_PROBE` | 第二阶段 |
|
||||
| `RIGID_TAP()` | 生成 rigid tap | 第二阶段 |
|
||||
| `SET_MOTION_CONTROL_MODE()` | G61/G64 path control | 与 planner/tolerance 验证绑定 |
|
||||
|
||||
依赖 shim:
|
||||
|
||||
- `interp_list`。
|
||||
- `EMC_TRAJ_LINEAR_MOVE`、`EMC_TRAJ_CIRCULAR_MOVE` 等 NML command 类型。
|
||||
- `StateTag`。
|
||||
- velocity/acceleration helpers 的 axis limits 来源。
|
||||
|
||||
验收:
|
||||
|
||||
- G0/G1 文件执行后 `interp_list` 中出现 LinuxCNC `EMC_TRAJ_LINEAR_MOVE`,再由 `emcTaskExecute()` issue。
|
||||
- 不再由 `loadProgramMotionPlan(plan_json)` 提供主路径 motion segments。
|
||||
- line number、motion id、axis endpoint 与 upstream interpreter/canon 输出一致。
|
||||
|
||||
### C3:spindle/tool/io canonical command
|
||||
|
||||
优先函数:
|
||||
|
||||
| 函数组 | 上游行为 | WASM 实施 |
|
||||
| --- | --- | --- |
|
||||
| `DWELL()` | append `EMC_TRAJ_DELAY` | 接 `WAITING_FOR_DELAY` |
|
||||
| `START_SPINDLE_*`、`STOP_SPINDLE_TURNING()`、`SET_SPINDLE_SPEED()` | append spindle commands | 初期 command/event shim |
|
||||
| `ORIENT_SPINDLE()`、`WAIT_SPINDLE_ORIENT_COMPLETE()` | spindle orient wait | 后续接 snapshot |
|
||||
| `SELECT_TOOL()`、`CHANGE_TOOL()`、`CHANGE_TOOL_NUMBER()` | append tool commands | 先支持 T/M6 smoke,再接 IO/tool DB |
|
||||
| `MOTION_OUTPUT_BIT_()`、`MOTION_OUTPUT_VALUE_()` | M62-M68 motion outputs | 优先用于 switchkins |
|
||||
| `WAIT()` | M66 input wait | 后续接 motion `synch_di/analog_input` |
|
||||
|
||||
验收:
|
||||
|
||||
- `M428/M429/M430` 不再 special-case 字符串 MDI,而是通过 remap/canon/MOTION_OUTPUT_VALUE_ 到 motion AOUT。
|
||||
- `DWELL` 进入 task delay state。
|
||||
- tool/spindle runtime boundary 在 readiness 中保持 false,直到有对应验收。
|
||||
|
||||
## 替换任务批次
|
||||
|
||||
| 批次 | 内容 | 退出条件 |
|
||||
| --- | --- | --- |
|
||||
| B1 | taskintf minimal bridge:`emcMotionInit/Update/Abort`、`emcTrajPause/Step/Resume/Abort/LinearMove` | task cycle 内 motion snapshot 和 linear move issue 通过 |
|
||||
| B2 | emctask state/update/abort:`emcTaskAbort/SetMode/SetState/Update` | state/mode/home/run/pause smoke 仍通过,且语义由 task cycle 触发 |
|
||||
| B3 | emctask plan wrapper:`PlanInit/Open/Read/Execute/Synch` | 文件和 MDI 通过 LinuxCNC interpreter/canon 生成 `interp_list` |
|
||||
| B4 | emccanon straight motion:`INIT_CANON/FINISH/STRAIGHT_TRAVERSE/STRAIGHT_FEED` | G0/G1 不再依赖 JSON motion plan |
|
||||
| B5 | task execute issue:`emcTaskExecute()` motion branches + `taskintf` issue | wait/queue/error/top-level status 对标 |
|
||||
| B6 | emccanon MDI/spindle/tool/io 子集 | MDI、switchkins、dwell、basic tool/spindle command 有验收 |
|
||||
|
||||
## 构建策略
|
||||
|
||||
1. 不直接修改 `/home/mes123456/cnc_wams/linuxcnc`。
|
||||
2. 优先 vendored source 或可重复 copy/sync 到 `wasm-port/vendor/linuxcnc`。
|
||||
3. 对 runtime-edge 依赖建立 shim:
|
||||
- `usrmot*` -> `lcmot_*`
|
||||
- NML channels -> in-process command/status buffers
|
||||
- POSIX process/system command -> blocked/shim
|
||||
- IO/tool DB/spindle hardware -> minimal status/command shim
|
||||
4. 每增加一个上游源文件到 build,更新:
|
||||
- `tools/task-hal-source-manifest.txt`
|
||||
- `tools/build_task_hal_wasm.sh`
|
||||
- `docs/source-reuse-map.md`
|
||||
- `working/04-任务矩阵.md`
|
||||
- `working/05-验收证据.md`
|
||||
|
||||
## 禁止路线
|
||||
|
||||
- 不允许继续把 G-code line 文本在 `linuxcnc_task_hal_wasm.cpp` 中手写解析成 motion。
|
||||
- 不允许让 `readStatus()` 触发 motion update 来掩盖 task cycle 缺失。
|
||||
- 不允许把 `nativeTaskReady` 提前置 true。
|
||||
- 不允许绕过 `interp_list` 直接把 `emccanon.cc` 输出改成 JSON。
|
||||
99
wasm-port/working/09-emc_nml复用评估.md
Normal file
99
wasm-port/working/09-emc_nml复用评估.md
Normal file
@@ -0,0 +1,99 @@
|
||||
# 09-emc_nml 复用评估
|
||||
|
||||
## 结论
|
||||
|
||||
T-029 选择:暂不直接 include 完整上游 `emc_nml.hh`,当前阶段采用窄 `StandaloneEmcStatus` / 分阶段 typedef 路线。
|
||||
|
||||
原因:
|
||||
|
||||
- `wasm-port/vendor/linuxcnc/src/emc/nml_intf/` 当前未 vendored `emc_nml.hh`。
|
||||
- 上游 `emc_nml.hh` 不是单纯状态结构头文件,会拉入 NML/CMS command/status message 基类和大量 interpreter/canon 依赖。
|
||||
- 当前 task runtime 已有 T-028 的 `RCS_STATUS` 等价聚合行为,T-007 已建立集中 `StandaloneEmcStatus` 容器;但完整 `emc_nml.hh` 仍需要未 promoted 的 NML/CMS/message runtime 边界,因此不直接 include。
|
||||
- 直接 include 会把未设计的 NML transport、CMS serialization、command message update、RS274 active code arrays、tool/canon table 等边界提前混入 task main loop 迁移。
|
||||
|
||||
## 上游依赖清单
|
||||
|
||||
上游文件:`linuxcnc/src/emc/nml_intf/emc_nml.hh`。
|
||||
|
||||
直接 include 依赖:
|
||||
|
||||
- `linuxcnc.h`
|
||||
- `emcpos.h`
|
||||
- `emc.hh`
|
||||
- `libnml/rcs/rcs.hh`
|
||||
- `libnml/nml/cmd_msg.hh`
|
||||
- `libnml/nml/stat_msg.hh`
|
||||
- `rs274ngc/modal_state.hh`
|
||||
- `canon.hh`
|
||||
- `rs274ngc/rs274ngc.hh`
|
||||
|
||||
这些依赖带来的边界:
|
||||
|
||||
- `RCS_CMD_MSG` / `RCS_STAT_MSG` / `CMS` / `NMLTYPE` message runtime。
|
||||
- `update(CMS *)` serialization hooks。
|
||||
- `CANON_TOOL_TABLE`、`CANON_UNITS`、RS274 active G/M/settings arrays。
|
||||
- full motion/task/io/tool/coolant/aux/spindle status object graph。
|
||||
|
||||
## 需要的状态子集
|
||||
|
||||
当前 T-028 已闭合的最小状态字段:
|
||||
|
||||
| 领域 | 当前字段 | LinuxCNC 对应概念 |
|
||||
| --- | --- | --- |
|
||||
| top | `top_level_rcs_status` | `EMC_STAT.status` |
|
||||
| task | `task_rcs_status` | `EMC_STAT.task.status` |
|
||||
| task | `state`、`mode`、`exec_state`、`interp_state` | `EMC_TASK_STAT.state/mode/execState/interpState` |
|
||||
| motion | `motion_rcs_status`、`LcmotStatusSnapshot.status` | `EMC_STAT.motion.status` |
|
||||
| motion.traj | queue、queueFull、in_position、paused、stepping、motion_id | `EMC_TRAJ_STAT` queue/inpos/pause/id 字段族 |
|
||||
| motion | `on_soft_limit` | `EMC_MOTION_STAT.on_soft_limit` |
|
||||
| io | `io_rcs_status`、`io_error` | `EMC_STAT.io.status` |
|
||||
|
||||
## 选择
|
||||
|
||||
采用分阶段 typedef / 窄 status 容器:
|
||||
|
||||
1. T-007 已建立 `StandaloneEmcStatus`,集中承载 task/motion/io/top-level 必需字段。
|
||||
2. 字段命名和 JSON 导出继续对齐 `EMC_STAT`、`EMC_TASK_STAT`、`EMC_MOTION_STAT`、`EMC_TRAJ_STAT`、`EMC_IO_STAT`。
|
||||
3. `RCS_STATUS` 暂以 `"DONE"`、`"EXEC"`、`"ERROR"` 字符串导出,内部可在 T-030/T-032 后替换为窄 enum。
|
||||
4. T-032+ 建立 usrmot/NML shim 后,再评估是否 vendor `emc_nml.hh` 及其必要依赖,或只 vendor 一个由上游字段映射驱动的 status subset header。
|
||||
|
||||
## 不采用的方案
|
||||
|
||||
### 直接 include 完整 `emc_nml.hh`
|
||||
|
||||
暂不采用。
|
||||
|
||||
阻塞项:
|
||||
|
||||
- `emc_nml.hh` 未在 vendor tree 中。
|
||||
- 直接 include 需要引入 `libnml`、CMS、RS274、canon 依赖链。
|
||||
- 完整类中大量 `update(CMS *)` 和 message 构造路径超出当前 WASM task runtime 边界。
|
||||
- 会让 T-028 已闭合的 status 聚合和后续 T-032/T-040 的 runtime edge 纠缠。
|
||||
|
||||
### 只扩展现有 `runtime/core/shims/nml_intf/emc.hh`
|
||||
|
||||
仅作为短期兼容,不作为 T-029 结论。
|
||||
|
||||
现有 shim 只服务解释器单位字段和 source probe:
|
||||
|
||||
- `EMC_STAT.motion.traj.linearUnits`
|
||||
- `EmcJointType`
|
||||
- `extern EMC_STAT *emcStatus`
|
||||
|
||||
继续无限扩展该 shim 会让 interpreter 单位兼容层和 task status 容器混在一起。
|
||||
|
||||
## 后续入口
|
||||
|
||||
- T-007:已建立集中 `StandaloneEmcStatus`。
|
||||
- T-030:更新 source reuse map 与 drift 文档,记录本 T-029 决策。
|
||||
- T-032:设计 `taskintf.cc` usrmot shim,明确 NML/transport 仍是 runtime boundary。
|
||||
- T-033/T-038:把 motion update 和 task update 映射到 `StandaloneEmcStatus` 字段。
|
||||
|
||||
## 验收
|
||||
|
||||
T-029 的验收由 `tools/verify_task_emc_nml_reuse_plan.sh` 固定:
|
||||
|
||||
- 上游 `emc_nml.hh` 存在。
|
||||
- 当前 vendor tree 未声称完整 `emc_nml.hh` 已 vendored。
|
||||
- 本文记录直接 include 依赖、阻塞项和最终选择。
|
||||
- 任务矩阵将 T-029 标为完成。
|
||||
191
wasm-port/working/10-taskintf-usrmot-shim设计.md
Normal file
191
wasm-port/working/10-taskintf-usrmot-shim设计.md
Normal file
@@ -0,0 +1,191 @@
|
||||
# 10-taskintf usrmot shim 设计
|
||||
|
||||
## 目标
|
||||
|
||||
T-032 定义 `taskintf.cc` 在 WASM 中继续保留的 usrmot 语义边界,以及这些边界如何落到 standalone `lcmot_*` runtime。目标是给 T-033 之后的实现提供窄 shim 合同,而不是在本阶段直接编译完整 `linuxcnc/src/emc/motion/usrmotintf.cc`。
|
||||
|
||||
上游锚点:
|
||||
|
||||
- `linuxcnc/src/emc/motion/usrmotintf.h`
|
||||
- `linuxcnc/src/emc/motion/usrmotintf.cc`
|
||||
- `linuxcnc/src/emc/task/taskintf.cc`
|
||||
|
||||
WASM runtime 锚点:
|
||||
|
||||
- `runtime/core/linuxcnc_wrap/linuxcnc_motion_runtime.h`
|
||||
- `runtime/core/linuxcnc_wrap/linuxcnc_motion_runtime.c`
|
||||
- `vendor/linuxcnc/src/emc/task/taskintf_wasm_subset.hh`
|
||||
- `vendor/linuxcnc/src/emc/task/taskintf_wasm_subset.cc`
|
||||
|
||||
## 不直接复用完整 `usrmotintf.cc`
|
||||
|
||||
完整上游 `usrmotintf.cc` 绑定 native shared memory、mutex、command ack 轮询、split read、error ring buffer、RTAPI init/exit 和 compensation file loading。WASM 当前 motion runtime 是同进程 standalone C ABI,不存在上游共享内存段,也没有 native emcmot process ack 通道。
|
||||
|
||||
因此 T-032 采用一个窄 usrmot shim:
|
||||
|
||||
```text
|
||||
taskintf.cc-compatible calls
|
||||
-> wasm usrmot shim
|
||||
-> lcmot_* C ABI
|
||||
-> standalone motion runtime
|
||||
```
|
||||
|
||||
shim 必须保留上游函数的返回值语义,但只能承诺当前 `lcmot_*` 已有或明确新增的能力。
|
||||
|
||||
## 映射总表
|
||||
|
||||
| usrmot 边界 | 上游行为 | WASM shim 映射 | 当前状态 |
|
||||
| --- | --- | --- | --- |
|
||||
| `usrmotIniLoad(file)` | 读取 INI 中的 motion shared memory key、timeout 等 | 只保存 `ini_path`,等待 `usrmotInit()` 调用 `lcmot_init_from_ini(ini_path, ini_text)` | 需要 shim 缓存 staged INI text |
|
||||
| `usrmotInit(name)` | 连接 native emcmot shared memory | 初始化 standalone motion runtime;映射到 `lcmot_init_from_ini()` | 已有底层 ABI |
|
||||
| `usrmotExit()` | 断开 native emcmot shared memory/RTAPI | 映射到 `lcmot_reset()`;不退出 WASM runtime | 已有底层 ABI |
|
||||
| `usrmotWriteEmcmotCommand(c)` | 写 `emcmot_command_t`,等待 `commandNumEcho` ack | 将 taskintf 命令转换为 `lcmot_write_command_json()` 可接受的 command JSON | 已有底层 ABI,ack 语义需降级 |
|
||||
| `usrmotReadEmcmotStatus(s)` | split-read 复制 `emcmot_status_t` | 映射 `lcmot_read_status_snapshot()` 到窄 `emcmot_status_t`/`EMC_MOTION_STAT` subset | 已有底层 ABI |
|
||||
| `usrmotReadEmcmotConfig(s)` | split-read 复制 `emcmot_config_t` | 新增 `lcmot_read_config_snapshot()`,输出 axes/joints/queue/config_num/limits/default units 等窄 config subset | T-033 已实现窄底层 ABI |
|
||||
| `usrmotReadEmcmotInternal(s)` | 读取 debug/internal shared memory | 第一阶段返回空 internal subset;后续可新增 `lcmot_read_internal_snapshot()` | 非 T-032 必需 |
|
||||
| `usrmotReadEmcmotError(e)` | 从 motion error ring 取最早错误 | 新增 `lcmot_read_error_message(char *out, int out_len)` 或等价 JSON/error buffer API | T-033 已实现窄 error message queue |
|
||||
| `usrmotLoadComp()` / `usrmotPrintComp()` | joint compensation 文件 IO | 暂不支持;返回 `EMCMOT_COMM_ERROR_COMMAND` 或独立 unsupported code | 后续 joint compensation 批次处理 |
|
||||
|
||||
## command write
|
||||
|
||||
上游 `usrmotWriteEmcmotCommand(emcmot_command_t *c)` 做三件事:
|
||||
|
||||
1. 校验 motion id。
|
||||
2. 写入 shared memory command slot。
|
||||
3. 轮询 `usrmotReadEmcmotStatus()`,等待 `commandNumEcho` 和 `commandStatus`。
|
||||
|
||||
WASM shim 的 T-033 最小实现合同:
|
||||
|
||||
```text
|
||||
usrmotWriteEmcmotCommand(c)
|
||||
-> validate supported command and motion id
|
||||
-> convert emcmot_command_t to taskintf/lcmot command JSON
|
||||
-> lcmot_write_command_json(json)
|
||||
-> return EMCMOT_COMM_OK on accepted enqueue
|
||||
```
|
||||
|
||||
返回值映射:
|
||||
|
||||
| 条件 | 返回值 |
|
||||
| --- | --- |
|
||||
| command 转换成功且 `lcmot_write_command_json()` 返回 0 | `EMCMOT_COMM_OK` |
|
||||
| command unsupported、queue full、字段非法 | `EMCMOT_COMM_ERROR_COMMAND` |
|
||||
| runtime 未初始化 | `EMCMOT_COMM_ERROR_CONNECT` |
|
||||
| motion id 为 invalid sentinel | `EMCMOT_COMM_INVALID_MOTION_ID` |
|
||||
| in-process WASM runtime 无 ack 通道 | 不使用 `EMCMOT_COMM_ERROR_TIMEOUT`,除非后续引入 command ack |
|
||||
|
||||
现有 `taskintf_wasm_subset` 已覆盖的 command family:
|
||||
|
||||
- `emcTrajAbort()` / `EMCMOT_ABORT`
|
||||
- `emcTrajPause()` / `EMCMOT_PAUSE`
|
||||
- `emcTrajStep()` / `EMCMOT_STEP`
|
||||
- `emcTrajResume()` / `EMCMOT_RESUME`
|
||||
- `emcTrajLinearMove()` / `EMCMOT_SET_LINE`
|
||||
- `emcJogIncr()` / `EMCMOT_JOG_INCR`
|
||||
- `emcJointHome()` / homing command envelope
|
||||
- `emcMotionSetAout()` / `EMCMOT_SET_AOUT`
|
||||
|
||||
后续 T-034 到 T-036 可以把这些 command family 从 JSON 拼接继续收缩到 `emcmot_command_t -> shim -> lcmot` 的窄转换层。
|
||||
|
||||
## status read
|
||||
|
||||
上游 `usrmotReadEmcmotStatus(emcmot_status_t *s)` 是 split-read,只复制 shared memory,不推进 servo。WASM 语义必须保持这一点:
|
||||
|
||||
```text
|
||||
usrmotReadEmcmotStatus(s)
|
||||
-> lcmot_read_status_snapshot(&snapshot)
|
||||
-> map snapshot to status subset
|
||||
-> return EMCMOT_COMM_OK
|
||||
```
|
||||
|
||||
硬性约束:
|
||||
|
||||
- 不调用 `lcmot_step_servo()`。
|
||||
- 不消费 motion command queue。
|
||||
- 不调用 `lctask_run_cycles()`。
|
||||
- 不从 JSON status 反向解析。
|
||||
- `status`、`in_position`、`queue_full`、`queue_count`、`motion_id`、`program_line`、`axis_cmd/fb`、`joint_cmd/fb`、`motion_error`、`on_soft_limit` 必须来自 `LcmotStatusSnapshot`。
|
||||
|
||||
`LcmotStatusSnapshot.status` 到 RCS 子状态的第一阶段映射:
|
||||
|
||||
| `LcmotStatusSnapshot.status` | 语义 |
|
||||
| --- | --- |
|
||||
| `0` | motion DONE |
|
||||
| `1` | motion EXEC |
|
||||
| `2` | motion ERROR |
|
||||
|
||||
## config read
|
||||
|
||||
上游 `usrmotReadEmcmotConfig(emcmot_config_t *s)` 读取 config shared memory,并依赖 `head == tail` 的 split-read 稳定性。当前 `lcmot_*` 只有 `lcmot_init_from_ini()`,没有 config snapshot read API。
|
||||
|
||||
T-032 设计结论:
|
||||
|
||||
```text
|
||||
usrmotReadEmcmotConfig(s)
|
||||
-> lcmot_read_config_snapshot(&config)
|
||||
-> map config to emcmot_config_t subset
|
||||
```
|
||||
|
||||
T-033 已新增窄实现:
|
||||
|
||||
```c
|
||||
typedef struct {
|
||||
int config_num;
|
||||
int axes;
|
||||
int joints;
|
||||
int queue_capacity;
|
||||
double linear_units;
|
||||
double angular_units;
|
||||
double axis_min_limit[LCMOT_MAX_AXES];
|
||||
double axis_max_limit[LCMOT_MAX_AXES];
|
||||
} LcmotConfigSnapshot;
|
||||
|
||||
int lcmot_read_config_snapshot(LcmotConfigSnapshot *snapshot);
|
||||
```
|
||||
|
||||
如果后续替换或重命名该 API,shim 不能假装 `usrmotReadEmcmotConfig()` 已支持。允许的临时行为只有:
|
||||
|
||||
- task 初始化阶段使用 `lcmot_init_from_ini()` 建立 runtime defaults。
|
||||
- `emcMotionUpdate()` 遇到 config read 需求时返回错误,保持 readiness false。
|
||||
- 文档和验证脚本继续记录 config read 是窄 runtime-edge ABI,不是 native shared-memory config promotion。
|
||||
|
||||
## error read
|
||||
|
||||
上游 `usrmotReadEmcmotError(char *e)` 从 motion error ring 取最早错误字符串。当前 `LcmotStatusSnapshot` 只有 `motion_error` 和 `on_soft_limit` 标志,不能替代错误队列。
|
||||
|
||||
T-032 设计结论:
|
||||
|
||||
```text
|
||||
usrmotReadEmcmotError(e)
|
||||
-> lcmot_read_error_message(e, EMCMOT_ERROR_LEN)
|
||||
```
|
||||
|
||||
T-033 已新增窄实现:
|
||||
|
||||
```c
|
||||
int lcmot_read_error_message(char *out, int out_len);
|
||||
```
|
||||
|
||||
行为合同:
|
||||
|
||||
- 有错误消息时返回 0,并复制最早错误。
|
||||
- 无错误消息时返回 -1,匹配上游 “no error” 分支。
|
||||
- `EMCMOT_INJECT_ERROR`、soft-limit、abort cleanup 写入该 error buffer。
|
||||
- status flag 仍来自 `lcmot_read_status_snapshot()`,错误文本只通过 error read 消费。
|
||||
|
||||
## T-033 实施入口
|
||||
|
||||
1. T-033 已在 `taskintf_wasm_subset` 中新增 `lc_taskintf_subset_motion_init()`、`lc_taskintf_subset_motion_update()`、`lc_taskintf_subset_motion_abort()`。
|
||||
2. T-033 已新增 `lcmot_read_config_snapshot()` 与 `lcmot_read_error_message()`。
|
||||
3. T-033 已让 `lctask_init_session()`、task-cycle motion update 和 task abort path 通过 shim 访问 motion runtime。
|
||||
4. 继续保持 task status read 和 motion status read 的周期隔离:外部 `lctask_read_status_json()` 不触发新的 motion update。
|
||||
5. T-034+ 可继续把 traj control command family 从 envelope 迁到更完整的 usrmot command conversion。
|
||||
|
||||
## 禁止路线
|
||||
|
||||
- 不把完整 `usrmotintf.cc` 直接加入 WASM build。
|
||||
- 不用 `lcmot_read_status_json()` 反解析生成 `emcmot_status_t`。
|
||||
- 不让 status read 推进 servo 或 task cycle。
|
||||
- 不把 config read 映射成 HAL snapshot。
|
||||
- 不把 `motion_error` boolean 当成 `usrmotReadEmcmotError()` 的错误队列。
|
||||
- 不把 T-032/T-033 的 usrmot shim 解释为 `nativeTaskReady=true` 或 `nativeHalSyncReady=true`。
|
||||
82
wasm-port/working/11-WASM核心状态机边界与后续完善路线.md
Normal file
82
wasm-port/working/11-WASM核心状态机边界与后续完善路线.md
Normal file
@@ -0,0 +1,82 @@
|
||||
# 11-WASM核心状态机边界与后续完善路线
|
||||
|
||||
## 目标
|
||||
|
||||
本文件固定后续完善 `wasm-port` 程序时的边界:WASM/C++ 程序作为核心状态机实现的运行载体,JS/SDK 和 JSON 只承担 host/browser 边界职责。
|
||||
|
||||
后续新增代码任务前,必须先把对应任务补入 `04-任务矩阵.md`,写明验收标准和 gate,再按本文件推进。
|
||||
|
||||
## 分层边界
|
||||
|
||||
| 层 | 职责 | 不应承担 |
|
||||
| --- | --- | --- |
|
||||
| WASM/C++ | LinuxCNC 语义复用、task/motion 核心状态机、task cycle、motion snapshot、command read/plan/execute、RCS 聚合、`StandaloneEmcStatus` | 浏览器 UI 状态、DOM、OPFS 业务流程、JSON 文本状态机 |
|
||||
| JS/SDK | 加载 WASM、管理 Emscripten FS/OPFS 边界、传入 command JSON、读取 status JSON、提供测试和 UI 友好 API | G-code 语义、task/motion 状态机、LinuxCNC planner/canon 语义 |
|
||||
| JSON | host 与 WASM 的输入/输出通信格式,例如 `lctask_send_command_json()` 和 `lctask_read_status_json()` | 保存事实状态、推进 task 周期、执行 motion 语义、替代结构体状态 |
|
||||
|
||||
## 核心原则
|
||||
|
||||
1. `lctask_run_cycles()` 是 task 状态变化的主入口。
|
||||
2. `lctask_send_command_json()` 只入队 host command,不直接改变 LinuxCNC task/motion 语义状态。
|
||||
3. `lctask_read_status_json()` 只导出最后一次 status write,不推进 cycle、不重新读取 motion、不触发 command 执行。
|
||||
4. 核心状态保存在 C/C++ 结构体、枚举、队列和周期函数中;当前集中容器为 `StandaloneEmcStatus`。
|
||||
5. motion 状态通过 `LcmotStatusSnapshot` 在 task 周期内读入,再映射到 `StandaloneEmcStatus.motion`。
|
||||
6. JSON 字段可以兼容旧 SDK/UI,但必须从核心结构体导出,不能成为新的事实源。
|
||||
7. 若 LinuxCNC 上游源码已有对应语义,优先接入 vendored source 或窄 shim,不在 JS/JSON 中重写。
|
||||
|
||||
## 当前事实源
|
||||
|
||||
当前阶段的事实源如下:
|
||||
|
||||
- task cycle skeleton:`linuxcnc_task_hal_wasm.cpp` 中的 command read、plan、execute、motion update、subordinate sync、task update、status write。
|
||||
- task/motion/io/top status:`StandaloneEmcStatus`。
|
||||
- motion runtime snapshot:`LcmotStatusSnapshot` 和 `lcmot_read_status_snapshot()`。
|
||||
- RUN 主路径:staged program -> `emcTaskPlanRead()` -> `emcTaskPlanCommand()` -> `emcTaskPlanExecute()` -> `emccanon.cc` command envelope -> `taskintf.cc` motion issue。
|
||||
- JSON status:`statusSource=StandaloneEmcStatus` 的外部导出视图。
|
||||
|
||||
status JSON 的 LinuxCNC `EMC_STAT` 字段映射、兼容策略和后续 SJ 批次见 `12-status-json-LinuxCNC对标方案.md`。
|
||||
|
||||
当前 `12-status-json-LinuxCNC对标方案.md` 中 SJ-1 到 SJ-5 已补入 `04-任务矩阵.md` 的 T-051 到 T-055,并已闭合。后续不得再只用“后续路线”描述实际任务;凡是出现可执行实现项,必须同步进入任务矩阵。
|
||||
|
||||
## 后续完善路线
|
||||
|
||||
后续 WASM 程序完善应按以下顺序拆成新任务:
|
||||
|
||||
1. 扩展 `StandaloneEmcStatus` 字段覆盖,而不是扩展 status JSON 自有字段。
|
||||
2. 将更多 `TaskRuntime` 分散字段迁移到 task/motion/io/top status 容器。
|
||||
3. 继续把 plan/execute 分支替换为 vendored `emctask.cc`、`taskintf.cc`、`emccanon.cc` 的 source-anchored 子集。
|
||||
4. 扩展 `taskintf.cc` usrmot shim,使 motion command/status/config/error 的映射更接近上游。
|
||||
5. 评估 `emc_nml.hh` 的分阶段 typedef 或窄编译复用,但不得为了 readiness 提前引入完整 native NML/process topology。
|
||||
6. 将新增状态字段同步补齐 WASM smoke、SDK smoke、state matrix 和 source reuse/drift docs gate。
|
||||
7. 只有在完整 native task/HAL/runtime 边界被实际采用并验证后,才能提升 `nativeTaskReady`、`nativeHalSyncReady` 或 `fullLinuxCncProgramExecutionReady`。
|
||||
|
||||
本轮已闭合的 status JSON 子任务:
|
||||
|
||||
- T-051 / SJ-1:`emcStatus.motion.traj`。
|
||||
- T-052 / SJ-2:task current/read/motion line 和 call level。
|
||||
- T-053 / SJ-3:`emcStatus.motion.axis[]` 与 `joint[]`。
|
||||
- T-054 / SJ-4:`emcStatus.io.aux/tool/coolant` 窄边界。
|
||||
- T-055 / SJ-5:`tools/verify_task_status_json_contract.sh`。
|
||||
|
||||
## 代码修改检查清单
|
||||
|
||||
每次按本路线改 WASM runtime 时,至少检查:
|
||||
|
||||
- 新状态是否有 C/C++ 结构体字段,而不是只新增 JSON 字段。
|
||||
- 新 command 是否先入队,再由 `lctask_run_cycles()` 消费。
|
||||
- 新 status JSON 字段是否从 `StandaloneEmcStatus` 或明确的 C/C++ status buffer 导出。
|
||||
- JS/SDK 是否只做边界包装和兼容 API。
|
||||
- 是否新增或更新 `tools/verify_task_*` gate。
|
||||
- 是否同步更新 `03-推进台账.md`、`05-验收证据.md`、`06-决策记录.md`。
|
||||
|
||||
## 验收要求
|
||||
|
||||
后续实现任务完成时,至少运行:
|
||||
|
||||
```bash
|
||||
cd /home/mes123456/cnc_wams/wasm-port
|
||||
./tools/verify_task_full_closure.sh
|
||||
git diff --check
|
||||
```
|
||||
|
||||
如任务新增专用 gate,应先运行专用 gate,再运行 full closure gate。
|
||||
242
wasm-port/working/12-status-json-LinuxCNC对标方案.md
Normal file
242
wasm-port/working/12-status-json-LinuxCNC对标方案.md
Normal file
@@ -0,0 +1,242 @@
|
||||
# 12-status JSON LinuxCNC对标方案
|
||||
|
||||
## 目标
|
||||
|
||||
本方案用于后续在 WASM 中完善 `status JSON`:对标 LinuxCNC 的 `EMC_STAT` / status buffer 模型,在 WASM/C++ 内维护结构化 status 事实源,再把最后一次 status write 序列化为 JSON 给 JS/SDK/UI 读取。
|
||||
|
||||
`status JSON` 不是 LinuxCNC 语义实现层。它是浏览器/Node host 无法直接读取 native NML/CMS status channel 时的外部通信格式。
|
||||
|
||||
## LinuxCNC对标基线
|
||||
|
||||
上游 LinuxCNC 的 status 模型来自:
|
||||
|
||||
- `/home/mes123456/cnc_wams/linuxcnc/src/emc/nml_intf/emc.hh`
|
||||
- 定义 `EMC_TASK_MODE`、`EMC_TASK_STATE`、`EMC_TASK_EXEC`、`EMC_TASK_INTERP`、`EMC_TRAJ_MODE` 等枚举。
|
||||
- 定义 `EMC_STAT_TYPE`、`EMC_TASK_STAT_TYPE`、`EMC_MOTION_STAT_TYPE`、`EMC_IO_STAT_TYPE` 等 NML 类型编号。
|
||||
- `/home/mes123456/cnc_wams/linuxcnc/src/emc/nml_intf/emc_nml.hh`
|
||||
- `EMC_STAT` 聚合 `EMC_TASK_STAT task`、`EMC_MOTION_STAT motion`、`EMC_IO_STAT io`。
|
||||
- `EMC_TASK_STAT` 保存 task mode/state、exec/interp state、program line、file、active G/M code、offset、program units、pause 等状态。
|
||||
- `EMC_MOTION_STAT` 保存 `EMC_TRAJ_STAT traj`、joint、axis、spindle、synch IO、analog IO、soft limit、heartbeat 等状态。
|
||||
- `EMC_TRAJ_STAT` 保存 enabled、inpos、queue、activeQueue、queueFull、id、paused、single_stepping、position、actualPosition、current_vel、probe、kinematics 等轨迹状态。
|
||||
- `EMC_IO_STAT` 保存 tool、coolant、aux、fault/reason 等 IO 状态。
|
||||
|
||||
上游 GUI 读取的是 status channel 中的 `EMC_STAT` 快照,不是在 GUI 层重建 task/motion 状态机。WASM 中的 JSON 应只模拟“读 status channel 后得到可展示快照”的边界。
|
||||
|
||||
## WASM中的等价模型
|
||||
|
||||
当前 WASM 侧已建立:
|
||||
|
||||
- `StandaloneEmcStatus`
|
||||
- `StandaloneEmcTaskStatus`
|
||||
- `StandaloneEmcMotionStatus`
|
||||
- `StandaloneEmcIoStatus`
|
||||
- `write_status_snapshot()`
|
||||
- `lctask_read_status_json()`
|
||||
|
||||
后续完善时采用以下固定链路:
|
||||
|
||||
```text
|
||||
LinuxCNC source semantics
|
||||
-> WASM/C++ task cycle
|
||||
-> LcmotStatusSnapshot
|
||||
-> StandaloneEmcStatus
|
||||
-> write_status_snapshot()
|
||||
-> lctask_read_status_json()
|
||||
-> JS/SDK/UI
|
||||
```
|
||||
|
||||
禁止以下链路:
|
||||
|
||||
```text
|
||||
motion JSON -> parse -> task state
|
||||
status JSON -> parse -> task/motion state
|
||||
JS/SDK -> compute LinuxCNC task/motion semantics
|
||||
lctask_read_status_json() -> step servo / read fresh motion / consume command
|
||||
```
|
||||
|
||||
## status JSON职责
|
||||
|
||||
`status JSON` 只承担四类职责:
|
||||
|
||||
1. 把最后一次 `write_status_snapshot()` 中的状态导出给 JS/SDK/UI。
|
||||
2. 给浏览器 UI 提供稳定、可版本化、可兼容的字段名。
|
||||
3. 给 Node/WASM/browser 测试提供可断言的观察面。
|
||||
4. 保留旧 SDK/UI 兼容字段,同时新增更接近 `EMC_STAT` 的 `emcStatus` 对象。
|
||||
|
||||
`status JSON` 不承担:
|
||||
|
||||
- task 状态机事实源。
|
||||
- motion 状态机事实源。
|
||||
- LinuxCNC planner/canon/interpreter 语义。
|
||||
- queueFull、inpos、abort、estop、pause/resume/step 等语义判断。
|
||||
|
||||
## 推荐JSON结构
|
||||
|
||||
顶层保留 runtime/readiness 和兼容字段,同时以 `emcStatus` 作为 LinuxCNC 对标主对象:
|
||||
|
||||
```json
|
||||
{
|
||||
"statusSource": "StandaloneEmcStatus",
|
||||
"schemaVersion": 1,
|
||||
"taskTopLevelStatus": "DONE",
|
||||
"rcsStatus": {
|
||||
"top": "DONE",
|
||||
"task": "DONE",
|
||||
"motion": "DONE",
|
||||
"io": "DONE"
|
||||
},
|
||||
"task": {},
|
||||
"motionStatus": {},
|
||||
"emcStatus": {
|
||||
"source": "StandaloneEmcStatus",
|
||||
"top": { "status": "DONE" },
|
||||
"task": {},
|
||||
"motion": {},
|
||||
"io": {}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
要求:
|
||||
|
||||
- `task` 和 `motionStatus` 是兼容视图,字段必须来自 `emcStatus` 或同一份 C/C++ status buffer。
|
||||
- `emcStatus` 是后续新增 LinuxCNC 对标字段的默认入口。
|
||||
- 新字段优先落在 `emcStatus.task`、`emcStatus.motion.traj`、`emcStatus.motion.joint[]`、`emcStatus.motion.axis[]`、`emcStatus.io` 中。
|
||||
- 若必须保留旧字段名,应在测试中断言旧字段与 `emcStatus` 同源一致。
|
||||
|
||||
## 字段映射方案
|
||||
|
||||
| LinuxCNC字段 | WASM事实源 | JSON位置 | 状态 |
|
||||
| --- | --- | --- | --- |
|
||||
| `EMC_STAT.status` / top RCS status | `StandaloneEmcStatus.top_rcs_status` | `emcStatus.top.status`、`taskTopLevelStatus`、`rcsStatus.top` | 已有 |
|
||||
| `EMC_STAT.task.status` | `StandaloneEmcTaskStatus.rcs_status` | `emcStatus.task.status`、`task.status`、`rcsStatus.task` | 已有 |
|
||||
| `EMC_STAT.task.state` | `StandaloneEmcTaskStatus.state` | `emcStatus.task.state`、`task.state` | 已有 |
|
||||
| `EMC_STAT.task.mode` | `StandaloneEmcTaskStatus.mode` | `emcStatus.task.mode`、`task.mode` | 已有 |
|
||||
| `EMC_STAT.task.execState` | `StandaloneEmcTaskStatus.exec_state` | `emcStatus.task.execState`、`task.execState` | 已有 |
|
||||
| `EMC_STAT.task.interpState` | `StandaloneEmcTaskStatus.interp_state` | `emcStatus.task.interpState`、`task.interpState` | 已有 |
|
||||
| `EMC_STAT.task.task_paused` | `StandaloneEmcTaskStatus.task_paused` | `emcStatus.task.taskPaused`、`task.taskPaused` | 已有 |
|
||||
| `EMC_STAT.task.file` | `StandaloneEmcTaskStatus.open_program` | `emcStatus.task.file`、`task.file` | 已有 |
|
||||
| `EMC_STAT.task.currentLine/readLine/motionLine` | staged interpreter + motion snapshot | `emcStatus.task.currentLine/readLine/motionLine` | 已有 |
|
||||
| `EMC_STAT.task.activeGCodes/activeMCodes/activeSettings` | vendored interpreter/canon state | `emcStatus.task.activeGCodes/activeMCodes/activeSettings` | 后续 |
|
||||
| `EMC_STAT.task.g5x_offset/g92_offset/toolOffset` | vendored interpreter/canon state | `emcStatus.task.offsets` | 后续 |
|
||||
| `EMC_STAT.motion.status` | `StandaloneEmcMotionStatus.rcs_status` | `emcStatus.motion.status`、`rcsStatus.motion` | 已有 |
|
||||
| `EMC_STAT.motion.traj.enabled` | `LcmotStatusSnapshot.motion_enabled` | `emcStatus.motion.traj.enabled` | 已有 |
|
||||
| `EMC_STAT.motion.traj.inpos` | `LcmotStatusSnapshot.in_position` | `emcStatus.motion.traj.inpos` | 已有 |
|
||||
| `EMC_STAT.motion.traj.queue` | `LcmotStatusSnapshot.queue_count` | `emcStatus.motion.traj.queue` | 已有 |
|
||||
| `EMC_STAT.motion.traj.activeQueue` | `LcmotStatusSnapshot.active_depth` | `emcStatus.motion.traj.activeQueue` | 已有 |
|
||||
| `EMC_STAT.motion.traj.queueFull` | `LcmotStatusSnapshot.queue_full` | `emcStatus.motion.traj.queueFull` | 已有 |
|
||||
| `EMC_STAT.motion.traj.id` | `LcmotStatusSnapshot.motion_id` | `emcStatus.motion.traj.id` | 已有 |
|
||||
| `EMC_STAT.motion.traj.paused` | `LcmotStatusSnapshot.paused` | `emcStatus.motion.traj.paused` | 已有 |
|
||||
| `EMC_STAT.motion.traj.single_stepping` | `LcmotStatusSnapshot.stepping` | `emcStatus.motion.traj.singleStepping` | 已有 |
|
||||
| `EMC_STAT.motion.traj.position/actualPosition` | `LcmotStatusSnapshot.axis_cmd/axis_fb` | `emcStatus.motion.traj.position/actualPosition` | 已有 |
|
||||
| `EMC_STAT.motion.traj.current_vel` | `LcmotStatusSnapshot.current_vel` | `emcStatus.motion.traj.currentVel` | 已有 |
|
||||
| `EMC_STAT.motion.on_soft_limit` | `LcmotStatusSnapshot.on_soft_limit` | `emcStatus.motion.onSoftLimit` | 已有 |
|
||||
| `EMC_STAT.motion.joint[]` | `LcmotStatusSnapshot.joint_cmd/joint_fb` | `emcStatus.motion.joint[]` | 已有 |
|
||||
| `EMC_STAT.motion.axis[]` | `LcmotStatusSnapshot.axis_cmd/axis_fb` | `emcStatus.motion.axis[]` | 已有 |
|
||||
| `EMC_STAT.io.status` | `StandaloneEmcIoStatus.rcs_status` | `emcStatus.io.status`、`rcsStatus.io` | 已有 |
|
||||
| `EMC_STAT.io.aux.estop` | task/io shim | `emcStatus.io.aux.estop` | 已有 |
|
||||
| `EMC_STAT.io.fault/reason` | `StandaloneEmcIoStatus.error/reason` | `emcStatus.io.fault/reason` | 已有 |
|
||||
|
||||
## 后续实施批次
|
||||
|
||||
### SJ-1:规范 `emcStatus.motion.traj`
|
||||
|
||||
状态:已完成,对应 T-051。
|
||||
|
||||
目标:把当前 `motionStatus.motion.*` 中已有的 queue、inpos、id、paused、stepping、currentVel 等字段,以 LinuxCNC `EMC_TRAJ_STAT` 名称归入 `emcStatus.motion.traj`。
|
||||
|
||||
验收:
|
||||
|
||||
- `emcStatus.motion.traj.queue` 等于兼容字段 `motionStatus.motion.queueDepth`。
|
||||
- `emcStatus.motion.traj.inpos` 等于兼容字段 `motionStatus.motion.inPosition`。
|
||||
- `emcStatus.motion.traj.id` 等于兼容字段 `motionStatus.motion.id`。
|
||||
- `lctask_read_status_json()` 不新增 motion read 或 servo step。
|
||||
|
||||
### SJ-2:规范 task line 和 interpreter字段
|
||||
|
||||
状态:已完成,对应 T-052。active G/M code、active settings 和 offsets 仍按字段映射表保留为后续 source-anchored 扩展,不计入本 SJ-2 验收。
|
||||
|
||||
目标:对齐 `EMC_TASK_STAT.currentLine`、`readLine`、`motionLine`、`callLevel`,让 UI 和测试能分辨 interpreter 已读行、当前执行行和 motion 正在执行行。
|
||||
|
||||
验收:
|
||||
|
||||
- staged program RUN 后,`emcStatus.task.readLine/currentLine/motionLine` 与现有 plan read/execute/motion id evidence 一致。
|
||||
- 兼容字段若存在,必须与 `emcStatus.task.*Line` 同源。
|
||||
|
||||
### SJ-3:规范 `motion.axis[]` 和 `motion.joint[]`
|
||||
|
||||
状态:已完成,对应 T-053。`emcStatus.motion.axis` 和 `emcStatus.motion.joint` 为数组;按名字访问的兼容视图保留在 `motionStatus.axis`,`emcStatus.motion.axisByName` 仅辅助迁移。
|
||||
|
||||
目标:把当前 axis x/y/z/a/b/c 和 joint0 字段扩展成数组结构,对标 `EMC_MOTION_STAT.axis[]` 和 `joint[]`。
|
||||
|
||||
验收:
|
||||
|
||||
- 至少导出存在的 5/6 轴位置和 joint0 command/feedback。
|
||||
- 旧 `motionStatus.axis`、`motionStatus.joint0` 与新数组值一致。
|
||||
|
||||
### SJ-4:规范 IO/aux/tool/coolant边界
|
||||
|
||||
状态:已完成,对应 T-054。tool/coolant 只暴露 shim/unsupported 边界,不提升 native IO readiness。
|
||||
|
||||
目标:将当前 IO shim 状态组织为 `emcStatus.io.aux`、`emcStatus.io.tool`、`emcStatus.io.coolant` 的窄对象,未实现字段显式标记为 shim/unsupported,而不是省略成语义完成。
|
||||
|
||||
验收:
|
||||
|
||||
- `emcStatus.io.status`、`fault`、`reason`、`aux.estop` 可观测。
|
||||
- readiness 仍保持 false,不因 JSON 字段存在而宣称 native IO ready。
|
||||
|
||||
### SJ-5:引入 schema gate
|
||||
|
||||
状态:已完成,对应 T-055。
|
||||
|
||||
目标:新增专用 gate,例如 `tools/verify_task_status_json_contract.sh`,固定 status JSON 字段来自 `StandaloneEmcStatus`,并检查 `emcStatus` 与兼容字段的一致性。
|
||||
|
||||
验收:
|
||||
|
||||
- gate 检查 `statusSource=StandaloneEmcStatus`。
|
||||
- gate 检查 `lctask_read_status_json()` 不调用 `lcmot_read_status_json()`。
|
||||
- gate 检查 JS/SDK 没有实现 task/motion 语义。
|
||||
- gate 纳入 `tools/verify_task_full_closure.sh`。
|
||||
|
||||
## 兼容策略
|
||||
|
||||
短期保留:
|
||||
|
||||
- `taskTopLevelStatus`
|
||||
- `rcsStatus`
|
||||
- `task`
|
||||
- `motionStatus`
|
||||
|
||||
新增字段默认进入:
|
||||
|
||||
- `emcStatus.top`
|
||||
- `emcStatus.task`
|
||||
- `emcStatus.motion`
|
||||
- `emcStatus.motion.traj`
|
||||
- `emcStatus.motion.axis`
|
||||
- `emcStatus.motion.joint`
|
||||
- `emcStatus.io`
|
||||
|
||||
旧字段只能作为兼容视图,不能作为后续实现的主字段。新增测试应优先断言 `emcStatus`,再断言兼容字段与其一致。
|
||||
|
||||
## 文档和测试要求
|
||||
|
||||
每完成一个 SJ 批次,需要同步更新:
|
||||
|
||||
- `04-任务矩阵.md`
|
||||
- `03-推进台账.md`
|
||||
- `05-验收证据.md`
|
||||
- `06-决策记录.md`
|
||||
- `07-emctaskmain周期对标蓝图.md`
|
||||
- `11-WASM核心状态机边界与后续完善路线.md`
|
||||
- `docs/source-reuse-map.md`
|
||||
- `docs/compatibility-validation.md`
|
||||
- 对应 `tools/verify_task_*` gate
|
||||
|
||||
默认最终验收命令:
|
||||
|
||||
```bash
|
||||
cd /home/mes123456/cnc_wams/wasm-port
|
||||
./tools/verify_task_full_closure.sh
|
||||
git diff --check
|
||||
```
|
||||
50
wasm-port/working/README.md
Normal file
50
wasm-port/working/README.md
Normal file
@@ -0,0 +1,50 @@
|
||||
# wasm-port task 主循环完全对标推进索引
|
||||
|
||||
## 目标
|
||||
|
||||
本目录用于推进 `wasm-port` 对标 LinuxCNC `linuxcnc/src/emc/task/emctaskmain.cc` 的 task 主循环,重点补齐每个 task 周期读取 motion 状态并驱动 task 状态机的结构。
|
||||
|
||||
当前基线结论:
|
||||
|
||||
- 上游 LinuxCNC task 主循环每周期执行 command read、`emcTaskPlan()`、`emcTaskExecute()`、`emcMotionUpdate(&emcStatus->motion)`、subordinate sync、`emcTaskUpdate()`、status write。
|
||||
- `wasm-port` 当前 task-HAL runtime 已闭合本目录任务矩阵:`lctask_run_cycles()` 具备 command read、plan、execute、motion update、subordinate sync、task update、status write 的 LinuxCNC 式周期骨架。
|
||||
- task status 已由周期内 `LcmotStatusSnapshot` 和 `StandaloneEmcStatus` 导出,`lctask_read_status_json()` 只读取最后一次 status write,不推进或重新同步 motion。
|
||||
- RUN 文件主路径已由 staged program 的 plan read/command/execute、`emccanon.cc` command envelope 和 `taskintf.cc` motion issue 驱动;host JSON motion plan 仅保留为 timed-plan 兼容/调试入口。
|
||||
- vendored/upstream `emctask.cc`、`taskintf.cc`、`emccanon.cc` 的窄子集已按 T-033 到 T-046 分阶段接入;完整 `emctaskmain.cc`/NML/native HAL/native motion process topology 仍未 promoted。
|
||||
|
||||
## 文档索引
|
||||
|
||||
| 文件 | 用途 |
|
||||
| --- | --- |
|
||||
| `01-项目功能内容.md` | 定义本阶段要实现的功能边界和 LinuxCNC 对标范围。 |
|
||||
| `02-项目程序开发详细步骤.md` | 拆解从当前 minimal adapter 到 LinuxCNC task 主循环对标的开发步骤。 |
|
||||
| `03-推进台账.md` | 记录每轮做了什么、改了哪些文件、验证了什么、下一步是什么。 |
|
||||
| `04-任务矩阵.md` | 维护任务编号、状态、验收标准,防止重复做和口径漂移。 |
|
||||
| `05-验收证据.md` | 记录命令、报告、截图、页面、job/report id 等证据。 |
|
||||
| `06-决策记录.md` | 记录关键技术决策和理由,后续变更避免重复争论。 |
|
||||
| `07-emctaskmain周期对标蓝图.md` | 把上游 `emctaskmain.cc` 周期拆成 WASM 可执行阶段、字段映射和验收要求。 |
|
||||
| `08-上游task源码替换分解.md` | 拆解 `emctask.cc`、`taskintf.cc`、`emccanon.cc` 的函数族迁移顺序、shim 和验收。 |
|
||||
| `09-emc_nml复用评估.md` | 记录完整 `emc_nml.hh` 直接复用评估、依赖清单和当前窄 status 容器路线。 |
|
||||
| `10-taskintf-usrmot-shim设计.md` | 设计 `taskintf.cc` usrmot shim 到 `lcmot_*` 的 command/status/config/error 映射。 |
|
||||
| `11-WASM核心状态机边界与后续完善路线.md` | 固定 WASM/C++、JS/SDK、JSON 的职责边界,并给出后续完善 WASM 核心状态机的任务拆分规则。 |
|
||||
| `12-status-json-LinuxCNC对标方案.md` | 对标 LinuxCNC `EMC_STAT` / status buffer,定义 WASM 中 `StandaloneEmcStatus -> status JSON` 的字段映射、禁止链路和后续实施批次。 |
|
||||
|
||||
## 使用方式
|
||||
|
||||
1. 每轮实施前先看 `04-任务矩阵.md`,选择 `待办` 或 `进行中` 任务。
|
||||
2. 修改代码或文档后同步更新 `03-推进台账.md`。
|
||||
3. 每条任务完成前,把可复现命令和关键输出写入 `05-验收证据.md`。
|
||||
4. 如改变迁移路线、边界或验收口径,先更新 `06-决策记录.md`。
|
||||
5. 涉及 task 主循环实现时,必须同步查看 `07-emctaskmain周期对标蓝图.md`。
|
||||
6. 涉及上游 task 源码替换时,必须同步查看 `08-上游task源码替换分解.md`。
|
||||
7. 涉及完整 `emc_nml.hh` 复用或 status 容器时,必须同步查看 `09-emc_nml复用评估.md`。
|
||||
8. 涉及 `taskintf.cc` motion bridge 或 usrmot shim 时,必须同步查看 `10-taskintf-usrmot-shim设计.md`。
|
||||
9. 涉及 WASM 程序核心状态机、JS/SDK 边界或 status JSON 时,必须同步查看 `11-WASM核心状态机边界与后续完善路线.md`。
|
||||
10. 涉及 status JSON 字段、SDK status API 或 UI status 展示时,必须同步查看 `12-status-json-LinuxCNC对标方案.md`。
|
||||
11. 每轮结束后遵守仓库 `AGENTS.md`,追加中文执行日志。
|
||||
|
||||
## 当前闭合状态
|
||||
|
||||
`04-任务矩阵.md` 当前所有任务均为完成,下一条优先任务为“无”。后续继续扩展对标范围时,先在矩阵中新增任务编号、验收标准和 gate,再实施代码或文档变更。
|
||||
|
||||
后续 WASM 程序完善的默认方向是:WASM/C++ 承载核心状态机和 LinuxCNC 语义,JS/SDK 承担加载、命令传递、状态读取和文件/OPFS 边界,JSON 仅作为 host/browser 通信格式,不作为核心状态机事实源。
|
||||
Reference in New Issue
Block a user