27 KiB
Native Task 与实时 HAL 同步实现步骤
生成时间:2026-06-21 CST
1. 目标和边界
本文用于指导后续把当前保留的两个 blocker 推进到可验证完成状态:
nativeTaskReady=false
nativeHalSyncReady=false
这里的“完成”不是把浏览器变成真实机床控制器,也不是接入真实硬件 IO;目标是建立一个 LinuxCNC 源码拥有语义的 task/HAL 同步 runtime 边界,使 Web 仿真能按 LinuxCNC task、motion、HAL 的顺序运行程序、执行 MDI/JOG、同步 HAL pin,并把状态反馈到 gmoccapy Web UI。
完成后的目标状态:
nativeTaskReady=true
nativeHalSyncReady=true
plannerRuntimeReady=true
fullLinuxCncProgramExecutionReady=true for simulated machine-file runtime
hardwareDrive=false
promotionAllowed=true for Web simulation boundary only
仍不属于本文范围:
- 真实硬件 IO、Mesa/并口/伺服驱动;
- Linux 内核实时线程等同物;
- 任意外部 user-M host 进程或系统脚本执行;
- Python GUI、GTK、Tk、QtVCP runtime;
- 未经过 LinuxCNC 源码边界验证的 JavaScript CNC 语义。
已单独实现但只限 Web simulation boundary:
- staged
tool.tbl的 tool DB Web/WASM 仿真; - 白名单
M128/M129/M428/M429/M430的受控 user-M 仿真; Tn/M6/G43/M61与 HAL/state 事件的可追溯状态输出。
2. LinuxCNC 源程序参考清单
后续实现必须以这些源文件为主参考,不能用 Web 侧自定义状态机替代 CNC 语义:
linuxcnc/src/emc/task/task.hh
linuxcnc/src/emc/task/emctask.cc
linuxcnc/src/emc/task/emctaskmain.cc
linuxcnc/src/emc/task/taskintf.cc
linuxcnc/src/emc/task/emccanon.cc
linuxcnc/src/emc/nml_intf/emc.hh
linuxcnc/src/emc/motion/usrmotintf.h
linuxcnc/src/emc/motion/motion.h
linuxcnc/src/emc/motion/motion.c
linuxcnc/src/emc/motion/command.c
linuxcnc/src/emc/motion/control.c
linuxcnc/src/emc/motion/mot_priv.h
linuxcnc/src/emc/tp/tp.c
linuxcnc/src/emc/tp/tc.c
linuxcnc/src/emc/tp/tcq.c
linuxcnc/src/hal/hal_lib.c
linuxcnc/src/hal/hal_priv.h
linuxcnc/src/hal/components/threads.c
当前 wasm-port/vendor/linuxcnc 已包含 interpreter、kinematics、TP 所需的一部分源码,但 task 和 HAL 目录是裁剪状态。实施前必须先把上述 task、motion、HAL、NML 相关源文件纳入 vendored source manifest,或者建立只读引用校验,确保构建用的源码和根目录 linuxcnc/ 中的参考源码一致。
3. 推荐架构
推荐实现为单进程确定性 runtime:
Web UI
-> linuxcnc-task-hal-worker-client.js
-> Web Worker
-> linuxcnc_task_hal.wasm
-> LinuxCNC task loop
-> LinuxCNC canonical queue
-> LinuxCNC motion command queue
-> deterministic HAL scheduler
-> LinuxCNC motion controller servo cycles
-> status snapshot
-> Web store / Three.js / DRO / G-code panel
这个结构不启动 LinuxCNC native 进程、不使用 OS NML IPC、不启动真实 HAL realtime thread。它把 LinuxCNC 的 task/motion/HAL 关键状态机编译到 WASM,并用显式 step(period_ns) API 驱动周期。这样浏览器中每一帧都是可复现的,Node 和 browser smoke 可以对同一 G-code 得到一致的 HAL/status 序列。
host-native LinuxCNC 只作为对照探针:
native LinuxCNC/halrun probe
-> 记录 task status、HAL pin、motion status 序列
WASM task/HAL runtime
-> 记录同类序列
对比 artifact
-> 允许提升 nativeTaskReady/nativeHalSyncReady
4. textbak 接续文件可复用结论
已分析 textbak 中和 native task / HAL 相关的接续文件,结论是:当前仓库已有大量 Web 仿真级 virtual HAL、motion matrix、native opt-in probe 和 promotion lock 资产,后续实现 native task/HAL 边界时必须复用这些成果,但不能把它们直接当成 native task/HAL runtime 已完成。
4.1 可直接复用的工作
textbak/text17.txt 记录了完整 virtual HAL 闭环,当前对应代码主要在:
wasm-port/runtime/sdk/src/linuxcnc-hal.js
wasm-port/runtime/opfs/snapshot-store.js
wasm-port/runtime/ui/simulation/simulation-app.js
wasm-port/tests/host/verify_project_release_readiness_artifact.mjs
可复用内容:
- HAL pin family registry:
axisui、halui、iocontrol、motion、axis、joint、spindle、coolant、tool; - HAL pin/signal/param/net store 结构;
executeVirtualHalcmd()/executeVirtualHalCommand()的 halcmd fixture 语义;stepVirtualHalMotion()/stepVirtualHalMotionController()的 deterministic servo-period stepping 测试模式;createVirtualHalMotionControllerMatrixReport()的 motion matrix 验证项;- OPFS snapshot 中的
createVirtualHalSessionPayload()、restoreVirtualHalStateFromSessionSnapshot(); - source compliance、sim-config source coverage、release diagnostics artifact 结构。
这些内容应作为阶段 2、阶段 3、阶段 7 的输入,避免重新设计 HAL registry、snapshot、diagnostics 和 motion matrix。
4.2 只能作为 evidence,不能直接提升的工作
textbak/text17.txt 和 textbak/text19.txt 明确:virtual HAL 在 Web 仿真范围内可以替代 host halcmd、host realtime HAL process 和 host motion process,但不能声称提供 Linux kernel hard-realtime ABI、外部硬件驱动 ABI 或 native HAL module ABI。
因此:
virtualHalReady=true
motionControllerMatrix.complete=true
sourceCompliance.complete=true
只能作为 nativeHalSyncReady 的前置 evidence,不能直接使:
nativeTaskReady=true
nativeHalSyncReady=true
fullLinuxCncProgramExecutionReady=true
真正提升仍必须由 LinuxCNC task/motion/HAL WASM runtime 或 host-native 对照探针完成。
4.3 native opt-in probe 模式
textbak/text21.txt、textbak/text24.txt、textbak/text28.txt、textbak/text35.txt 和 wasm-port/docs/full-process-boundary-design.md 已形成一套可复用规则:
source proof ready
native runtime readiness checked
probe disabled by default
ENABLE_*_RUNTIME_PROBE=1 才运行真实 host runtime
缺少 host runtime 时 skip,不失败
已有 LinuxCNC runtime 冲突时 blocked,不抢占
execution_enabled=0
promotion_allowed=0 until Node/WASM/browser proof also passes
当前已有可参考脚本:
wasm-port/tests/native/probe_millturn_user_m_runtime.sh
wasm-port/tests/native/probe_tool_db_runtime.sh
wasm-port/tests/native/probe_python_remap_runtime.sh
后续 probe_trt_task_hal_runtime.sh 必须照这个模式写,尤其是:
- 检查
linuxcnc、halcmd、halrun、milltask或所需命令; - 默认只报告 readiness,不执行独占 runtime;
- 显式 opt-in 后才启动 native runtime;
- 如果发现已有
linuxcncsvr -ini或rtapi_app load,报告 blocked; - 输出 key/value artifact,且默认保持
promotion_allowed=0。
4.4 Web/virtual HAL user-M proof 可借鉴
textbak/text28.txt 的 L4-USER-M-PROCESS 记录说明:millturn M429 -> M129 -> turn、M428 -> M128 -> mill 已接入 Web/virtual HAL 状态 proof,验证了:
motion.switchkins-type
motion.analog-out-03
kinstype.is-0 / kinstype.is-1
ini.x.min_limit / ini.x.max_limit
ini.z.min_limit / ini.z.max_limit
这对 TRT M428/M429/M430 的 task/HAL 同步很有价值:可复用状态目标、guard pin、source-boundary report 的写法。当前实现已把这些模式收敛为白名单 user-M Web 仿真事件,但仍然不执行 arbitrary external user-M host process,不解除 native promotion。
4.5 kinematics 和 HAL shim 已有注意事项
textbak/text39.txt、textbak/text40.txt、textbak/text41.txt 记录了 kinematics WASM ABI 和 HAL shim 经验:
wasm-port/runtime/core/shims/hal.h已是 C ABI 边界;linuxcnc_hal_adapter.cpp需要对 C/C++ 调用者保持一致 ABI;- kinematics C 源可能直接调用
hal_*,所以 task/HAL runtime 的 HAL API 不能只做 JS wrapper; - kinematics ready 不能等同于 interpreter/remap/full-process ready。
后续新增 linuxcnc_hal_runtime.hh/.cpp 时,应兼容现有 hal.h 和 linuxcnc_hal_adapter.hh,不要另起一套不兼容 HAL 类型定义。
4.6 应写入后续实现的复用点
后续代码实施时,优先按下面映射复用:
| 后续阶段 | 复用来源 | 用法 |
|---|---|---|
| 阶段 1 Native 对照探针 | probe_millturn_user_m_runtime.sh |
复制 opt-in、skip、blocked、key/value 输出模式 |
| 阶段 2 HAL runtime | linuxcnc-hal.js、hal.h、linuxcnc_hal_adapter.hh |
复用 pin 类型、family、source evidence、C ABI 类型 |
| 阶段 3 Motion HAL sync | createVirtualHalMotionControllerMatrixReport() |
把 matrix 从 virtual HAL fixture 升级为 task/motion/HAL runtime 对比 gate |
| 阶段 5 Machine-file session | linuxcnc-machine-file-staging.js、snapshot-store.js |
复用 OPFS 文件和 virtual HAL session payload 结构 |
| 阶段 6 SWITCHKINS | VIRTUAL_HAL_MILLTURN_USER_M_PROCESS_BOUNDARY |
复用 guard pin / state target / source-boundary report 方法 |
| 阶段 8 Full boundary | full-process-boundary-design.md |
保持 promotion lock,直到 native/WASM/browser 全链路通过 |
5. 分阶段实现
阶段 0:源码和构建清单补齐
目标:
- 把 task、motion、HAL、NML 相关源码加入可追溯清单;
- 明确哪些源文件参与 WASM 构建,哪些只用于 native 对照;
- 禁止直接从 JS 手写 task/HAL 语义。
要编写或更新的文件:
wasm-port/tools/source-manifest.txt
wasm-port/docs/source-reuse-map.md
web-rtcp-5axis-sim-plan/docs/traceability-matrix.md
具体步骤:
- 在
source-manifest.txt中加入src/emc/task、src/emc/motion、src/hal、src/libnml、src/emc/nml_intf的必要文件。 - 建立 manifest 校验脚本,比较
linuxcnc/和wasm-port/vendor/linuxcnc/的 hash。 - 对
emctaskmain.cc、emctask.cc、taskintf.cc、emccanon.cc做编译依赖扫描,列出必须 shim 的函数。 - 对
hal_lib.c、hal_priv.h、threads.c、motion HAL pin 定义做依赖扫描,列出 HAL API 最小集合。 - 验收时输出机器可读 artifact:
task_hal_source_manifest_ready=1
task_source_count>0
hal_source_count>0
motion_source_count>0
阶段 1:Native 对照探针
目标:
- 先用 host-native LinuxCNC 证明期望行为;
- 不修改 Web runtime;
- 如果本机没有 LinuxCNC runtime 命令,探针允许 skip,但不得 promoted。
- 复用
textbak中已有 native opt-in probe 规则,避免默认启动或抢占 LinuxCNC host runtime。
要编写的文件:
wasm-port/tests/native/probe_trt_task_hal_runtime.sh
wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_task_hal_native_probe.cpp
wasm-port/build/native/task-hal-reference/*.json
固定序列:
SET_STATE ON
SET_MODE AUTO
OPEN impeller-7bl-xyzac.ngc
RUN
wait until first motion
PAUSE
RESUME
run through M428/M429 switchkins segment
ABORT
必须记录:
task.state
task.mode
task.interpState
task.execState
motion.program-line
motion.motion-type
motion.switchkins-type
motion.coord-mode
motion.teleop-mode
motion.in-position
joint.N.motor-pos-cmd
joint.N.motor-pos-fb
axis pose / commanded pose / feedback pose
analog-out-03
synch digital/analog IO
验收:
native_task_hal_probe=ok
native_probe_status=passed or skipped_missing_host_runtime
promotionAllowed=false until WASM comparison passes
阶段 2:HAL 内存模型和线程调度器
目标:
- 用 LinuxCNC HAL API 名称建立 WASM 内部 HAL registry;
- 支持 pin、signal、param、net、alias;
- 支持确定性 thread/function 调度。
- 复用
linuxcnc-hal.js中的 HAL family/source evidence 和hal.h的类型定义。
参考源码:
linuxcnc/src/hal/hal_lib.c
linuxcnc/src/hal/hal_priv.h
linuxcnc/src/hal/components/threads.c
wasm-port/runtime/core/shims/hal.h
wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_hal_adapter.hh
要编写的文件:
wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_hal_runtime.hh
wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_hal_runtime.cpp
wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_halcmd_runtime.cpp
wasm-port/tests/wasm/node/verify_hal_runtime.sh
wasm-port/runtime/sdk/src/linuxcnc-hal.js
必须实现的 C/C++ API:
hal_init
hal_ready
hal_exit
hal_malloc
hal_pin_bit_new
hal_pin_float_new
hal_pin_s32_new
hal_pin_u32_new
hal_pin_*_newf
hal_param_*_newf
hal_get_pin_value_by_name
hal_get_signal_value_by_name
hal_get_param_value_by_name
hal_link
hal_unlink
hal_set_p
hal_get_p
hal_create_thread
hal_add_funct_to_thread
hal_del_funct_from_thread
hal_start_threads
hal_stop_threads
必须实现的 WASM C ABI:
int lchal_init_runtime(void);
int lchal_load_hal_file(const char *path, const char *text);
int lchal_set_pin_float(const char *name, double value);
int lchal_set_pin_s32(const char *name, int value);
int lchal_set_pin_bit(const char *name, int value);
int lchal_get_pin_json(const char *name, char *out, int out_len);
int lchal_get_snapshot_json(char *out, int out_len);
int lchal_step_threads(long period_ns, int cycles);
int lchal_reset_runtime(void);
编写要点:
- 所有 HAL 值必须保存在 C/C++ runtime 内部,不放在 JS 里当语义源。
net只建立 pin 到 signal 的绑定,值传播由 thread step 或显式 set/get 触发。halcmd先支持 TRT sim config 需要的最小命令:loadrt、addf、net、setp、gets。- 对
loadusr、外部进程、真实驱动组件必须返回 blocked evidence,不得静默忽略。 - 每次
lchal_step_threads()记录 cycle、thread name、function name、changed pins。
验收:
hal_runtime_registry=ok
hal_thread_scheduler=ok
hal_net_signal_propagation=ok
loadusr_blocked_evidence=ok
阶段 3:Motion realtime 同步最小闭环
目标:
- 把 LinuxCNC motion controller 以确定性 servo cycle 方式接入;
- task 发出的 trajectory/jog 命令进入 motion command queue;
- motion controller 每周期更新 status 和 HAL pins。
- 把现有 virtual HAL motion controller matrix 改造为 task/motion/HAL runtime 的对比 gate。
参考源码:
linuxcnc/src/emc/motion/usrmotintf.h
linuxcnc/src/emc/motion/motion.h
linuxcnc/src/emc/motion/motion.c
linuxcnc/src/emc/motion/command.c
linuxcnc/src/emc/motion/control.c
linuxcnc/src/emc/motion/mot_priv.h
linuxcnc/src/emc/task/taskintf.cc
要编写的文件:
wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_motion_runtime.c
wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_motion_runtime.h
wasm-port/tests/wasm/node/verify_motion_hal_sync.sh
wasm-port/runtime/sdk/src/linuxcnc-motion.js
必须实现的 C ABI:
int lcmot_init_from_ini(const char *ini_path, const char *ini_text);
int lcmot_write_command_json(const char *json);
int lcmot_step_servo(long period_ns, int cycles);
int lcmot_read_status_json(char *out, int out_len);
int lcmot_read_hal_snapshot_json(char *out, int out_len);
int lcmot_reset(void);
编写要点:
- 优先复用
emcmot_status_t、emcmot_command_t、emcmot_config_t,避免新建 Web 专用 motion struct。 usrmotWriteEmcmotCommand()在 WASM 中改为写入内存队列。usrmotReadEmcmotStatus()在 WASM 中从同一 runtime snapshot 读取。emcmotController(void *arg, long period)按固定周期调用。- motion HAL pins 必须按
mot_priv.h中的方向和名称输出。 - 至少覆盖
EMC_JOG_*、EMC_TRAJ_LINEAR_MOVE、EMC_TRAJ_CIRCULAR_MOVE、EMC_TRAJ_PAUSE、EMC_TRAJ_RESUME、EMC_TRAJ_ABORT、override 类命令。
验收:
motion_hal_servo_cycle=ok
motion_program_line_hal_sync=ok
switchkins_type_hal_sync=ok
jog_motion_status_sync=ok
阶段 4:Task runtime 移植
目标:
- 让 Web runtime 使用 LinuxCNC task loop 处理 operator command;
RUN/PAUSE/RESUME/STOP/ABORT/MDI/JOG不再只走 Web policy mirror;- task status、exec state、interp state 来自 LinuxCNC task runtime。
参考源码:
linuxcnc/src/emc/task/task.hh
linuxcnc/src/emc/task/emctask.cc
linuxcnc/src/emc/task/emctaskmain.cc
linuxcnc/src/emc/task/taskintf.cc
linuxcnc/src/emc/task/emccanon.cc
linuxcnc/src/emc/nml_intf/emc.hh
要编写的文件:
wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_task_hal_wasm.cpp
wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_task_nml_inproc.hh
wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_task_nml_inproc.cpp
wasm-port/tools/build_task_hal_wasm.sh
wasm-port/runtime/sdk/src/linuxcnc-task-hal.js
web-rtcp-5axis-sim-plan/app/src/runtime/linuxcnc-task-hal-runtime.js
web-rtcp-5axis-sim-plan/app/src/runtime/linuxcnc-task-hal-worker.js
web-rtcp-5axis-sim-plan/app/src/runtime/linuxcnc-task-hal-worker-client.js
必须实现的 C ABI:
int lctask_init_session(const char *session_json);
int lctask_stage_file(const char *path, const char *text);
int lctask_open_program(const char *path);
int lctask_send_command_json(const char *command_json);
int lctask_run_cycles(long task_period_ns, long servo_period_ns, int task_cycles);
int lctask_read_status_json(char *out, int out_len);
int lctask_read_events_json(char *out, int out_len);
int lctask_reset_session(void);
command JSON 最小格式:
{"type":"EMC_TASK_SET_STATE","state":"ON"}
{"type":"EMC_TASK_SET_MODE","mode":"AUTO"}
{"type":"EMC_TASK_PLAN_RUN","line":0}
{"type":"EMC_TASK_PLAN_PAUSE"}
{"type":"EMC_TASK_PLAN_RESUME"}
{"type":"EMC_TASK_ABORT"}
{"type":"EMC_TASK_PLAN_EXECUTE","mdi":"G0 X1"}
{"type":"EMC_JOG_INCR","axis":"X","distance":1,"velocity":60}
编写要点:
emcTaskOnce()是 task loop 的首选入口;不能直接复制 Web 现有linuxcnc-task-policy.js的判断结果作为完成状态。RCS_CMD_CHANNEL、RCS_STAT_CHANNEL、NML channel 在 WASM 中用 in-process queue shim 替代,消息类型仍来自emc.hh。emcTaskQueueCommand()输出的EMC_TRAJ_*消息必须进入 motion runtime,而不是只生成 UI event。emccanon.cc生成的 canonical motion 要同时进入 task queue evidence、motion command queue、TP planner timing evidence、G-code 当前行映射。- task cycle 和 servo cycle 分开,例如每个 10 ms task cycle 运行 10 个 1 ms servo cycle。
验收:
linuxcnc_task_runtime_smoke=ok
task_status_from_linuxcnc_runtime=ok
task_commands_drive_motion_runtime=ok
mdi_jog_task_motion_hal_sync=ok
阶段 5:TRT machine-file session 接入
目标:
- 复用现有 OPFS machine-file staging;
- task/HAL runtime 读取同一 INI、HAL、tool table、remap、G-code 文件;
xyzac-trt和xyzbc-trt都能跑 smoke。
要更新的文件:
web-rtcp-5axis-sim-plan/app/src/runtime/linuxcnc-machine-file-staging.js
web-rtcp-5axis-sim-plan/app/src/runtime/linuxcnc-interpreter-runtime.js
web-rtcp-5axis-sim-plan/app/src/state/store.js
web-rtcp-5axis-sim-plan/app/src/ui/gmoccapy-shell.js
具体步骤:
- 给 staging 结果增加
taskHalSession,记录 INI、HAL、tool table、remap、program path。 - Worker 初始化时把所有 staged 文件写入 Emscripten FS。
LOAD_LINUXCNC_GCODE_SOURCE后自动调用lctask_open_program()。RUN优先走 task/HAL runtime;失败时可 fallback 到现有 interpreter runtime,但 UI 必须显示 fallback boundary。- G-code panel 当前行改用 task/motion status 的
motion.program-line,interpreter canonical line 只作为辅助 evidence。
验收:
task_hal_machine_file_staging=ok
xyzac_trt_task_hal_run=ok
xyzbc_trt_task_hal_run=ok
gcode_current_line_from_motion_hal=ok
阶段 6:SWITCHKINS 和 M428/M429/M430 同步
目标:
M428/M429/M430的状态变化由 LinuxCNC task/remap/motion/HAL 链路驱动;- Web runtime 不再单独用 JS 事件切换 RTCP 作为主语义源。
参考源:
linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/428remap.ngc
linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/429remap.ngc
linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/430remap.ngc
linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/switchkins_postgui.hal
linuxcnc/src/emc/motion/control.c
linuxcnc/src/emc/kinematics/switchkins.c
linuxcnc/src/emc/kinematics/xyzac-trt-kins.c
linuxcnc/src/emc/kinematics/xyzbc-trt-kins.c
具体步骤:
- 在 HAL runtime 中保证
motion.switchkins-type可读写。 - 在 remap execution 中保留
M68/M66同步语义。 - motion servo cycle 读取
motion.switchkins-type后调用 kinematics switch。 - Three.js 和 DRO 从 task/HAL snapshot 中读取
rtcpState、kinsType、tool axis。 - 当前已有的 JS switchkins event 只保留为 diagnostics fallback,不作为 promoted source。
验收:
switchkins_remap_hal_sync=ok
m428_to_tcp_xyzac=ok
m429_to_identity=ok
m430_to_userk_or_profile_defined=ok
rtcp_frame_from_task_hal_runtime=ok
阶段 7:浏览器 Worker 和 store 接线
目标:
- task/HAL runtime 在 Worker 内运行;
- UI 不直接阻塞;
- status snapshot 驱动 gmoccapy UI。
Worker message 类型:
init
stageFiles
openProgram
command
runCycles
readStatus
reset
store action 映射:
TOGGLE_POWER -> EMC_TASK_SET_STATE
RESET -> EMC_TASK_SET_STATE RESET / task reset sequence
SET_MODE -> EMC_TASK_SET_MODE
RUN -> EMC_TASK_PLAN_RUN
PAUSE -> EMC_TASK_PLAN_PAUSE
RESUME -> EMC_TASK_PLAN_RESUME
STOP/ABORT -> EMC_TASK_ABORT + EMC_TRAJ_ABORT
RUN_MDI -> EMC_TASK_PLAN_EXECUTE
JOG -> EMC_JOG_INCR or EMC_JOG_CONT + EMC_JOG_STOP
ADJUST_OVERRIDE -> EMC_TRAJ_SET_SCALE / EMC_TRAJ_SET_RAPID_SCALE
UI 显示要求:
taskRuntimeReady
halRuntimeReady
taskCycle
servoCycle
motionQueueDepth
halChangedPinCount
nativeTaskReady
nativeHalSyncReady
fullLinuxCncProgramExecutionReady
验收:
browser_task_hal_worker_smoke=ok
gmoccapy_task_hal_dom_smoke=ok
canvas_updates_from_task_hal_snapshot=ok
阶段 8:Full boundary 提升
目标:
- 只有所有 task/HAL smoke 通过后,才修改 full boundary;
- 把 blocker 从当前状态移除。
提升条件:
kinematicsReady=true
interpreterReady=true
plannerRuntimeReady=true
machineFileStagingReady=true
machineFileRemapReady=true
taskRuntimeReady=true
motionRuntimeReady=true
halRuntimeReady=true
nativeTaskReady=true
nativeHalSyncReady=true
taskHalComparisonReady=true
createFullLinuxCncExecutionBoundary() 修改规则:
nativeTaskReady = taskHal?.summary?.taskRuntimeReady === true
nativeHalSyncReady = taskHal?.summary?.halSyncReady === true
fullLinuxCncProgramExecutionReady =
kinematicsReady &&
interpreterReady &&
canonicalProgramReady &&
machineFileStagingReady &&
machineFileRemapReady &&
plannerRuntimeReady &&
nativeTaskReady &&
nativeHalSyncReady
semantic boundary 名称:
linuxcnc_task_motion_hal_wasm_simulation_runtime
不允许的提升:
- 只有 Web policy mirror 通过;
- 只有 interpreter canonical events 通过;
- 只有 TP timing 通过;
- 只有 HAL source map 或 PyVCP schema 通过;
- 没有 task cycle 与 HAL servo cycle 对比 artifact。
5. 详细编程顺序
建议严格按以下顺序写程序,避免一次性移植 task、HAL、motion 后难以定位问题。
- 新建
linuxcnc_hal_runtime.hh/.cpp,只实现 pin registry、hal_init()、hal_ready()、hal_malloc()、hal_pin_*_newf()。 - 写
verify_hal_runtime.sh,证明 pin 创建、set/get、snapshot JSON 可用。 - 增加 signal/net/link,写
halcmd_runtime.cpp支持net和setp。 - 增加 thread registry,支持
hal_create_thread()、hal_add_funct_to_thread()、lchal_step_threads()。 - 接入 motion HAL pin 初始化,先让
motion.switchkins-type、motion.program-line、joint.0.motor-pos-cmd能在 snapshot 中出现。 - 新建
linuxcnc_motion_runtime.c,实现 in-memoryusrmotWriteEmcmotCommand()和usrmotReadEmcmotStatus()。 - 调用
emcmotController()运行固定 servo cycles,先验证空闲状态 heartbeat 增长。 - 接入
EMC_TRAJ_LINEAR_MOVE,验证 motor/carte command position 随周期变化。 - 接入 JOG 命令,验证 FREE/TELEOP/COORD 模式切换和 HAL pins。
- 新建 in-process NML queue shim,消息类型必须来自
emc.hh。 - 编译
emctask.cc、emctaskmain.cc、taskintf.cc、emccanon.cc的最小 task runtime。 - 实现
lctask_init_session()和lctask_send_command_json(),先跑SET_STATE、SET_MODE。 - 实现
lctask_open_program(),读取 staged G-code。 - 实现
RUN/PAUSE/RESUME/ABORT,验证 task status 和 motion status 同步。 - 接入 existing interpreter/remap machine-file path,确保 M428/M429/M430 不再被 Web 主逻辑单独处理。
- 把 task/HAL runtime 包成 SDK
linuxcnc-task-hal.js。 - 写 Web Worker client,加入 sequence guard,防止旧 status 覆盖新 session。
- 修改 store:优先 task/HAL runtime,失败时保留现有 interpreter fallback 并显示 fallback boundary。
- 修改 UI diagnostics,显示 task/HAL readiness 和 cycle counters。
- 修改 full boundary,只有全部新 smoke 通过后才把
nativeTaskReady、nativeHalSyncReady置为 true。
6. 验收测试矩阵
Node smoke:
node web-rtcp-5axis-sim-plan/tests/node/verify_linuxcnc_task_hal_runtime.mjs
node web-rtcp-5axis-sim-plan/tests/node/verify_task_hal_machine_file_run.mjs
node web-rtcp-5axis-sim-plan/tests/node/verify_full_execution_boundary.mjs
npm --prefix web-rtcp-5axis-sim-plan/app run smoke:node
Browser smoke:
npm --prefix web-rtcp-5axis-sim-plan/app run build
npm --prefix web-rtcp-5axis-sim-plan/app run smoke
WASM smoke:
bash wasm-port/tools/build_task_hal_wasm.sh
bash wasm-port/tests/wasm/node/verify_hal_runtime.sh
bash wasm-port/tests/wasm/node/verify_motion_hal_sync.sh
bash wasm-port/tests/wasm/node/verify_task_hal_wasm.sh
Native optional proof:
ENABLE_TRT_TASK_HAL_RUNTIME_PROBE=1 bash wasm-port/tests/native/probe_trt_task_hal_runtime.sh
最终 gate:
linuxcnc_task_hal_wasm_build=ok
hal_runtime_smoke=ok
motion_hal_sync_smoke=ok
linuxcnc_task_runtime_smoke=ok
task_hal_machine_file_smoke=ok
switchkins_remap_hal_sync_smoke=ok
browser_task_hal_worker_smoke=ok
full_execution_boundary_smoke=ok
7. 完成定义
只有同时满足以下条件,才允许把文档和 UI 中的 blocker 改为完成:
task commands are accepted by LinuxCNC task-derived runtime
task runtime drives motion command queue
motion runtime advances through deterministic servo cycles
HAL pins are created from LinuxCNC-style HAL API
HAL thread/function scheduler advances with servo cycles
M428/M429 switchkins changes are visible through motion.switchkins-type
G-code current line comes from motion/task status
Node smoke passes
Browser source smoke passes
Browser dist smoke passes
Optional native LinuxCNC probe either passes or is explicitly skipped without promotion dependency
Traceability document records every source file and boundary
完成后仍必须在 UI 和文档里显示:
hardwareDrive=false
hostRealtimeKernel=false
externalUserMProcessReady=true for web_simulation_only
toolDbProcessReady=true for web_simulation_only
hostExternalUserMProcessReady=false
hostToolDbProcessReady=false
arbitraryUserMExecution=false