chore: close wasm status contract work

This commit is contained in:
wangdequan
2026-07-08 09:20:47 -04:00
parent 97732ceb0b
commit e69333972c
69 changed files with 20435 additions and 495 deletions

View 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。
### E2plan/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` 分解
### TIF1motion 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()`
### TIF2traj 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`
### TIF3joint/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` 分解
### C1canon 基础状态和单位转换
优先函数/变量:
| 函数/组 | 上游行为 | 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 输出一致。
### C3spindle/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。