目录名 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 两行说明。
70 lines
2.0 KiB
Python
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)
|