跳到主要内容

MDP — 模块化设备

Modular Device Profile (MDP) 是 EtherCAT 中描述模块化设备的标准协议。

通过 slave.MDP 访问。从站不支持 MDP 时为 null。​

自动处理

SDK 在状态切换到 OP 时会自动编排 MDP 模块化设备——模块检测、PDO Assignment 生成、启动参数写入全部在内部完成,对用户透明。GCAN-8200 等典型 MDP 设备进 OP 无需任何额外代码。
绝大多数场景下,用户无需直接操作 slave.MDP;此页 API 仅用于诊断查询(查看已配置/已检测模块、PDO 布局)与手动触发模块检测。

关于热插拔

SDK 支持 MDP 模块热插拔再配置自修复。
但生产环境中几乎不会出现 MDP 模块热插拔的使用场景。
EtherCAT 从站的模块配置在设备上电后即固定,运行期间不会动态变更。
部署 MDP 模块化设备推荐使用 DENI;
如需自动配置,请先导入对应的 ESI 文件,再调用 AutoStartup()。

属性​

类别属性类型读写说明
模块列表ConfiguredModulesIReadOnlyList<MdpSlotInfo>只读已配置模块列表(索引 0xF030)
DetectedModulesIReadOnlyList<MdpSlotInfo>只读已检测模块列表(索引 0xF050)
AvailableModulesIReadOnlyList<MdpAvailableModule>只读ESI 中定义的可选模块列表(缓存)
模块索引ModuleIndexDistanceushort只读模块索引间距(0xF000:01,默认 0x0008);槽位 OD 地址 = 间距 × 槽位号
标识数组ConfigModuleIdentsuint[]只读0xF030 模块标识数组(DLL 直读,无 ESI 依赖)
DetectedModuleIdentsuint[]只读0xF050 模块标识数组(DLL 直读,无 ESI 依赖)

ConfiguredModules​

public IReadOnlyList<MdpSlotInfo> ConfiguredModules { get; }

已配置模块列表。每次访问实时读取(索引 0xF030,DLL 直读,无 ESI 依赖);模块名称与 I/O 类型由 ESI 派生。

返回值:

  • IReadOnlyList<MdpSlotInfo> — 已配置模块列表

相关结构:

public class MdpSlotInfo
{
public int SlotIndex { get; set; } // 槽位索引(从 1 开始)
public uint ModuleIdent { get; set; } // 模块标识码(32 位)
public string ModuleName { get; set; } // 模块名称
public uint ModuleType { get; set; } // 模块设备类型码
public string Status { get; set; } // 状态("已配置" / "已检测")
public ushort ObjectDictionaryIndex { get; set; } // 对象字典基地址
public string ModuleIOType { get; set; } // I/O 类型(Input / Output / I/O / Unknown)
}
ModuleIOType 判定逻辑

优先从 ESI 文件的模块定义中读取 TxPdo / RxPdo 配置:

  • 仅有 TxPdo → "Input"(从站发送到主站)
  • 仅有 RxPdo → "Output"(主站发送到从站)
  • 两者都有 → "I/O"

ESI 无法判断时回退到模块名称关键字匹配。

示例:

foreach (var slot in slave.MDP.ConfiguredModules)
Console.WriteLine($"Slot {slot.SlotIndex}: {slot.ModuleName} (0x{slot.ModuleIdent:X8})");

DetectedModules​

public IReadOnlyList<MdpSlotInfo> DetectedModules { get; }

已检测模块列表,反映物理上实际插入的模块。每次访问实时读取(索引 0xF050,DLL 直读,无 ESI 依赖);模块名称与 I/O 类型由 ESI 派生。

返回值:

  • IReadOnlyList<MdpSlotInfo> — 已检测模块列表(同 ConfiguredModules 结构)

示例:

foreach (var slot in slave.MDP.DetectedModules)
Console.WriteLine($"Slot {slot.SlotIndex}: {slot.ModuleName}");

AvailableModules​

public IReadOnlyList<MdpAvailableModule> AvailableModules { get; }

ESI 中定义的可选模块列表。需要从站已导入 ESI 文件,否则返回空列表。结果会缓存,仅首次访问时解析。

返回值:

  • IReadOnlyList<MdpAvailableModule> — 可选模块列表

相关结构:

public class MdpAvailableModule
{
public uint ModuleIdent { get; set; } // 模块标识码
public uint ModuleType { get; set; } // 模块设备类型码
public string ModuleName { get; set; } // 模块名称
public string Description { get; set; } // 模块描述
}

示例:

foreach (var mod in slave.MDP.AvailableModules)
Console.WriteLine($"{mod.ModuleName} (0x{mod.ModuleIdent:X8})");

方法​

类别方法返回类型读写说明
模块检测DetectModules()bool写入触发从站重新扫描已安装模块(写 0xF002:01)
CheckModuleMatch()ModuleListMatchResult只读校验 0xF030 与 0xF050 列表是否匹配
列表读取ReadModuleProfileList()Dictionary<byte, uint>只读读取 Module Profile List(0xF010)
ReadConfiguredAddressList()Dictionary<byte, uint>只读读取 Configured Address List(0xF020)
ReadDetectedAddressList()Dictionary<byte, uint>只读读取 Detected Address List(0xF040)
PDO 布局GetModulePdoLayout()List<MdpModulePdoInfo>?只读各模块在 IOmap 中的 PDO 布局

DetectModules()​

public bool DetectModules()

触发从站模块检测命令(ETG.5001.1 Table 5,写入 0xF002:01),从站重新扫描已安装的模块。部分从站不支持此对象,调用前请确认设备是否实现。成功后自动清静态缓存,下次属性访问取最新数据。

返回值:

  • bool — true 写入成功,false 写入失败或从站不支持

示例:

if (slave.MDP.DetectModules())
Console.WriteLine("模块检测命令已下发");

GetModulePdoLayout()​

public List<MdpModulePdoInfo>? GetModulePdoLayout()

获取各模块在从站 IOmap 中的 PDO 布局。通过 CoE SDORead 读取 PDO Assignment (0x1C12/0x1C13) 和 PDO Mapping 条目,累积计算各模块的字节偏移。

备注

需要从站已完成 DENI 配置(ConfigMap 后可用),不依赖 ESI 文件。CoE 不可用或未检测到模块时返回 null。

返回值:

  • List<MdpModulePdoInfo>? — 各模块的 PDO 布局信息,无法获取时返回 null

相关结构:

public class MdpModulePdoInfo
{
public int SlotIndex { get; set; } // 槽位索引
public uint InputOffset { get; set; } // 输入 PDO 偏移(相对于 slave.Ioffset)
public ushort InputSize { get; set; } // 输入 PDO 字节数
public uint OutputOffset { get; set; } // 输出 PDO 偏移(相对于 slave.Ooffset)
public ushort OutputSize { get; set; } // 输出 PDO 字节数
}

示例:

var layout = slave.MDP.GetModulePdoLayout();
if (layout != null)
{
foreach (var mod in layout)
Console.WriteLine($"Slot {mod.SlotIndex}: In={mod.InputSize}B @{mod.InputOffset}, Out={mod.OutputSize}B @{mod.OutputOffset}");
}

自动配置​

MDP 设备的自动配置需要先导入对应的 ESI 文件,由以下方法完成: