硬件控制系统的中枢管理类Controller实现

public class Controller : INamed<string>, IDisposable
    {
        private ControllerHandle controllerHandle;

        private bool disposed;

        private readonly Data data;

        private readonly ControllerInformation information;

        private readonly ControllerParameters parameters;

        private readonly TasksCollection tasks;

        private readonly ControlCenter controlCenter;

        private readonly TaskSelectionCommands commands;

        private readonly ControllerVariableContainer variables;

        private readonly LoadedProgramCollection loadedPrograms;

        private readonly CallbackRegistrar callbackRegistrar;

        private static object mutex = new object();

        private static Controller connectedController;

        private static SystemConfiguration systemConfiguration;

        string INamed<string>.Name => "A3200";

        public Data DataCollection => data;

        public ControllerInformation Information => information;

        public ControllerParameters Parameters => parameters;

        public TasksCollection Tasks => tasks;

        public ControlCenter ControlCenter => controlCenter;

        public TaskSelectionCommands Commands => commands;

        public ControllerVariableContainer Variables => variables;

        public LoadedProgramCollection LoadedPrograms => loadedPrograms;

        internal ControllerHandle Handle => controllerHandle;

        internal CallbackRegistrar CallbackRegistrar => callbackRegistrar;

        internal int Number => 0;

        public static Controller ConnectedController => connectedController;

        public static SystemConfiguration Configuration
        {
            get
            {
                if (systemConfiguration == null)
                {
                    systemConfiguration = new SystemConfiguration();
                }

                return systemConfiguration;
            }
        }

        public static bool IsRunning
        {
            get
            {
                int pdwInitialized_ = 0;
                ExceptionResolver.ResolveThrow(Wrapper.AerSysIsSystemInitialized(ref pdwInitialized_));
                return pdwInitialized_ != 1;
            }
        }

        internal Controller(IntPtr controllerHandle)
            : this(new ControllerHandle(controllerHandle))
        {
        }

        internal Controller(ControllerHandle controllerHandle)
        {
            this.controllerHandle = controllerHandle;
            information = new ControllerInformation(this);
            parameters = new ControllerParameters(this, new ControllerParameterCreator(this));
            tasks = new TasksCollection(this);
            callbackRegistrar = new CallbackRegistrar(this);
            commands = new TaskSelectionCommands(this);
            data = new Data(this);
            controlCenter = new ControlCenter(this);
            variables = new ControllerVariableContainer(this);
            loadedPrograms = new LoadedProgramCollection(this);
            Information.ControllerResetPre += delegate (object sender, ControllerEventArgs eventArgs)
            {
                eventArgs.Controller.Parameters.InvalidateCache();
                eventArgs.Controller.Information.invalidateCache();
            };
        }

        ~Controller()
        {
            Dispose(disposing: false);
        }

        public void Reset()
        {
            if (controllerHandle == null)
            {
                throw new InvalidOperationException(Resources.ControllerNotConnectedException);
            }

            InitializationWrapper(controllerHandle.Value, smc: true);
        }

        public void Dispose()
        {
            Dispose(disposing: true);
            GC.SuppressFinalize(this);
        }

        public void ChangePassword(string oldPassword, string newPassword)
        {
            if (oldPassword == null)
            {
                throw new ArgumentNullException("oldPassword");
            }

            if (newPassword == null)
            {
                throw new ArgumentNullException("newPassword");
            }

            ExceptionResolver.ResolveThrow(Wrapper.AerSysSetPassword(controllerHandle.Value, oldPassword, newPassword));
        }

        protected virtual void Dispose(bool disposing)
        {
            if (!disposed && disposing)
            {
                information.stopResetThread();
                Wrapper.AerEventWaitCancel(controllerHandle.Value);
                controlCenter.UnsubscribeAll();
                CallbackRegistrar.ShutDown();
                ((IDisposable)DataCollection.Poller).Dispose();
                controllerHandle.Dispose();
                variables.Dispose();
                disposed = true;
            }
        }

        public static Controller Connect()
        {
            Disconnect();
            IntPtr phAerCtrl_ = IntPtr.Zero;
            int pdwConfigMode_ = 0;
            ExceptionResolver.ResolveThrow(Wrapper.AerSysConnect(ref phAerCtrl_, ref pdwConfigMode_));
            try
            {
                _SYS_INIT_INFO pSysInitInfo_ = default(_SYS_INIT_INFO);
                Wrapper.AerSysServerIsInitialized(phAerCtrl_, ref pSysInitInfo_);
                InitializationWrapper(phAerCtrl_, !pSysInitInfo_.bSmcIsInitialized);
            }
            catch
            {
                Wrapper.AerSysDisconnect(phAerCtrl_);
                throw;
            }

            lock (mutex)
            {
                connectedController = new Controller(phAerCtrl_);
                DiagPacketPoller.Threader.ResetInterval();
                DiagPacketPoller.Threader.Spooler.InitQueue(1);
                TaskStatesPoller.Threader.ResetInterval();
                TaskStatesPoller.Threader.Spooler.InitQueue(1);
                return connectedController;
            }
        }

        private static void InitializationWrapper(IntPtr handle, bool smc)
        {
            int pdwInitErrorState_ = 0;
            ErrorData peRcWarning_ = default(ErrorData);
            StringBuilder stringBuilder = new StringBuilder(4096);
            if (smc)
            {
                ErrorData errorData = Wrapper.AerSysInitialize(handle, null, bResetFieldbus_: true, ref pdwInitErrorState_, ref peRcWarning_, stringBuilder);
                string errorMessage = ExceptionResolver.GetErrorMessage(errorData, stringBuilder.ToString());
                ExceptionResolver.ResolveThrow(errorData, errorMessage);
            }
        }

        public static void Disconnect()
        {
            DiagPacketPoller.Threader.StopAll();
            TaskStatesPoller.Threader.StopAll();
            lock (mutex)
            {
                if (connectedController != null)
                {
                    connectedController.Dispose();
                }

                connectedController = null;
                DiagPacketPoller.Threader.Spooler.InitQueue(0);
                TaskStatesPoller.Threader.Spooler.InitQueue(0);
            }
        }
    }

以下是对 Controller 类的深度解析,从架构设计到实现细节的全面分析:


1. 核心角色

作为 硬件控制系统的中枢管理类,主要职责包括:

  • 硬件连接生命周期管理(连接/断开/重置)

  • 子系统协调:任务、程序、变量、回调等组件的统一访问入口

  • 线程安全的全局状态维护

  • 密码保护和资源清理


2. 关键设计模式

(1)单例模式(受限)
private static Controller connectedController;
private static object mutex = new object();

public static Controller Connect() {
    lock(mutex) {
        if (connectedController == null) {
            // 初始化连接...
            connectedController = new Controller(phAerCtrl_);
        }
        return connectedController;
    }
}
  • 全局唯一性:通过静态字段确保单连接实例

  • 线程安全:使用 mutex 保护连接过程

(2)组合模式

  • 子系统解耦:各功能模块通过独立类实现

  • 统一接口:通过Controller属性暴露子组件

(3)观察者模式
Information.ControllerResetPre += (sender, e) => {
    e.Controller.Parameters.InvalidateCache();
    // ...
};

 

  • 事件驱动:硬件状态变化通知相关组件


3. 核心组件分析

组件类型功能
TasksCollection集合管理所有任务的容器
CallbackRegistrar事件处理硬件回调注册中心
ControllerHandle资源封装原生硬件句柄的托管包装
DiagPacketPoller后台服务诊断数据轮询

4. 硬件交互关键流程

(1)连接初始化

(2)资源释放 

protected virtual void Dispose(bool disposing) {
    if (!disposed) {
        // 1. 停止监控线程
        information.stopResetThread(); 
        // 2. 取消硬件事件等待
        Wrapper.AerEventWaitCancel(handle); 
        // 3. 释放所有子组件
        controlCenter.UnsubscribeAll();
        callbackRegistrar.ShutDown();
        // 4. 释放原生句柄
        controllerHandle.Dispose(); 
    }
}

5. 线程安全设计

机制应用场景实现方式
静态锁全局连接管理lock(mutex) 保护 connectedController
后台轮询状态监控DiagPacketPoller 独立线程
事件取消资源释放AerEventWaitCancel 中断硬件等待

6. 典型使用场景

(1)系统初始化
using (var controller = Controller.Connect()) {
    controller.Tasks[0].ExecutionMode = TaskExecutionMode.SingleStep;
    controller.LoadedPrograms.Add("test.script");
}

 (2)异常处理

try {
    controller.Reset();
} catch (A3200Exception ex) {
    Console.WriteLine($"Reset failed: {ex.ErrorData}");
}

总结

该类的设计优势:

  • 清晰的层次结构:通过组合模式分离关注点

  • 可靠的资源管理:完善的Dispose模式

  • 全局协调能力:统一管理硬件访问和后台服务

适用于需要 精确控制物理设备 的工业自动化场景,典型应用于:

  1. CNC机床控制系统

  2. 机器人运动控制

  3. 实时数据采集系统

通过引入异步模式和更细粒度的状态监控,可进一步提升其在现代工业4.0系统中的适用性。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值