PDO 输入输出
通过 slave.pdo 访问。对齐 C#:请用 CopyInputPdo / WriteOutputPdo generation 整帧 API。
邮箱通信自动附带在 PDO 周期中,不占用额外帧。邮箱响应延迟约 2-3 个 PDO 周期。
Python 主路径是 generation 整帧复制:读走 CopySlaveInputPdo(slave.pdo.inputs / as_memoryview),写走 WriteSlaveOutputPdo(slave.pdo.write_outputs)。调用方拿到的是 owned 快照,不是 IOmap 指针。
内核 SHM 零拷贝只存在于驱动内部,不向应用层暴露指针。不要再把 get_input_data_pointer、PDOArrayInstance、bind_pdo_struct 当成 live overlay——指针入口已退场(固定返回 0 / fail-closed);bind_pdo_struct 只是 from_buffer_copy 独立快照,改字段不会写回。
主路径:generation 整帧
inputs / write_outputs
@property
def inputs(self) -> Optional[bytes] # CopySlaveInputPdo 完整 TxPDO 快照
@property
def outputs(self) -> Optional[bytes] # CopySlaveOutputPdo 完整 RxPDO 快照
def write_outputs(self, data: bytes) -> bool # WriteSlaveOutputPdo;长度必须相等,无截断
write_outputs 是单 owner 完整帧入口,禁止当局部/typed/batch 读改写用。局部更新走版本化 Copy→patch→commit。
示例:
import struct
raw_input = slave.pdo.inputs
if raw_input and len(raw_input) >= 6:
status_word, actual_pos = struct.unpack_from('<Hi', raw_input, 0)
print(f"StatusWord=0x{status_word:04X} pos={actual_pos}")
frame = bytearray(slave.pdo.outputs or b'')
if len(frame) >= 6:
struct.pack_into('<Hi', frame, 0, 0x000F, 10000)
ok = slave.pdo.write_outputs(bytes(frame))
if not ok:
# 如实处理失败,不要假定已写入
pass
as_memoryview()
def as_memoryview(dll, master_index, slave_index, is_input: bool = True) -> memoryview
owned 只读快照,不是 live IOmap view。输出修改必须走 write_outputs / 版本化事务。
read_input_data_direct() / write_output_data_direct()
def read_input_data_direct(self, buffer: bytearray, offset: int = 0, length: int = 0) -> int
def write_output_data_direct(self, data: bytes, offset: int = 0, length: int = 0) -> int
读:native 整帧复制后写入目标缓冲。写:局部数据先合并进完整 RxPDO,再版本化提交(不是 GetIO overlay)。
同一路径上的便捷包装
下列入口不是第二套 PDO API,内部仍走 Copy/Write 整帧。
类型化读写
read_uint16(offset) / write_uint16(offset, val) 等从完整帧快照解析或版本化 patch。错误读折叠为 0,无法区分真零值;新代码应先取 inputs 再 struct.unpack_from。
bind_pdo_struct()
def bind_pdo_struct(self, struct_type, is_input: bool = True)
实际语义:对完整帧快照做 ctypes.Structure.from_buffer_copy,不持有 native live pointer。改结构体字段不会写回 RxPDO;写入请组完整帧后 write_outputs。
batch_read() / batch_write()
一次完整输入快照切片;批量写走单个版本化事务。越界整批失败,不静默截断。
已退场(不要再用)
| 旧写法 | 现状 |
|---|---|
get_input_data_pointer() / get_output_data_pointer() | GetIO 已退场,固定返回 0 |
PDOArrayInstance / PDODataItem 裸指针 | 构造即 DeprecationWarning,访问抛错 |
get_input_memoryview() 当 live 可写 IOmap | 只读 owned 快照 |
bind_pdo_struct 当零拷贝 overlay | 独立快照,改了不写回 |
inputs_mapping_info['pointer'] | 固定为 0 |
需要结构体视图时:先 inputs / CopySlaveInputPdo,再 struct.unpack_from 或 from_buffer_copy。不要假设能拿到跨周期仍有效的 IOmap 指针。