dev(UML-1462): Переделал передачу датаграмм в одном фрейме. Еще не проверял, но выглядит красиво

This commit is contained in:
algin 2023-05-29 13:39:52 +03:00
parent 059aaa7f3d
commit 3221451fd8
3 changed files with 112 additions and 55 deletions

View File

@ -63,10 +63,12 @@ void EthEcatPdoFMMU::wait_op() {
void EthEcatPdoFMMU::process() { void EthEcatPdoFMMU::process() {
std::array<std::array<uint8_t, 55>, 2> process_data; std::array<std::array<uint8_t, 55>, 2> process_data;
process_data[0].fill(0x00);
process_data[1].fill(0x00);
wait_op(); wait_op();
while(1) while(1) {
{
read(process_data[0], process_data[1]); read(process_data[0], process_data[1]);
/* /*
for(uint8_t& byte : process_data[0]) { for(uint8_t& byte : process_data[0]) {

View File

@ -39,6 +39,34 @@ private:
ecat_buffer::EcatBufferSlave& buffer_slave_; ecat_buffer::EcatBufferSlave& buffer_slave_;
}; };
// Функтор для работы с датаграммами в custom_tuple
struct DatagramFunctor {
datagram::EcatTelegram& telegram;
size_t number_of_slaves;
// Первый/последний вызов при forward/reverse обходе custom_tuple
template<typename DatagramT>
void operator()(DatagramT& datagram) {
do {
telegram.transfer(datagram);
} while(datagram.get_all_wkc() < number_of_slaves);
}
// Последующие вызовы в custom_tuple
template<typename DatagramT, typename DatagramPreviousT>
void operator()(DatagramT& datagram, DatagramPreviousT& previous) {
previous + datagram;
}
// Последний/первый вызов при forward/reverse обходе custom_tuple.
// Второй аргумент нужен для корректной перегрузки, чтобы отличить от первой сигнатуры
template<typename DatagramPreviousT>
void operator()(DatagramPreviousT& previous, uint32_t) { }
// Пустой custom_tuple
void operator()() { }
};
class EthEcatPdoFMMU { class EthEcatPdoFMMU {
public: public:
EthEcatPdoFMMU(ecat_buffer::EthEcatBuffer& ecat_mailbox): ecat_buffer_{ecat_mailbox} { } EthEcatPdoFMMU(ecat_buffer::EthEcatBuffer& ecat_mailbox): ecat_buffer_{ecat_mailbox} { }
@ -46,28 +74,48 @@ public:
void init(); void init();
void process(); void process();
template<typename DataType, typename... DataTypes> template<typename... DataTypes>
void write(DataType& head, DataTypes&... tail) { void write(DataTypes&... data) {
if(sizeof...(tail) + 1 > pdo_fmmu_slaves_.size()) { if(sizeof...(data) > pdo_fmmu_slaves_.size()) {
return; return;
} }
size_t slave_index = 0; size_t i = 0;
auto datagram = pdo_fmmu_slaves_[slave_index].make_datagram_write(head); custom_tuple<datagram::EcatDatagram<command::LWR, DataTypes>...> datagram_tuple{pdo_fmmu_slaves_[i++].make_datagram_write(data)...};
// Сборка и отправка телеграммы с "головы" DatagramFunctor functor{ecat_buffer_.get_ecat().get_telegram(), pdo_fmmu_slaves_.size()};
write_recursion(slave_index + 1, datagram, datagram, tail...);
datagram_tuple.for_each_reverse(functor);
} }
template<typename DataType, typename... DataTypes> template<typename... DataTypes>
void read(DataType& head, DataTypes&... tail) { void read(DataTypes&... data) {
if(sizeof...(tail) + 1 > pdo_fmmu_slaves_.size()) { if(sizeof...(data) > pdo_fmmu_slaves_.size()) {
return; return;
} }
size_t slave_index = 0; size_t i = 0;
auto datagram = pdo_fmmu_slaves_[slave_index].make_datagram_read(head); custom_tuple<datagram::EcatDatagram<command::LRD, DataTypes>...> datagram_tuple{pdo_fmmu_slaves_[i++].make_datagram_read(data)...};
// Сборка и отправка телеграммы с "головы" DatagramFunctor functor{ecat_buffer_.get_ecat().get_telegram(), pdo_fmmu_slaves_.size()};
read_recursion(slave_index + 1, datagram, datagram, tail...);
datagram_tuple.for_each_reverse(functor);
}
template<typename... DataTypes>
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<command::LRD, DataTypes>... , datagram::EcatDatagram<command::LWR, DataTypes>...>
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: private:
@ -75,45 +123,6 @@ private:
std::vector<EcatPdoFMMUSlave> pdo_fmmu_slaves_; std::vector<EcatPdoFMMUSlave> pdo_fmmu_slaves_;
template<typename DatagramTypeFirst, typename DatagramTypePrevious, typename... DataTypes>
void write_recursion(size_t slave_index, DatagramTypeFirst& first, DatagramTypePrevious& previous, DataTypes&... data);
template<typename DatagramTypeFirst, typename DatagramTypePrevious, typename DataType, typename... DataTypes>
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<typename DatagramTypeFirst, typename DatagramTypePrevious>
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<typename DatagramTypeFirst, typename DatagramTypePrevious, typename... DataTypes>
void read_recursion(size_t slave_index, DatagramTypeFirst& first, DatagramTypePrevious& previous, DataTypes&... data);
template<typename DatagramTypeFirst, typename DatagramTypePrevious, typename DataType, typename... DataTypes>
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<typename DatagramTypeFirst, typename DatagramTypePrevious>
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(); void wait_op();
}; };

View File

@ -47,6 +47,30 @@ struct custom_tuple<HeadT, TailT...> : custom_tuple<TailT...> {
return TBase::unpack(raw + sizeof(THeadDeref)); return TBase::unpack(raw + sizeof(THeadDeref));
} }
template<typename FunctorT>
void for_each(FunctorT& functor) {
functor(head_);
TBase::template for_each<FunctorT>(functor, head_);
}
template<typename FunctorT, typename PreviousT>
void for_each(FunctorT& functor, PreviousT& previous) {
functor(head_, previous);
TBase::template for_each<FunctorT>(functor, head_);
}
template<typename FunctorT>
void for_each_reverse(FunctorT& functor) {
TBase::template for_each_reverse<FunctorT>(functor, head_);
functor(head_);
}
template<typename FunctorT, typename PreviousT>
void for_each_reverse(FunctorT& functor, PreviousT& previous) {
TBase::template for_each_reverse<FunctorT>(functor, head_);
functor(head_, previous);
}
}; };
// Специализация завершения рекурсии // Специализация завершения рекурсии
@ -61,6 +85,28 @@ struct custom_tuple<> {
uint8_t* unpack(uint8_t *raw) { uint8_t* unpack(uint8_t *raw) {
return raw; return raw;
} }
// Вызывается для пустого custom_tuple. Не особо полезно, но пускай будет
template<typename FunctorT>
void for_each_forward(FunctorT& functor) {
functor();
}
template<typename FunctorT, typename PreviousT>
void for_each_forward(FunctorT& functor, PreviousT& previous) {
functor(previous, 0);
}
// Вызывается для пустого custom_tuple. Не особо полезно, но пускай будет
template<typename FunctorT>
void for_each_reverse(FunctorT& functor) {
functor();
}
template<typename FunctorT, typename PreviousT>
void for_each_reverse(FunctorT& functor, PreviousT& previous) {
functor(previous, 0);
}
}; };
template<size_t index, typename TupleT> template<size_t index, typename TupleT>