Files
cnc_wams/wasm-port/working/08-上游task源码替换分解.md
2026-07-08 09:20:47 -04:00

13 KiB
Raw Blame History

08-上游 task 源码替换分解

目标

本文件把上游 emctask.cctaskintf.ccemccanon.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 的自有行为

迁移依赖链

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.modemdiOrAuto 推导 task mode 用 snapshot 推导 status而不是保存字符串
determineState() io.aux.estopmotion.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=IDLEexecState=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_ABORTlcmot
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_MOVEemcTrajLinearMove() 路径进入 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_MOVEEMC_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 bridgeemcMotionInit/Update/AbortemcTrajPause/Step/Resume/Abort/LinearMove task cycle 内 motion snapshot 和 linear move issue 通过
B2 emctask state/update/abortemcTaskAbort/SetMode/SetState/Update state/mode/home/run/pause smoke 仍通过,且语义由 task cycle 触发
B3 emctask plan wrapperPlanInit/Open/Read/Execute/Synch 文件和 MDI 通过 LinuxCNC interpreter/canon 生成 interp_list
B4 emccanon straight motionINIT_CANON/FINISH/STRAIGHT_TRAVERSE/STRAIGHT_FEED G0/G1 不再依赖 JSON motion plan
B5 task execute issueemcTaskExecute() 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。