Example #1
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));
        }
Example #2
0
        private static bool EnsureValidCsa(IntPtr context, ec_slave_info_t[] newSlaves, ec_slave_info_t[] referenceSlaves)
        {
            // UPDATE: first step ('isValid') is skipped as CSA is now generated randomly. This function returns now a boolean to indicate success.
            //
            //
            //
            // Idea:
            // 1. isValid: select all slaves whose CSA is greater than zero but smaller than the CSA-base
            //
            // 2. hasUniqueCsa: select all slaves with overall unique CSA (both lists)
            //
            // 3. toBeProtected: select all slaves of new list that are distinct (comparison of CSA is not sufficient) and have counterpart in reference list
            //    -> throw out all slaves where reference CSA is not unique
            //
            // 4. Combination: isValid & (hasUniqueCsa | toBeProtected)
            //
            // ## EXAMPLE ##                                                * -> indicates that new slave is identical to referenced slave
            //
            // CSA base             : 7
            //
            //  reference slave CSAs: 1 1 2 3
            //        new slave CSAs: 1*| 2  2*| 3  3* 3* | 4 | 9 | 0
            //
            //
            //                hasRef: 1 | 0  1 | 0  1  1  | 0 | 0 | 0
            //            isDistinct: 1 | 1  1 | 1  0  0  | 1 | 1 | 1
            //      hasUniqueCsa_ref: 0 | 1  1 | 1  1  1  | 0 | 0 | 0
            //                        ===============================
            //         toBeProtected: 0 | 0  1 | 0  0  0  | 0 | 0 | 0
            //
            //
            //        new slave CSAs: 1*| 2  2*| 3  3* 3* | 4 | 9 | 0
            //                        _______________________________
            //               isValid: 1 | 1  1 | 1  1  1  | 1 | 0 | 0
            //          hasUniqueCsa: 0 | 0  1 | 0  0  0  | 1 | 1 | 1
            //         toBeProtected: 0 | 0  1 | 0  0  0  | 0 | 0 | 0
            //                        ===============================
            //                result: 0 | 0  1 | 0  0  0  | 1 | 0 | 0
            //
            // 5. take all slaves whose result is '0' and update their CSA
            //                result: 7 | 8  2 | 9  10 11 | 4 | 12| 13

            //// reference
            //var reference1 = new ec_slave_info_t() { csa = 1, manufacturer = 2, productCode = 2, revision = 2 }; // 1
            //var reference2 = new ec_slave_info_t() { csa = 1, manufacturer = 3, productCode = 2, revision = 2 }; // 1
            //var reference3 = new ec_slave_info_t() { csa = 2, manufacturer = 2, productCode = 2, revision = 2 }; // 2
            //var reference4 = new ec_slave_info_t() { csa = 3, manufacturer = 2, productCode = 2, revision = 2 }; // 3
            //var reference = new ec_slave_info_t[] { reference1, reference2, reference3, reference4 };

            //// new
            //var new1 = new ec_slave_info_t() { csa = 1, manufacturer = 2, productCode = 2, revision = 2 }; // 1
            //var new2 = new ec_slave_info_t() { csa = 2, manufacturer = 2, productCode = 3, revision = 2 }; // 2
            //var new3 = new ec_slave_info_t() { csa = 2, manufacturer = 2, productCode = 2, revision = 2 }; // 2
            //var new4 = new ec_slave_info_t() { csa = 3, manufacturer = 7, productCode = 2, revision = 2 }; // 3
            //var new5 = new ec_slave_info_t() { csa = 3, manufacturer = 2, productCode = 2, revision = 2 }; // 3
            //var new6 = new ec_slave_info_t() { csa = 3, manufacturer = 2, productCode = 2, revision = 2 }; // 3
            //var new7 = new ec_slave_info_t() { csa = 4, manufacturer = 2, productCode = 2, revision = 2 }; // 4
            //var new8 = new ec_slave_info_t() { csa = 9, manufacturer = 2, productCode = 2, revision = 2 }; // 9
            //var new9 = new ec_slave_info_t() { csa = 0, manufacturer = 2, productCode = 2, revision = 2 }; // 0
            //var newset = new ec_slave_info_t[] { new1, new2, new3, new4, new5, new6, new7, new8, new9 };

            //Settings.Default.CsaBase = 7;

            //SoemWrapper.ValidateCsa(newset, reference);

            var totalSlaves                = newSlaves.Concat(referenceSlaves).ToArray();
            var totalSlavesCsaDistinct     = totalSlaves.Select(x => x.csa).TrueDistinct().ToArray();
            var newSlavesDistinct          = newSlaves.TrueDistinct().ToArray();
            var referenceSlavesCsaDistinct = referenceSlaves.Select(x => x.csa).TrueDistinct().ToArray();
            var hasCsaChanged              = false;

            for (int i = 0; i < newSlaves.Count(); i++)
            {
                ec_slave_info_t newSlave = newSlaves[i];

                // 1. - isValid
                var isValid = true; // isValid = newSlave.csa > 0 && newSlave.csa < originalCsaBase;

                // 2. - hasUniqueCsa
                var hasUniqueCsa = totalSlavesCsaDistinct.Contains(newSlave.csa);

                // 3. - toBeProtected

                // => hasRef
                var referenceSlave = referenceSlaves.FirstOrDefault(x => x.csa == newSlave.csa);

                var hasRef = referenceSlave.csa == newSlave.csa &&
                             referenceSlave.manufacturer == newSlave.manufacturer &&
                             referenceSlave.productCode == newSlave.productCode &&
                             referenceSlave.revision == newSlave.revision;

                // => isDistinct
                var isDistinct = newSlavesDistinct.Contains(newSlave);

                // => hasUniqueCsa_ref
                var hasUniqueCsa_ref = referenceSlavesCsaDistinct.Contains(newSlave.csa);

                // => toBeProtected
                var toBeProtected = hasRef && isDistinct && hasUniqueCsa_ref;

                // 4. Combination
                if (i > 0 && !(isValid && (hasUniqueCsa || toBeProtected)))
                {
                    var csaValue = (ushort)_random.Next(1, ushort.MaxValue);
                    EcHL.UpdateCsa(context, newSlaves.ToList().IndexOf(newSlave), csaValue);
                    newSlave.csa  = csaValue;
                    newSlaves[i]  = newSlave;
                    hasCsaChanged = true;
                }
            }

            return(hasCsaChanged);
        }