Files
DCU_ECAT_Master/_probe_scan.py
T
cbb 8d414ae3fb docs: 定名 dcu-ecat-master, 登记 _probe_scan.py
目录名 ecat 过泛(tools/ 下另有 ESP32), 按同级项目 DCU_APP / ESP32_COMM /
spi_link 的风格定名 dcu-ecat-master: dcu 限定归属, ecat-master 表明是
EtherCAT 主站侧工具(区别于从站固件)。远端托管用小写连字符形式。
名字写入 README 标题(对外可见)与 .git/description(本地元数据)。

同时把 _probe_scan.py(扫描响应帧头在 SM1 RAM 的确切偏移)登记进脚本表,
补齐 _probe_wedge2 / _probe_stuck 两行说明。
2026-09-03 02:41:19 +08:00

70 lines
2.0 KiB
Python

"""_probe_scan.py — 精确定位响应帧头在 SM1 RAM 的偏移 + SM0 请求侧同步 dump。"""
import struct
import sys
import time
import ecat_server as es
import pysoem
r = es.api_open({"substr": "I226"})
if not r.get("ok"):
sys.exit(1)
m = es.g_master
s = m.slaves[0]
def fprd(addr, size):
try:
return bytes(s._fprd(addr, size, 20000))
except Exception:
return None
def sm_reg(addr):
d = fprd(addr, 8)
if d is None:
return None
start, length = struct.unpack("<HH", d[:4])
return {"start": start, "len": length, "ctl": d[4], "st": d[5], "act": d[6]}
m.state = pysoem.INIT_STATE | pysoem.STATE_ACK
m.write_state()
m.state_check(pysoem.INIT_STATE, 1_000_000)
m.config_init()
m.state = pysoem.PREOP_STATE | pysoem.STATE_ACK
m.write_state()
print("PREOP:", "OK" if m.state_check(pysoem.PREOP_STATE, 1_000_000) == pysoem.PREOP_STATE else "FAIL", flush=True)
sm0, sm1 = sm_reg(0x0800), sm_reg(0x0808)
print(f"SM0: start=0x{sm0['start']:04X} len={sm0['len']} | SM1: start=0x{sm1['start']:04X} len={sm1['len']}", flush=True)
# 注入请求(SOEM 标准格式 SDO 读 0x1018:01)
req = bytes([0x0A, 0x00, 0x00, 0x00, 0x00, 0x03,
0x00, 0x10, 0x40, 0x01, 0x18, 0x10, 0x01, 0x00, 0x00, 0x00])
mbx = (req + bytes(sm0["len"]))[:sm0["len"]]
s._fpwr(sm0["start"], mbx)
print("请求已写入 SM0", flush=True)
time.sleep(0.2)
# 扫描 SM1 start-8 .. start+72
base = sm1["start"]
d = fprd(base - 8, 80)
if d:
print(f"\nSM1 RAM 扫描 [0x{base - 8:04X} .. 0x{base + 72:04X}]:", flush=True)
for i in range(0, 80, 8):
chunk = d[i:i + 8]
off = i - 8
mark = " <-- SM1.start" if off == 0 else ""
print(f" {off:+4d} (0x{base + off:04X}): {chunk.hex().upper()}{mark}", flush=True)
st1 = sm_reg(0x0808)
print(f"\nSM1 st=0x{st1['st']:02X}(bit3={st1['st'] >> 3 & 1})", flush=True)
# 同步看 SM0 侧(请求是否被读走)
st0 = sm_reg(0x0800)
print(f"SM0 st=0x{st0['st']:02X}(bit3={st0['st'] >> 3 & 1})", flush=True)
es.api_close({})
print("DONE", flush=True)