diff --git a/components/free_rtos/ethernet_industry/CoE/eth_ecat_pdo_fmmu.cpp b/components/free_rtos/ethernet_industry/CoE/eth_ecat_pdo_fmmu.cpp index 9909060..c2dd31b 100644 --- a/components/free_rtos/ethernet_industry/CoE/eth_ecat_pdo_fmmu.cpp +++ b/components/free_rtos/ethernet_industry/CoE/eth_ecat_pdo_fmmu.cpp @@ -63,10 +63,12 @@ void EthEcatPdoFMMU::wait_op() { void EthEcatPdoFMMU::process() { std::array, 2> process_data; + process_data[0].fill(0x00); + process_data[1].fill(0x00); + wait_op(); - while(1) - { + while(1) { read(process_data[0], process_data[1]); /* for(uint8_t& byte : process_data[0]) { diff --git a/components/free_rtos/ethernet_industry/CoE/eth_ecat_pdo_fmmu.hpp b/components/free_rtos/ethernet_industry/CoE/eth_ecat_pdo_fmmu.hpp index 460768e..7033cae 100644 --- a/components/free_rtos/ethernet_industry/CoE/eth_ecat_pdo_fmmu.hpp +++ b/components/free_rtos/ethernet_industry/CoE/eth_ecat_pdo_fmmu.hpp @@ -39,6 +39,34 @@ private: ecat_buffer::EcatBufferSlave& buffer_slave_; }; +// Функтор для работы с датаграммами в custom_tuple +struct DatagramFunctor { + datagram::EcatTelegram& telegram; + size_t number_of_slaves; + + // Первый/последний вызов при forward/reverse обходе custom_tuple + template + void operator()(DatagramT& datagram) { + do { + telegram.transfer(datagram); + } while(datagram.get_all_wkc() < number_of_slaves); + } + + // Последующие вызовы в custom_tuple + template + void operator()(DatagramT& datagram, DatagramPreviousT& previous) { + previous + datagram; + } + + // Последний/первый вызов при forward/reverse обходе custom_tuple. + // Второй аргумент нужен для корректной перегрузки, чтобы отличить от первой сигнатуры + template + void operator()(DatagramPreviousT& previous, uint32_t) { } + + // Пустой custom_tuple + void operator()() { } +}; + class EthEcatPdoFMMU { public: EthEcatPdoFMMU(ecat_buffer::EthEcatBuffer& ecat_mailbox): ecat_buffer_{ecat_mailbox} { } @@ -46,28 +74,48 @@ public: void init(); void process(); - template - void write(DataType& head, DataTypes&... tail) { - if(sizeof...(tail) + 1 > pdo_fmmu_slaves_.size()) { + template + void write(DataTypes&... data) { + if(sizeof...(data) > pdo_fmmu_slaves_.size()) { return; } - size_t slave_index = 0; - auto datagram = pdo_fmmu_slaves_[slave_index].make_datagram_write(head); - // Сборка и отправка телеграммы с "головы" - write_recursion(slave_index + 1, datagram, datagram, tail...); + size_t i = 0; + custom_tuple...> datagram_tuple{pdo_fmmu_slaves_[i++].make_datagram_write(data)...}; + DatagramFunctor functor{ecat_buffer_.get_ecat().get_telegram(), pdo_fmmu_slaves_.size()}; + + datagram_tuple.for_each_reverse(functor); } - template - void read(DataType& head, DataTypes&... tail) { - if(sizeof...(tail) + 1 > pdo_fmmu_slaves_.size()) { + template + void read(DataTypes&... data) { + if(sizeof...(data) > pdo_fmmu_slaves_.size()) { return; } - size_t slave_index = 0; - auto datagram = pdo_fmmu_slaves_[slave_index].make_datagram_read(head); - // Сборка и отправка телеграммы с "головы" - read_recursion(slave_index + 1, datagram, datagram, tail...); + size_t i = 0; + custom_tuple...> datagram_tuple{pdo_fmmu_slaves_[i++].make_datagram_read(data)...}; + DatagramFunctor functor{ecat_buffer_.get_ecat().get_telegram(), pdo_fmmu_slaves_.size()}; + + datagram_tuple.for_each_reverse(functor); + } + + template + void read_write(DataTypes&... data) { + if(sizeof...(data) > pdo_fmmu_slaves_.size()) { + return; + } + + size_t i = 0; + size_t j = 0; + + // custom_tuple с датаграммами и на чтение и на запись в две строки. 1 строка - тип, 2 - строка имя переменной + custom_tuple... , datagram::EcatDatagram...> + datagram_tuple{pdo_fmmu_slaves_[i++].make_datagram_read(data)... , pdo_fmmu_slaves_[j++].make_datagram_write(data)...}; + + DatagramFunctor functor{ecat_buffer_.get_ecat().get_telegram(), pdo_fmmu_slaves_.size()}; + + datagram_tuple.for_each_reverse(functor); } private: @@ -75,45 +123,6 @@ private: std::vector pdo_fmmu_slaves_; - template - void write_recursion(size_t slave_index, DatagramTypeFirst& first, DatagramTypePrevious& previous, DataTypes&... data); - - template - void write_recursion(size_t slave_index, DatagramTypeFirst& first, DatagramTypePrevious& previous, DataType& head, DataTypes&... tail) { - auto datagram = pdo_fmmu_slaves_[slave_index].make_datagram_write(head); - - write_recursion(slave_index + 1, first, previous + datagram, tail...); - } - - template - void write_recursion(size_t slave_index, DatagramTypeFirst& first, DatagramTypePrevious& previous) { - datagram::EcatTelegram& telegram = ecat_buffer_.get_ecat().get_telegram(); - - do { - telegram.transfer(first); - } while(first.get_all_wkc() < slave_index); - } - - - template - void read_recursion(size_t slave_index, DatagramTypeFirst& first, DatagramTypePrevious& previous, DataTypes&... data); - - template - void read_recursion(size_t slave_index, DatagramTypeFirst& first, DatagramTypePrevious& previous, DataType& head, DataTypes&... tail) { - auto datagram = pdo_fmmu_slaves_[slave_index].make_datagram_read(head); - - read_recursion(slave_index + 1, first, previous + datagram, tail...); - } - - template - void read_recursion(size_t slave_index, DatagramTypeFirst& first, DatagramTypePrevious& previous) { - datagram::EcatTelegram& telegram = ecat_buffer_.get_ecat().get_telegram(); - - do { - telegram.transfer(first); - } while(first.get_all_wkc() < slave_index); - } - void wait_op(); }; diff --git a/components/free_rtos/ethernet_industry/eth_ecat_custom_tuple.hpp b/components/free_rtos/ethernet_industry/eth_ecat_custom_tuple.hpp index c746c17..a44c906 100644 --- a/components/free_rtos/ethernet_industry/eth_ecat_custom_tuple.hpp +++ b/components/free_rtos/ethernet_industry/eth_ecat_custom_tuple.hpp @@ -47,6 +47,30 @@ struct custom_tuple : custom_tuple { return TBase::unpack(raw + sizeof(THeadDeref)); } + + template + void for_each(FunctorT& functor) { + functor(head_); + TBase::template for_each(functor, head_); + } + + template + void for_each(FunctorT& functor, PreviousT& previous) { + functor(head_, previous); + TBase::template for_each(functor, head_); + } + + template + void for_each_reverse(FunctorT& functor) { + TBase::template for_each_reverse(functor, head_); + functor(head_); + } + + template + void for_each_reverse(FunctorT& functor, PreviousT& previous) { + TBase::template for_each_reverse(functor, head_); + functor(head_, previous); + } }; // Специализация завершения рекурсии @@ -61,6 +85,28 @@ struct custom_tuple<> { uint8_t* unpack(uint8_t *raw) { return raw; } + + // Вызывается для пустого custom_tuple. Не особо полезно, но пускай будет + template + void for_each_forward(FunctorT& functor) { + functor(); + } + + template + void for_each_forward(FunctorT& functor, PreviousT& previous) { + functor(previous, 0); + } + + // Вызывается для пустого custom_tuple. Не особо полезно, но пускай будет + template + void for_each_reverse(FunctorT& functor) { + functor(); + } + + template + void for_each_reverse(FunctorT& functor, PreviousT& previous) { + functor(previous, 0); + } }; template