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)); } } } }
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); }); }
public static SlaveInfo RescanDevices(EcSettings settings, SlaveInfo referenceRootSlave) { var referenceSlaves = default(IEnumerable <SlaveInfo>); if (referenceRootSlave != null) { referenceSlaves = referenceRootSlave.Descendants().ToList(); } var newRootSlave = EcUtilities.ScanDevices(settings.InterfaceName, referenceRootSlave); newRootSlave.Descendants().ToList().ForEach(slave => { var referenceSlave = slave.Csa == slave.OldCsa ? referenceSlaves?.FirstOrDefault(x => x.Csa == slave.Csa) : null; if (referenceSlave != null) { slave.Extensions = referenceSlave.Extensions; } EcUtilities.CreateDynamicData(settings.EsiDirectoryPath, slave); }); return(newRootSlave); }
/// <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)); }
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"); }
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); } }
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); } }
public static OneDasDataType GetOneDasDataTypeFromEthercatDataType(string value) { if (value == null) { return(0); } else { return(EcUtilities.GetOneDasDataTypeFromEthercatDataType((EthercatDataType)Enum.Parse(typeof(EthercatDataType), value))); } }
public static SlaveInfo ScanDevices(string interfaceName, SlaveInfo referenceSlaveInfo = null) { IntPtr context; SlaveInfo slaveInfo; context = EcHL.CreateContext(); slaveInfo = EcUtilities.ScanDevices(context, interfaceName, referenceSlaveInfo); EcHL.FreeContext(context); return(slaveInfo); }
public static SlaveInfo ScanDevices(string interfaceName, SlaveInfo referenceRootSlave = null) { if (NetworkInterface.GetAllNetworkInterfaces().Where(x => x.Name == interfaceName).FirstOrDefault()?.OperationalStatus != OperationalStatus.Up) { throw new Exception($"The network interface '{interfaceName}' is not linked. Aborting action."); } var context = EcHL.CreateContext(); var rootSlave = EcUtilities.ScanDevices(context, interfaceName, referenceRootSlave); EcHL.FreeContext(context); return(rootSlave); }
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); }); }
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)); } } } }
public static void CreateDynamicData(string esiDirectoryPath, SlaveInfo slave) { // find ESI if (slave.Csa != 0) { (slave.Esi, slave.EsiGroup) = EsiUtilities.FindEsi(esiDirectoryPath, slave.Manufacturer, slave.ProductCode, slave.Revision); } // var pdos = new List <SlavePdo>(); var base64ImageData = new byte[] { }; var name = slave.Esi.Type.Value; var description = slave.Esi.Name.FirstOrDefault()?.Value; if (description.StartsWith(name)) { description = description.Substring(name.Length); } else if (string.IsNullOrWhiteSpace(description)) { description = "no description available"; } // PDOs foreach (DataDirection dataDirection in Enum.GetValues(typeof(DataDirection))) { IEnumerable <PdoType> pdoTypes = null; switch (dataDirection) { case DataDirection.Output: pdoTypes = slave.Esi.RxPdo; break; case DataDirection.Input: pdoTypes = slave.Esi.TxPdo; break; } foreach (var pdoType in pdoTypes) { var osMax = Convert.ToUInt16(pdoType.OSMax); if (osMax == 0) { var pdoName = pdoType.Name.First().Value; var pdoIndex = (ushort)EsiUtilities.ParseHexDecString(pdoType.Index.Value); var syncManager = pdoType.SmSpecified ? pdoType.Sm : -1; var slavePdo = new SlavePdo(slave, pdoName, pdoIndex, osMax, pdoType.Fixed, pdoType.Mandatory, syncManager); pdos.Add(slavePdo); var slaveVariables = pdoType.Entry.Select(x => { var variableIndex = (ushort)EsiUtilities.ParseHexDecString(x.Index.Value); var subIndex = Convert.ToByte(x.SubIndex); //// Improve. What about -1 if SubIndex does not exist? return(new SlaveVariable(slavePdo, x.Name?.FirstOrDefault()?.Value, variableIndex, subIndex, dataDirection, EcUtilities.ParseEtherCatDataType(x.DataType?.Value), (byte)x.BitLen)); }).ToList(); slavePdo.SetVariables(slaveVariables); } else { for (ushort indexOffset = 0; indexOffset <= osMax - 1; indexOffset++) { var pdoName = $"{pdoType.Name.First().Value} [{indexOffset}]"; var pdoIndex = (ushort)((ushort)EsiUtilities.ParseHexDecString(pdoType.Index.Value) + indexOffset); var syncManager = pdoType.SmSpecified ? pdoType.Sm : -1; var indexOffset_Tmp = indexOffset; var slavePdo = new SlavePdo(slave, pdoName, pdoIndex, osMax, pdoType.Fixed, pdoType.Mandatory, syncManager); pdos.Add(slavePdo); var slaveVariables = pdoType.Entry.Select(x => { var variableIndex = (ushort)EsiUtilities.ParseHexDecString(x.Index.Value); var subIndex = (byte)(byte.Parse(x.SubIndex) + indexOffset_Tmp); //// Improve. What about -1 if SubIndex does not exist? return(new SlaveVariable(slavePdo, x.Name.FirstOrDefault()?.Value, variableIndex, subIndex, dataDirection, EcUtilities.ParseEtherCatDataType(x.DataType?.Value), (byte)x.BitLen)); }).ToList(); slavePdo.SetVariables(slaveVariables); } } } } // image data if (slave.EsiGroup.ItemElementName == ItemChoiceType1.ImageData16x14) { base64ImageData = (byte[])slave.EsiGroup.Item; } if (slave.Esi.ItemElementName.ToString() == nameof(ItemChoiceType1.ImageData16x14)) { base64ImageData = (byte[])slave.Esi.Item; } // attach dynamic data slave.DynamicData = new SlaveInfoDynamicData(name, description, pdos, base64ImageData); // add DC extension to extensions if (slave.Esi.Dc is not null && !slave.Extensions.Any(extension => extension.GetType() == typeof(DistributedClocksExtension))) { slave.Extensions.Add(new DistributedClocksExtension(slave)); } // execute extension logic slave.Extensions.ToList().ForEach(extension => { extension.EvaluateSettings(); }); }
public static SlavePdo[] UploadPdoConfig(IntPtr context, UInt16 slave, UInt16 smIndex) { int pdoCount; IntPtr ecPdoInfoPtrSet; SlavePdo[] slavePdoSet; SyncManagerType syncManagerType; DataDirection dataDirection; // EcHL.GetSyncManagerType(context, slave, smIndex, out syncManagerType); switch (syncManagerType) { case SyncManagerType.Inputs: dataDirection = DataDirection.Input; break; case SyncManagerType.Outputs: dataDirection = DataDirection.Output; break; default: throw new ArgumentException(); } EcHL.UploadPdoConfig(context, slave, smIndex, out ecPdoInfoPtrSet, out pdoCount); slavePdoSet = Enumerable.Range(0, pdoCount).Select(index => { ec_pdo_info_t ecPdoInfo; SlavePdo slavePdo; IntPtr ecPdoInfoPtr; ecPdoInfoPtr = IntPtr.Add(ecPdoInfoPtrSet, index * Marshal.SizeOf(typeof(ec_pdo_info_t))); ecPdoInfo = Marshal.PtrToStructure <ec_pdo_info_t>(ecPdoInfoPtr); slavePdo = new SlavePdo(null, ecPdoInfo.name, ecPdoInfo.index, 0, true, true, smIndex - 0x1C10); slavePdo.SetVariableSet(Enumerable.Range(0, ecPdoInfo.variableCount).Select(index2 => { ec_variable_info_t ecVariableInfo; SlaveVariable slaveVariable; IntPtr ecVariableInfoPtr; ecVariableInfoPtr = IntPtr.Add(ecPdoInfo.variableInfoSet, index2 * Marshal.SizeOf(typeof(ec_variable_info_t))); ecVariableInfo = Marshal.PtrToStructure <ec_variable_info_t>(ecVariableInfoPtr); slaveVariable = new SlaveVariable(slavePdo, ecVariableInfo.name, ecVariableInfo.index, ecVariableInfo.subIndex, dataDirection, EcUtilities.GetOneDasDataTypeFromEthercatDataType(ecVariableInfo.dataType)); return(slaveVariable); }).ToList()); EcHL.Free(ecPdoInfo.variableInfoSet); return(slavePdo); }).ToArray(); EcHL.Free(ecPdoInfoPtrSet); return(slavePdoSet); }