dev(UML-1462): Доработал custom tuple и мелкие улучшения

This commit is contained in:
algin 2023-05-25 10:20:33 +03:00
parent d356b80aac
commit 95f2cc120e
8 changed files with 171 additions and 134 deletions

View File

@ -21,7 +21,7 @@ void EthEcatPdoFMMU::init() {
} }
} }
void EthEcatPdoFMMU::process() { void EthEcatPdoFMMU::wait_op() {
free_rtos::Semaphore& init_sem = ecat_buffer_.get_ecat().get_init_sem(); free_rtos::Semaphore& init_sem = ecat_buffer_.get_ecat().get_init_sem();
free_rtos::Semaphore& process_sem = ecat_buffer_.get_ecat().get_process_sem(); free_rtos::Semaphore& process_sem = ecat_buffer_.get_ecat().get_process_sem();
std::array<std::array<uint8_t, 55>, 2> process_data; std::array<std::array<uint8_t, 55>, 2> process_data;
@ -31,44 +31,50 @@ void EthEcatPdoFMMU::process() {
process_data[0].fill(0x00); process_data[0].fill(0x00);
process_data[1].fill(0x00); process_data[1].fill(0x00);
read(0, 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]) {
DebugP_log("0x%01x", byte); DebugP_log("0x%01x", byte);
} }
DebugP_log("\r\n"); DebugP_log("\r\n");
*/
write(0, process_data[0], process_data[1]); write(process_data[0], process_data[1]);
init_sem.post(); init_sem.post();
process_sem.pend(); process_sem.pend();
for(uint32_t i = 0; i < 250; i++) { for(uint32_t i = 0; i < 250; i++) {
read(0, 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]) {
DebugP_log("0x%01x", byte); DebugP_log("0x%01x", byte);
} }
DebugP_log("\r\n"); DebugP_log("\r\n");
*/
write(0, process_data[0], process_data[1]); write(process_data[0], process_data[1]);
//ClockP_usleep(125ul); //ClockP_usleep(125ul);
} }
init_sem.post(); init_sem.post();
process_sem.pend(); process_sem.pend();
}
void EthEcatPdoFMMU::process() {
std::array<std::array<uint8_t, 55>, 2> process_data;
wait_op();
while(1) while(1)
{ {
read(0, 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]) {
DebugP_log("0x%01x", byte); DebugP_log("0x%01x", byte);
} }
DebugP_log("\r\n"); DebugP_log("\r\n");
*/
write(0, process_data[0], process_data[1]); write(process_data[0], process_data[1]);
//ClockP_usleep(125ul); //ClockP_usleep(125ul);
} }

View File

@ -48,55 +48,71 @@ private:
}; };
class EthEcatPdoFMMU { class EthEcatPdoFMMU {
public: private:
EthEcatPdoFMMU(ecat_buffer::EthEcatBuffer& ecat_mailbox): ecat_buffer_{ecat_mailbox} { }
void init();
template<typename... DataTypes> template<typename... DataTypes>
void write(size_t slave_index, DataTypes&... data); void write_recursion(datagram::EcatTelegram& telegram, size_t slave_index, DataTypes&... data);
template<typename DataType, typename... DataTypes> template<typename DataType, typename... DataTypes>
void write(size_t slave_index, DataType& head, DataTypes&... tail) { void write_recursion(datagram::EcatTelegram& telegram, size_t slave_index, DataType& head, DataTypes&... tail) {
datagram::EcatTelegram& telegram = ecat_buffer_.get_ecat().get_telegram();
pdo_fmmu_slaves_[slave_index].write(telegram, head); pdo_fmmu_slaves_[slave_index].write(telegram, head);
slave_index++; slave_index++;
if(slave_index < pdo_fmmu_slaves_.size()) { write_recursion(telegram, slave_index, tail...);
write(slave_index, tail...);
}
} }
template<> template<>
void write(size_t slave_index) { } void write_recursion(datagram::EcatTelegram& telegram, size_t slave_index) { }
template<typename... DataTypes> template<typename... DataTypes>
void read(size_t slave_index, DataTypes&... data); void read_recursion(datagram::EcatTelegram& telegram, size_t slave_index, DataTypes&... data);
template<typename DataType, typename... DataTypes> template<typename DataType, typename... DataTypes>
void read(size_t slave_index, DataType& head, DataTypes&... tail) { void read_recursion(datagram::EcatTelegram& telegram, size_t slave_index, DataType& head, DataTypes&... tail) {
datagram::EcatTelegram& telegram = ecat_buffer_.get_ecat().get_telegram();
pdo_fmmu_slaves_[slave_index].read(telegram, head); pdo_fmmu_slaves_[slave_index].read(telegram, head);
slave_index++; slave_index++;
if(slave_index < pdo_fmmu_slaves_.size()) { read_recursion(telegram, slave_index, tail...);
read(slave_index, tail...);
}
} }
template<> template<>
void read(size_t slave_index) { } void read_recursion(datagram::EcatTelegram& telegram, size_t slave_index) { }
public:
EthEcatPdoFMMU(ecat_buffer::EthEcatBuffer& ecat_mailbox): ecat_buffer_{ecat_mailbox} { }
void init();
void process(); void process();
template<typename... DataTypes>
void write(DataTypes&... data) {
datagram::EcatTelegram& telegram = ecat_buffer_.get_ecat().get_telegram();
if(sizeof...(data) > pdo_fmmu_slaves_.size()) {
return;
}
write_recursion(telegram, 0, data...);
}
template<typename... DataTypes>
void read(DataTypes&... data) {
datagram::EcatTelegram& telegram = ecat_buffer_.get_ecat().get_telegram();
if(sizeof...(data) > pdo_fmmu_slaves_.size()) {
return;
}
read_recursion(telegram, 0, data...);
}
private: private:
ecat_buffer::EthEcatBuffer& ecat_buffer_; ecat_buffer::EthEcatBuffer& ecat_buffer_;
std::vector<EcatPdoFMMUSlave> pdo_fmmu_slaves_; std::vector<EcatPdoFMMUSlave> pdo_fmmu_slaves_;
void wait_op();
}; };
} // namespace ecat_pdo_fmmu } // namespace ecat_pdo_fmmu

View File

@ -106,17 +106,17 @@ struct MailboxHeader {
// Специализация шаблона для распаковки протокола CoE // Специализация шаблона для распаковки протокола CoE
template<typename... TailT> template<typename... TailT>
struct CustomTuple<ecat_sdo_mailbox::CoEElements, ecat_sdo_mailbox::CompleteSize, TailT...> : CustomTuple<TailT...> { struct custom_tuple<ecat_sdo_mailbox::CoEElements&, ecat_sdo_mailbox::CompleteSize&, TailT...> : custom_tuple<TailT...> {
CustomTuple(ecat_sdo_mailbox::CoEElements& head, ecat_sdo_mailbox::CompleteSize& complete_size, TailT&... tail) custom_tuple(ecat_sdo_mailbox::CoEElements& head, ecat_sdo_mailbox::CompleteSize& complete_size, TailT... tail)
: CustomTuple<TailT...>(tail...) : custom_tuple<TailT...>(tail...)
, head_(head) , head_(head)
, complete_size_(complete_size) { } , complete_size_(complete_size) { }
using TBase = CustomTuple<TailT...>; using TBase = custom_tuple<TailT...>;
constexpr static size_t size = sizeof(ecat_sdo_mailbox::CoEElements) + sizeof(ecat_sdo_mailbox::CompleteSize) + TBase::size; constexpr static size_t size = sizeof(ecat_sdo_mailbox::CoEElements) + sizeof(ecat_sdo_mailbox::CompleteSize) + TBase::size;
TBase& base_ = static_cast<TBase&>(*this); //TBase& base_ = static_cast<TBase&>(*this);
ecat_sdo_mailbox::CoEElements& head_; ecat_sdo_mailbox::CoEElements& head_;
ecat_sdo_mailbox::CompleteSize& complete_size_; ecat_sdo_mailbox::CompleteSize& complete_size_;
@ -127,13 +127,13 @@ struct CustomTuple<ecat_sdo_mailbox::CoEElements, ecat_sdo_mailbox::CompleteSize
(void)complete_size; (void)complete_size;
raw += sizeof(ecat_sdo_mailbox::CompleteSize); raw += sizeof(ecat_sdo_mailbox::CompleteSize);
raw = base_.pack(raw); raw = TBase::pack(raw);
} }
if(head_.command_specifier.transfer_type == static_cast<uint8_t>(ecat_sdo_mailbox::TransferType::EXPEDITED)) { if(head_.command_specifier.transfer_type == static_cast<uint8_t>(ecat_sdo_mailbox::TransferType::EXPEDITED)) {
// По-нормальному мы не должны сюда попадать, т.к. в expedited транзакции не должно быть блока CompleteSize, // По-нормальному мы не должны сюда попадать, т.к. в expedited транзакции не должно быть блока CompleteSize,
// значит либо пользователь ошибся, либо после предыдущей отправки датаграммы слейв указал тип expedited // значит либо пользователь ошибся, либо после предыдущей отправки датаграммы слейв указал тип expedited
raw = base_.pack(raw); raw = TBase::pack(raw);
raw += sizeof(ecat_sdo_mailbox::CompleteSize); raw += sizeof(ecat_sdo_mailbox::CompleteSize);
} }
@ -155,11 +155,11 @@ struct CustomTuple<ecat_sdo_mailbox::CoEElements, ecat_sdo_mailbox::CompleteSize
complete_size_ = *complete_size; complete_size_ = *complete_size;
raw += sizeof(ecat_sdo_mailbox::CompleteSize); raw += sizeof(ecat_sdo_mailbox::CompleteSize);
raw = base_.unpack(raw); raw = TBase::unpack(raw);
} }
if(head_.command_specifier.transfer_type == static_cast<uint8_t>(ecat_sdo_mailbox::TransferType::EXPEDITED)) { if(head_.command_specifier.transfer_type == static_cast<uint8_t>(ecat_sdo_mailbox::TransferType::EXPEDITED)) {
raw = base_.unpack(raw); raw = TBase::unpack(raw);
raw += sizeof(ecat_sdo_mailbox::CompleteSize); raw += sizeof(ecat_sdo_mailbox::CompleteSize);
} }
@ -239,7 +239,7 @@ public:
auto slave_address = slave.get_slave_address<TypeT>(); auto slave_address = slave.get_slave_address<TypeT>();
std::array<address::Offset, 4>& buffer_regs = buffer_slave_.get_buffer_regs(); std::array<address::Offset, 4>& buffer_regs = buffer_slave_.get_buffer_regs();
MailboxHeader header{ MailboxHeader header{
.length = CustomTuple<DataTypes...>::size, .length = custom_tuple<DataTypes...>::size,
.address = 0, // slave.get_slave_address<command::FP>() .address = 0, // slave.get_slave_address<command::FP>()
.channel = channel, .channel = channel,
.priority = priority, .priority = priority,
@ -247,7 +247,7 @@ public:
.cnt = static_cast<uint16_t>(counter_) .cnt = static_cast<uint16_t>(counter_)
}; };
datagram::EcatDatagram<TCommand, MailboxHeader, DataTypes...> datagram{ {{slave_address, buffer_regs[MailboxesRegs::WRITE]}}, header, data... }; datagram::EcatDatagram<TCommand, MailboxHeader, DataTypes...> datagram{ {{slave_address, buffer_regs[MailboxesRegs::WRITE]}}, header, data... };
uint16_t padding = buffer_slave_.get_buffer_properties_write().length - sizeof(MailboxHeader) - CustomTuple<DataTypes...>::size; uint16_t padding = buffer_slave_.get_buffer_properties_write().length - sizeof(MailboxHeader) - custom_tuple<DataTypes...>::size;
datagram.set_padding(padding); datagram.set_padding(padding);
@ -266,7 +266,7 @@ public:
std::array<address::Offset, 4>& buffer_regs = buffer_slave_.get_buffer_regs(); std::array<address::Offset, 4>& buffer_regs = buffer_slave_.get_buffer_regs();
MailboxHeader header; MailboxHeader header;
datagram::EcatDatagram<TCommand, MailboxHeader, DataTypes...> datagram{ {{slave_address, buffer_regs[MailboxesRegs::READ]}}, header, data... }; datagram::EcatDatagram<TCommand, MailboxHeader, DataTypes...> datagram{ {{slave_address, buffer_regs[MailboxesRegs::READ]}}, header, data... };
uint16_t padding = buffer_slave_.get_buffer_properties_read().length - sizeof(MailboxHeader) - CustomTuple<DataTypes...>::size; uint16_t padding = buffer_slave_.get_buffer_properties_read().length - sizeof(MailboxHeader) - custom_tuple<DataTypes...>::size;
datagram.set_padding(padding); datagram.set_padding(padding);

View File

@ -125,20 +125,20 @@ void EthEcat::set_slaves_to_default() {
uint8_t m_data_out{0x00}; uint8_t m_data_out{0x00};
datagram::EcatDatagram<command::BWR, uint8_t> m{ {{broadcast, ECT_REG_EEPCFG}}, m_data_out }; datagram::EcatDatagram<command::BWR, uint8_t> m{ {{broadcast, ECT_REG_EEPCFG}}, m_data_out };
//a + b + c + d + e + f + g + h + i + j + k + l + m; a + b + c + d + e + f + g + h + i + j + k + l + m;
telegram_.transfer(a); telegram_.transfer(a);
telegram_.transfer(b); //telegram_.transfer(b);
telegram_.transfer(c); //telegram_.transfer(c);
telegram_.transfer(d); //telegram_.transfer(d);
telegram_.transfer(e); //telegram_.transfer(e);
telegram_.transfer(f); //telegram_.transfer(f);
telegram_.transfer(g); //telegram_.transfer(g);
telegram_.transfer(h); //telegram_.transfer(h);
telegram_.transfer(i); //telegram_.transfer(i);
telegram_.transfer(j); //telegram_.transfer(j);
telegram_.transfer(k); //telegram_.transfer(k);
telegram_.transfer(l); //telegram_.transfer(l);
telegram_.transfer(m); //telegram_.transfer(m);
DebugP_log("a.get_wkc() = %d\r\n", a.get_wkc()); DebugP_log("a.get_wkc() = %d\r\n", a.get_wkc());
DebugP_log("b.get_wkc() = %d\r\n", b.get_wkc()); DebugP_log("b.get_wkc() = %d\r\n", b.get_wkc());
@ -157,8 +157,8 @@ void EthEcat::set_slaves_to_default() {
uint16_t EthEcat::slaves_detecting() { uint16_t EthEcat::slaves_detecting() {
address::Broadcast broadcast{0x0000}; address::Broadcast broadcast{0x0000};
uint16_t data_out{0x0000}; uint16_t data{0x0000};
datagram::EcatDatagram<command::BRD, uint16_t> datagram{ {{broadcast, ECT_REG_TYPE}}, data_out }; datagram::EcatDatagram<command::BRD, uint16_t> datagram{ {{broadcast, ECT_REG_TYPE}}, data };
telegram_.transfer(datagram); telegram_.transfer(datagram);

View File

@ -43,12 +43,12 @@ public:
template<typename TypeT> template<typename TypeT>
void set_slave_address(typename TypeT::TSlaveAddress&& slave_address) { void set_slave_address(typename TypeT::TSlaveAddress&& slave_address) {
std::get<static_cast<size_t>(TypeT::type)>(slave_addresses_) = slave_address; free_rtos::get<static_cast<size_t>(TypeT::type)>(slave_addresses_) = slave_address;
} }
template<typename TypeT> template<typename TypeT>
typename TypeT::TSlaveAddress& get_slave_address() { typename TypeT::TSlaveAddress& get_slave_address() {
return std::get<static_cast<size_t>(TypeT::type)>(slave_addresses_); return free_rtos::get<static_cast<size_t>(TypeT::type)>(slave_addresses_);
} }
template<typename TypeT> template<typename TypeT>
@ -266,8 +266,6 @@ private:
e_pktTotal e_pktTotal
}; };
static constexpr uint16_t max_number_of_slaves = 32;
TEthPkt * p_pkt_; TEthPkt * p_pkt_;
TEthPkt * p_pkt_next_; TEthPkt * p_pkt_next_;

View File

@ -10,11 +10,11 @@
#include <cstdint> #include <cstdint>
#include <array> #include <array>
#include <tuple>
#include <type_traits> #include <type_traits>
#include "ethernet_industry/ethercattype.hpp" #include "ethernet_industry/ethercattype.hpp"
#include "ethernet_industry/eth_ecat_types.h" #include "ethernet_industry/eth_ecat_types.h"
#include "ethernet_industry/eth_ecat_custom_tuple.hpp"
namespace free_rtos { namespace free_rtos {
@ -26,17 +26,17 @@ using Broadcast = uint16_t;
using Station = uint16_t; using Station = uint16_t;
using Logical = uint32_t; using Logical = uint32_t;
using SlaveAddresses = std::tuple<Position, Broadcast, Station, Logical>; using SlaveAddresses = free_rtos::custom_tuple<Position, Broadcast, Station, Logical>;
// Register offset // Register offset
using Offset = uint16_t; using Offset = uint16_t;
using PositionAddress = std::tuple<Position, Offset>; using PositionAddress = free_rtos::custom_tuple<Position, Offset>;
using BroadcastAddress = std::tuple<Broadcast, Offset>; using BroadcastAddress = free_rtos::custom_tuple<Broadcast, Offset>;
using StationAddress = std::tuple<Station, Offset>; using StationAddress = free_rtos::custom_tuple<Station, Offset>;
using LogicalAddress = std::tuple<Logical>; using LogicalAddress = free_rtos::custom_tuple<Logical>;
using Addresses = std::tuple<PositionAddress, BroadcastAddress, StationAddress, LogicalAddress>; using Addresses = free_rtos::custom_tuple<PositionAddress, BroadcastAddress, StationAddress, LogicalAddress>;
} // namespace address } // namespace address
@ -79,12 +79,33 @@ struct TypeBase {
template<TYPE_INDEX type_index> template<TYPE_INDEX type_index>
struct Type : public TypeBase { struct Type : public TypeBase {
using TAddress = typename std::tuple_element<static_cast<size_t>(type_index), address::Addresses>::type; using TAddress = typename free_rtos::custom_tuple_element<static_cast<size_t>(type_index), address::Addresses>::type;
using TSlaveAddress = typename std::tuple_element<0, TAddress>::type; using TSlaveAddress = typename free_rtos::custom_tuple_element<0, TAddress>::type;
static constexpr TYPE_INDEX type = type_index; static constexpr TYPE_INDEX type = type_index;
};
static constexpr ec_cmdtype get_cmd(DIR_INDEX dir) { using AP = Type<TYPE_INDEX::AP>;
using B = Type<TYPE_INDEX::B>;
using FP = Type<TYPE_INDEX::FP>;
using L = Type<TYPE_INDEX::L>;
class EcatCommandBase {
public:
EcatCommandBase(TYPE_INDEX type, DIR_INDEX dir)
: cmd_{get_cmd_from_table(type, dir)} { }
EcatCommandBase()
: cmd_{ec_cmdtype::EC_CMD_NOP} { }
uint8_t get_cmd() {
return cmd_;
}
private:
ec_cmdtype cmd_;
static constexpr ec_cmdtype get_cmd_from_table(TYPE_INDEX type, DIR_INDEX dir) {
std::array<std::array<ec_cmdtype, 4>, 4> commands = {{ std::array<std::array<ec_cmdtype, 4>, 4> commands = {{
{{EC_CMD_APRD, EC_CMD_APWR, EC_CMD_APRW, EC_CMD_ARMW}}, {{EC_CMD_APRD, EC_CMD_APWR, EC_CMD_APRW, EC_CMD_ARMW}},
{{EC_CMD_BRD, EC_CMD_BWR, EC_CMD_BRW, EC_CMD_NOP}}, {{EC_CMD_BRD, EC_CMD_BWR, EC_CMD_BRW, EC_CMD_NOP}},
@ -96,63 +117,29 @@ struct Type : public TypeBase {
} }
}; };
using AP = Type<TYPE_INDEX::AP>;
using B = Type<TYPE_INDEX::B>;
using FP = Type<TYPE_INDEX::FP>;
using L = Type<TYPE_INDEX::L>;
class EcatCommandBase {
public:
EcatCommandBase(ec_cmdtype cmd)
: cmd_{cmd} { }
EcatCommandBase()
: cmd_{ec_cmdtype::EC_CMD_NOP} { }
uint8_t get_cmd() {
return cmd_;
}
private:
ec_cmdtype cmd_;
};
template<typename TypeT, typename DirT> template<typename TypeT, typename DirT>
class EcatCommand : public EcatCommandBase { class EcatCommand : public EcatCommandBase {
static_assert(std::is_base_of<TypeBase, TypeT>::value == true, "TypeT should be derived from command::TypeBase"); static_assert(std::is_base_of<TypeBase, TypeT>::value == true, "TypeT should be derived from command::TypeBase");
static_assert(std::is_base_of<DirBase, DirT>::value == true, "DirT should be derived from command::DirBase"); static_assert(std::is_base_of<DirBase, DirT>::value == true, "DirT should be derived from command::DirBase");
public: public:
EcatCommand(typename TypeT::TAddress fields) EcatCommand(typename TypeT::TAddress address)
: EcatCommandBase{TypeT::get_cmd(DirT::dir)} : EcatCommandBase{TypeT::type, DirT::dir}
, address_union_{fields} { } , address_{address} { }
EcatCommand() { } EcatCommand() { }
uint32_t get_address() { uint32_t get_address() {
return address_union_.dword_; uint32_t address{0x00000000};
address_.pack(reinterpret_cast<uint8_t*>(&address));
return address;
} }
private: private:
template<typename FieldsT>
union AddressUnion
{
AddressUnion(FieldsT fields)
: fields_{fields} { }
AddressUnion() { } typename TypeT::TAddress address_;
AddressUnion& operator=(const AddressUnion& other) {
fields_ = other.fields_;
return *this;
}
FieldsT fields_;
uint32_t dword_;
};
AddressUnion<typename TypeT::TAddress> address_union_;
}; };
/* /*

View File

@ -12,42 +12,47 @@ namespace free_rtos {
// Базовый шаблон класса, никогда не инстанциируется, поэтому без тела // Базовый шаблон класса, никогда не инстанциируется, поэтому без тела
template<typename... Args> template<typename... Args>
struct CustomTuple; struct custom_tuple;
// Основная специализация шаблона. Есть еще одна для протокола CoE. // Основная специализация шаблона. Есть еще одна для протокола CoE.
template<typename HeadT, typename... TailT> template<typename HeadT, typename... TailT>
struct CustomTuple<HeadT, TailT...> : CustomTuple<TailT...> { struct custom_tuple<HeadT, TailT...> : custom_tuple<TailT...> {
CustomTuple(HeadT& head, TailT&... tail) custom_tuple(HeadT head, TailT... tail)
: CustomTuple<TailT...>(tail...) : custom_tuple<TailT...>(tail...)
, head_(head) { } , head_(head) { }
using TBase = CustomTuple<TailT...>; custom_tuple()
: custom_tuple<TailT...>() { }
constexpr static size_t size = sizeof(HeadT) + TBase::size; using TBase = custom_tuple<TailT...>;
using THead = HeadT;
using THeadDeref = typename std::remove_reference<THead>::type;
TBase& base_ = static_cast<TBase&>(*this); constexpr static size_t size = sizeof(THeadDeref) + TBase::size;
HeadT& head_;
//TBase& base_ = static_cast<TBase&>(*this);
THead head_;
uint8_t* pack(uint8_t *raw) { uint8_t* pack(uint8_t *raw) {
HeadT *head = new(raw) HeadT{head_}; THeadDeref *head = new(raw) THeadDeref{head_};
(void)head; (void)head;
return base_.pack(raw + sizeof(HeadT)); return TBase::pack(raw + sizeof(THeadDeref));
} }
uint8_t* unpack(uint8_t *raw) { uint8_t* unpack(uint8_t *raw) {
HeadT *head = reinterpret_cast<HeadT*>(raw); THeadDeref *head = reinterpret_cast<THeadDeref*>(raw);
head_ = *head; head_ = *head;
return base_.unpack(raw + sizeof(HeadT)); return TBase::unpack(raw + sizeof(THeadDeref));
} }
}; };
// Специализация завершения рекурсии // Специализация завершения рекурсии
template<> template<>
struct CustomTuple<> { struct custom_tuple<> {
constexpr static size_t size = 0; constexpr static size_t size = 0;
uint8_t* pack(uint8_t *raw) { uint8_t* pack(uint8_t *raw) {
@ -59,8 +64,33 @@ struct CustomTuple<> {
} }
}; };
template<size_t index, typename TupleT>
struct custom_tuple_element;
template<size_t index, typename HeadT, typename... TailT>
struct custom_tuple_element<index, custom_tuple<HeadT, TailT...>> {
using TBase = custom_tuple_element<index - 1, custom_tuple<TailT...>>;
using type = typename TBase::type;
static type& get(custom_tuple<HeadT, TailT...>& t) {
return TBase::get(t);
}
};
template<typename HeadT, typename... TailT>
struct custom_tuple_element<0, custom_tuple<HeadT, TailT...>> {
using type = HeadT;
static type& get(custom_tuple<HeadT, TailT...>& t) {
return t.head_;
}
};
template<size_t index, typename TupleT>
typename custom_tuple_element<index, TupleT>::type& get(TupleT& t) {
return custom_tuple_element<index, TupleT>::get(t);
} }
}
#endif /* FREE_RTOS_ETHERNET_INDUSTRY_ETH_ECAT_CUSTOM_TUPLE_HPP_ */ #endif /* FREE_RTOS_ETHERNET_INDUSTRY_ETH_ECAT_CUSTOM_TUPLE_HPP_ */

View File

@ -13,8 +13,8 @@
#include "ethernet/eth.hpp" #include "ethernet/eth.hpp"
#include "ethernet_industry/ethercattype.hpp" #include "ethernet_industry/ethercattype.hpp"
#include "ethernet_industry/eth_ecat_types.h" #include "ethernet_industry/eth_ecat_types.h"
#include "ethernet_industry/eth_ecat_command.hpp"
#include "ethernet_industry/eth_ecat_custom_tuple.hpp" #include "ethernet_industry/eth_ecat_custom_tuple.hpp"
#include "ethernet_industry/eth_ecat_command.hpp"
namespace free_rtos { namespace free_rtos {
@ -95,7 +95,7 @@ public:
private: private:
CommandT command_; CommandT command_;
CustomTuple<DataTypes...> data_; custom_tuple<DataTypes&...> data_;
uint8_t* pack_wkc(uint8_t *raw) { uint8_t* pack_wkc(uint8_t *raw) {
TEcatWkc *wkc = new(raw) TEcatWkc{0x0000}; TEcatWkc *wkc = new(raw) TEcatWkc{0x0000};