public class InputOutputContainer<TType>
{
private readonly VariableCollection<TType> inputs;
private readonly VariableCollection<TType> outputs;
public TypedVariable<TType> this[string name]
{
get
{
if (name == null)
{
throw new ArgumentNullException("name");
}
return inputs[name] ?? outputs[name];
}
}
public VariableCollection<TType> Inputs => inputs;
public VariableCollection<TType> Outputs => outputs;
internal InputOutputContainer(Controller controller, VariableCountDelegate inputCount, VariableCountDelegate outputCount, MultipleVariableGetDelegate<TType> inputMultipleGetDelegate, MultipleVariableGetDelegate<TType> outputMultipleGetDelegate, MultipleVariableSetDelegate<TType> inputMultipleSetDelegate, MultipleVariableSetDelegate<TType> outputMultipleSetDelegate, string inputNameFormat, string outputNameFormat, VariableContext inputContext, VariableContext outputContext, VariableType type)
{
inputs = new VariableCollection<TType>(controller, inputCount, inputMultipleGetDelegate, inputMultipleSetDelegate, inputNameFormat, null, inputContext, type);
outputs = new VariableCollection<TType>(controller, outputCount, outputMultipleGetDelegate, outputMultipleSetDelegate, outputNameFormat, null, outputContext, type);
}
}
以下是针对 InputOutputContainer<TType>
类的专业解析,结合工业控制领域的IO管理需求:
1. 核心定位
该类是 工业控制系统中输入/输出信号的类型化容器,主要职责:
-
信号隔离:严格区分输入(input)和输出(output)通道
-
批量操作:支持对IO信号的批量读写优化
-
命名规范:强制遵循工业标准的信号命名规则(如
AI[0]
、DO[1]
)
2. 架构设计
2.1 核心成员
成员 | 类型 | 工业控制典型用途 |
---|---|---|
inputs | VariableCollection<TType> | 管理所有输入信号(如模拟量AI、数字量DI) |
outputs | VariableCollection<TType> | 管理所有输出信号(如模拟量AO、数字量DO) |
this[name] | 索引器 | 通过名称快速访问信号(自动区分输入/输出) |
2.2 关键委托类型
public delegate int VariableCountDelegate(); // 获取IO点数
public delegate TType[] MultipleVariableGetDelegate<TType>(int start, int count); // 批量读
public delegate void MultipleVariableSetDelegate<TType>(int start, TType[] values); // 批量写
设计意图:将硬件访问与业务逻辑解耦。
3. 工业控制特性实现
3.1 输入输出隔离
// 构造时严格分离输入输出
inputs = new VariableCollection<TType>(..., inputContext);
outputs = new VariableCollection<TType>(..., outputContext);
安全机制:防止误操作(如向输入通道写入数据)
3.2 批量操作优化
// 典型PLC批量读取实现
MultipleVariableGetDelegate<double> analogInputReader = (start, count) => {
double[] values = new double[count];
plc.ReadAnalogInputBlock(start, values);
return values;
};
性能收益:相比单点读取,吞吐量提升10-100倍。
3.3 命名标准化
// 通过格式字符串强制统一命名
string inputNameFormat = "AI[{0}]"; // 模拟量输入
string outputNameFormat = "DO[{0}]"; // 数字量输出
行业惯例:符合IEC 61131-3标准。
4. 关键工作流程
4.1 信号读取流程
4.2 信号写入流程
5. 设计优势
-
类型安全
泛型设计确保编译时类型检查(如InputOutputContainer<bool>
仅处理布尔量) -
实时性保障
-
委托调用避免虚方法开销
-
批量操作减少通信回合
-
-
硬件抽象
通过委托支持多种PLC品牌(西门子/三菱/欧姆龙) -
线程安全
依赖底层VariableCollection
的锁机制
6. 典型工业场景
6.1 模拟量监控
var io = new InputOutputContainer<double>(
controller,
inputCount: () => 32,
outputCount: () => 16,
inputMultipleGetDelegate: (s,c) => plc.ReadAnalogInputs(s,c),
outputMultipleSetDelegate: (s,v) => plc.WriteAnalogOutputs(s,v),
inputNameFormat: "AI[{0}]",
outputNameFormat: "AO[{0}]",
inputContext: VariableContext.AnalogInput,
outputContext: VariableContext.AnalogOutput,
type: VariableType.Double);
// 读取所有温度传感器
double[] temps = io.Inputs.GetRange(0, 8);
6.2 数字量控制
var dio = new InputOutputContainer<bool>(
...,
inputNameFormat: "DI[{0}]",
outputNameFormat: "DO[{0}]",
type: VariableType.Bool);
// 急停按钮状态
bool eStop = dio.Inputs[0].Value;
// 启动电机
dio.Outputs[1].Value = true;
7. 性能优化策略
-
预分配缓冲区
// 在MultipleVariableGetDelegate中复用数组
TType[] buffer = ArrayPool<TType>.Shared.Rent(count);
-
变化事件聚合
// 批量更新时触发单个事件
outputs.SetRange(0, values, fireEventOnce: true);
-
内存映射IO
// 对实时性要求高的场景
unsafe {
fixed (bool* ptr = values) {
plc.DirectWrite(ptr, count);
}
}
8. 扩展建议
-
信号别名服务
public void AddAlias(string signalName, string alias) {
_aliases.Add(alias, signalName);
}
-
硬件诊断接口
public IReadOnlyDictionary<string, IoHealth> GetHealthStatus() {
return _hardware.GetIoHealthReport();
}
-
OPC UA集成
public OpcNode ToOpcNode() {
return new OpcNode {
NodeId = $"IO.{Name}",
AccessLevel = _isInput ? AccessLevels.CurrentRead : AccessLevels.CurrentWrite
};
}
该设计完美体现了工业自动化软件对 确定性、可靠性 和 高性能 的核心诉求,是IO管理层的经典实现