예제 #1
0
        private void ConfigureSync01(IList <SlaveInfo> slaveInfoSet)
        {
            // SYNC0 / SYNC1
            foreach (SlaveInfo slaveInfo in slaveInfoSet)
            {
                ushort slaveIndex;
                DistributedClocksSettings distributedClocksSettings;

                slaveIndex = (ushort)(Convert.ToUInt16(slaveInfoSet.ToList().IndexOf(slaveInfo)) + 1);
                distributedClocksSettings = slaveInfo.SlaveExtensionSet.OfType <DistributedClocksSettings>().ToList().FirstOrDefault();

                if (distributedClocksSettings != null)
                {
                    DistributedClocksParameters parameters;
                    byte[] assignActivate;

                    if (!slaveInfo.SlaveEsi.Dc.TimeLoopControlOnly)
                    {
                        assignActivate = null;
                        parameters     = distributedClocksSettings.CalculateDcParameters(ref assignActivate, _settings.CycleFrequency);
                        EcUtilities.CheckErrorCode(this.Context, EcHL.ConfigureSync01(this.Context, slaveIndex, ref assignActivate, assignActivate.Count(), parameters.CycleTime0, parameters.CycleTime1, parameters.ShiftTime0));
                    }
                }
            }
        }
예제 #2
0
        private void ConfigureSlaves(IList <SlaveInfo> slaves)
        {
            var callbacks = new List <EcHL.PO2SOCallback>();

            foreach (var slave in slaves)
            {
                // SDO / PDO config / PDO assign
                var currentSlaveIndex = (ushort)(Convert.ToUInt16(slaves.ToList().IndexOf(slave)) + 1);
                var extensions        = slave.Extensions;

                var sdoWriteRequests = slave.GetConfiguration(extensions).ToList();

                EcHL.PO2SOCallback callback = slaveIndex =>
                {
                    sdoWriteRequests.ToList().ForEach(sdoWriteRequest =>
                    {
                        EcUtilities.CheckErrorCode(this.Context, EcUtilities.SdoWrite(this.Context, slaveIndex, sdoWriteRequest.Index, sdoWriteRequest.SubIndex, sdoWriteRequest.Dataset), nameof(EcHL.SdoWrite));
                    });

                    return(0);
                };

                EcHL.RegisterCallback(this.Context, currentSlaveIndex, callback);
                callbacks.Add(callback);
            }

            callbacks.ForEach(callback =>
            {
                GC.KeepAlive(callback);
            });
        }
예제 #3
0
        /// <summary>
        /// Initializes EtherCAT and returns found slaves.
        /// </summary>
        /// <param name="interfaceName">The name of the network adapter.</param>
        /// <returns>Returns found slave.</returns>
        public static SlaveInfo ScanDevices(IntPtr context, string interfaceName, SlaveInfo referenceSlave = null)
        {
            ec_slave_info_t[] refSlaveIdentifications = null;

            if (referenceSlave != null)
            {
                refSlaveIdentifications = EcUtilities.ToSlaveIdentifications(referenceSlave);
            }
            else
            {
                refSlaveIdentifications = new ec_slave_info_t[] { }
            };

            // scan devices
            var networkInterface = NetworkInterface
                                   .GetAllNetworkInterfaces()
                                   .Where(nic => nic.Name == interfaceName)
                                   .FirstOrDefault();

            if (networkInterface == null)
            {
                throw new Exception($"{ ErrorMessage.SoemWrapper_NetworkInterfaceNotFound } Interface name: '{ interfaceName }'.");
            }

            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                interfaceName = $@"rpcap://\Device\NPF_{networkInterface.Id}";
            }

            else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ||
                     RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
            {
                interfaceName = $"{interfaceName}";
            }

            else
            {
                throw new PlatformNotSupportedException();
            }

            EcUtilities.CheckErrorCode(context, EcHL.ScanDevices(context, interfaceName, out var slaveIdentifications, out var slaveCount));

            // create slaveInfo from received data
            var offset = 0;
            var newSlaveIdentifications = new ec_slave_info_t[slaveCount + 1]; // correct because EC master = slaveIdentifications[0]

            for (int i = 0; i <= newSlaveIdentifications.Count() - 1; i++)
            {
                newSlaveIdentifications[i] = Marshal.PtrToStructure <ec_slave_info_t>(IntPtr.Add(slaveIdentifications, offset));
                offset += Marshal.SizeOf(typeof(ec_slave_info_t));
            }

            // validate CSA
            while (EcUtilities.EnsureValidCsa(context, newSlaveIdentifications, refSlaveIdentifications))
            {
                //
            }

            return(EcUtilities.ToSlaveInfo(newSlaveIdentifications));
        }
예제 #4
0
        private void ConfigureDc()
        {
            uint systemTimeDifference;

            EcUtilities.CheckErrorCode(this.Context, EcHL.ConfigureDc(this.Context, _settings.FrameCount, _settings.TargetTimeDifference, out systemTimeDifference), nameof(EcHL.ConfigureDc));

            _logger.LogInformation($"DC system time diff. is <= { systemTimeDifference & 0x7FFF } ns");
        }
예제 #5
0
        public void Configure(SlaveInfo rootSlaveInfo = null)
        {
            SlaveInfo         actualSlaveInfo;
            IList <SlaveInfo> slaveInfoSet;
            IList <SlaveInfo> actualSlaveInfoSet;
            NetworkInterface  networkInterface;

            networkInterface = NetworkInterface.GetAllNetworkInterfaces().Where(nic => nic.Name == _settings.InterfaceName).FirstOrDefault();

            if (networkInterface?.OperationalStatus != OperationalStatus.Up)
            {
                throw new Exception($"Network interface '{_settings.InterfaceName}' is not linked. Aborting action.");
            }

            #region "PreOp"

            actualSlaveInfo = EcUtilities.ScanDevices(this.Context, _settings.InterfaceName, null);

            if (rootSlaveInfo == null)
            {
                rootSlaveInfo = actualSlaveInfo;

                rootSlaveInfo.Descendants().ToList().ForEach(current =>
                {
                    ExtensibilityHelper.CreateDynamicData(_settings.EsiDirectoryPath, _extensionFactory, current);
                });
            }

            slaveInfoSet       = rootSlaveInfo.Descendants().ToList();
            actualSlaveInfoSet = actualSlaveInfo.Descendants().ToList();

            this.ValidateSlaves(slaveInfoSet, actualSlaveInfoSet);
            this.ConfigureSlaves(slaveInfoSet);
            this.ConfigureIoMap(slaveInfoSet);
            this.ConfigureDc();
            this.ConfigureSync01(slaveInfoSet);

            #endregion

            #region "SafeOp"

            EcUtilities.CheckErrorCode(this.Context, EcHL.CheckSafeOpState(this.Context), nameof(EcHL.CheckSafeOpState));

            #endregion

            #region "Op"

            EcUtilities.CheckErrorCode(this.Context, EcHL.RequestOpState(this.Context), nameof(EcHL.RequestOpState));

            #endregion

            if (_watchdogTask == null)
            {
                _watchdogTask = Task.Run(() => this.WatchdogRoutine(), _cts.Token);
            }
        }
예제 #6
0
        public void Configure(SlaveInfo rootSlave = null)
        {
            var networkInterface = NetworkInterface
                                   .GetAllNetworkInterfaces()
                                   .Where(nic => nic.Name == _settings.InterfaceName)
                                   .FirstOrDefault();

            if (networkInterface?.OperationalStatus != OperationalStatus.Up)
            {
                throw new Exception($"Network interface '{_settings.InterfaceName}' is not linked. Aborting action.");
            }

            #region "PreOp"

            var actualSlave = EcUtilities.ScanDevices(this.Context, _settings.InterfaceName, null);

            if (rootSlave == null)
            {
                rootSlave = actualSlave;

                rootSlave.Descendants().ToList().ForEach(current =>
                {
                    EcUtilities.CreateDynamicData(_settings.EsiDirectoryPath, current);
                });
            }

            var slaves       = rootSlave.Descendants().ToList();
            var actualSlaves = actualSlave.Descendants().ToList();

            this.ValidateSlaves(slaves, actualSlaves);
            this.ConfigureSlaves(slaves);
            this.ConfigureIoMap(slaves);
            this.ConfigureDc();
            this.ConfigureSync01(slaves);

            #endregion

            #region "SafeOp"

            EcUtilities.CheckErrorCode(this.Context, EcHL.CheckSafeOpState(this.Context), nameof(EcHL.CheckSafeOpState));

            #endregion

            #region "Op"

            EcUtilities.CheckErrorCode(this.Context, EcHL.RequestCommonState(this.Context, (UInt16)SlaveState.Operational), nameof(EcHL.RequestCommonState));

            #endregion

            if (_watchdogTask == null)
            {
                _watchdogTask = Task.Run(() => this.WatchdogRoutine(), _cts.Token);
            }
        }
예제 #7
0
        private void ConfigureSlaves(IList <SlaveInfo> slaveInfoSet)
        {
            List <EcHL.PO2SOCallback> callbackSet;

            callbackSet = new List <EcHL.PO2SOCallback>();

            foreach (SlaveInfo slaveInfo in slaveInfoSet)
            {
                ushort currentSlaveIndex;
                IEnumerable <SlaveExtensionLogic> extensionSet;
                IEnumerable <SdoWriteRequest>     sdoWriteRequestSet;
                EcHL.PO2SOCallback callback;

                // SDO / PDO config / PDO assign
                currentSlaveIndex = (ushort)(Convert.ToUInt16(slaveInfoSet.ToList().IndexOf(slaveInfo)) + 1);
                extensionSet      = slaveInfo.SlaveExtensionSet.Select(slaveExtension => _extensionFactory.BuildLogic <SlaveExtensionLogic>(slaveExtension)).ToList();

                sdoWriteRequestSet = slaveInfo.GetConfiguration(extensionSet).ToList();

                callback = slaveIndex =>
                {
                    sdoWriteRequestSet.ToList().ForEach(sdoWriteRequest =>
                    {
                        EcUtilities.CheckErrorCode(this.Context, EcUtilities.SdoWrite(this.Context, slaveIndex, sdoWriteRequest.Index, sdoWriteRequest.SubIndex, sdoWriteRequest.Dataset), nameof(EcHL.SdoWrite));
                    });

                    return(0);
                };

                EcHL.RegisterCallback(this.Context, currentSlaveIndex, callback);
                callbackSet.Add(callback);
            }

            callbackSet.ForEach(callback =>
            {
                GC.KeepAlive(callback);
            });
        }
예제 #8
0
        private void ConfigureSync01(IList <SlaveInfo> slaves)
        {
            // SYNC0 / SYNC1
            foreach (var slave in slaves)
            {
                var slaveIndex = (ushort)(Convert.ToUInt16(slaves.ToList().IndexOf(slave)) + 1);
                var distributedClocksSettings = slave
                                                .Extensions
                                                .OfType <DistributedClocksExtension>()
                                                .ToList()
                                                .FirstOrDefault();

                if (distributedClocksSettings != null)
                {
                    if (!slave.Esi.Dc.TimeLoopControlOnly)
                    {
                        byte[] assignActivate = null;
                        var    parameters     = distributedClocksSettings.CalculateDcParameters(ref assignActivate, _settings.CycleFrequency);
                        EcUtilities.CheckErrorCode(this.Context, EcHL.ConfigureSync01(this.Context, slaveIndex, ref assignActivate, assignActivate.Count(), parameters.CycleTime0, parameters.CycleTime1, parameters.ShiftTime0));
                    }
                }
            }
        }