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() {
std::array<std::array<uint8_t, 55>, 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]) {

View File

@ -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<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 {
public:
EthEcatPdoFMMU(ecat_buffer::EthEcatBuffer& ecat_mailbox): ecat_buffer_{ecat_mailbox} { }
@ -46,28 +74,48 @@ public:
void init();
void process();
template<typename DataType, typename... DataTypes>
void write(DataType& head, DataTypes&... tail) {
if(sizeof...(tail) + 1 > pdo_fmmu_slaves_.size()) {
template<typename... DataTypes>
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::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()};
datagram_tuple.for_each_reverse(functor);
}
template<typename DataType, typename... DataTypes>
void read(DataType& head, DataTypes&... tail) {
if(sizeof...(tail) + 1 > pdo_fmmu_slaves_.size()) {
template<typename... DataTypes>
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::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()};
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:
@ -75,45 +123,6 @@ private:
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();
};

View File

@ -47,6 +47,30 @@ struct custom_tuple<HeadT, TailT...> : custom_tuple<TailT...> {
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) {
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>