跳到主要内容

PDO 输入输出

对齐 C#:GetIO / Mapping 已退场,请用 CopySlaveInputPdo / WriteSlaveOutputPdo generation 整帧 API。

PDO 周期与邮箱的关系

邮箱通信自动附带在 PDO 周期中,不占用额外帧。邮箱响应延迟约 2 个 PDO 周期。

应用层不是零拷贝指针

C 应用层当前主路径是 generation 整帧复制:读走 CopySlaveInputPdo,写走 WriteSlaveOutputPdo。调用方预分配完整帧缓冲区,SDK 把这一代过程数据拷进/拷出。

内核 SHM 零拷贝只存在于驱动内部(IOmap / GlobalIO),不向应用层暴露指针。不要再把 GetIO、结构体指针 overlay、PdoWrite* 当成可用主路径——GetIO 已退场(fail-closed,不返回内部 IOmap 地址);PdoWrite* 固定 no-op。

主路径:generation 整帧

声明见 slave/slave_pdo.h(动态加载走 dll.CopySlaveInputPdo 等)。

uint8_t CopySlaveInputPdo(uint16_t master, uint16_t slave,
uint8_t* buffer, uint32_t buffer_size,
uint32_t* copied_size, uint32_t* required_size);
uint8_t CopySlaveOutputPdo(uint16_t master, uint16_t slave,
uint8_t* buffer, uint32_t buffer_size,
uint32_t* copied_size, uint32_t* required_size);
uint8_t WriteSlaveOutputPdo(uint16_t master, uint16_t slave,
const uint8_t* data, uint32_t size,
uint32_t* written_size, uint32_t* required_size);

状态:ec_pdo_io_status_t — 0=失败, 1=成功, 2=缓冲不足, 3=长度不匹配, 4=冲突, 5=generation 失效, 6=Busy。

查询尺寸:传入 buffer=NULL, buffer_size=0 可读 required_size(不拷数据)。缓冲不足时不复制半帧。

WriteSlaveOutputPdo 是单 owner 完整帧入口,长度必须与当前 RxPDO 完全相等,无静默截断。禁止与 CopySlaveOutputPdo 组合成局部 RMW;局部更新走 CopySlaveOutputPdoVersioned → patch → CommitSlaveOutputPdoVersioned

示例:

#pragma pack(push, 1)
typedef struct {
uint16_t status_word;
int32_t actual_position;
} servo_input_t;
#pragma pack(pop)

uint32_t copied = 0, required = 0;
uint8_t st = dll.CopySlaveInputPdo(master, 1, NULL, 0, &copied, &required);
if (st == 2 /* BUFFER_TOO_SMALL */ && required >= sizeof(servo_input_t)) {
uint8_t* buf = malloc(required);
st = dll.CopySlaveInputPdo(master, 1, buf, required, &copied, &required);
if (st == 1 && copied == required) {
servo_input_t in;
memcpy(&in, buf, sizeof(in));
printf("位置: %d\n", in.actual_position);
}
free(buf);
}

类型化 / 批量 ABI(已降级)

PdoRead* / PDOReadInput* 使用 caller-owned 快照,错误折叠为 0,无法区分真零值。新代码应检查 CopySlaveInputPdo 状态。

PdoWrite* 固定 no-op,没有成功状态。PDOWriteOutput* 固定返回 FALSE。PDOWriteDirect 固定 FALSE,PDOBatchWrite 固定返回 0。生产写入必须走 1747 整帧或 1748/1749 版本化事务。

PDO 统计与监控

void* GetPDOStats(uint16_t master_index, uint16_t slave_index);
void ResetPDOStats(uint16_t master_index, uint16_t slave_index);
void EnablePDOMonitoring(BOOL enable);
BOOL GetPDOMapping(uint16_t master_index, uint16_t slave_index, uint16_t pdo_type,
void* mapping_buffer, uint32_t buffer_size, uint32_t* mapping_count);

PDO 周期 / 丢帧请用 GetPDOStats / GetPDOFrameLossStats / 主站诊断,见 诊断

输入/输出字节数仍可用 GetSlaveInputBytes / GetSlaveOutputBytes。不要用 GetIO 取指针再按偏移 overlay。

已退场(不要再用)

旧写法现状
GetIO(...)in_ptr/out_ptr 再 struct cast已退场,fail-closed
PdoWriteInt32 / PDOWriteOutputU16固定 no-op / FALSE
WriteSlaveOutput / WriteSlaveOutputByte已弃用 ABI,fail-closed
GetIO 当 C# OutputsMapping<T>()Mapping 已退场

需要结构体视图时:先 CopySlaveInputPdo 到调用方缓冲区,再 memcpy 到 packed struct。不要假设能拿到跨周期仍有效的 IOmap 指针。