EtherCATFrame.h
Go to the documentation of this file.
1 #pragma once
2 
3 /*!
4  * Copied from https://gitlab.com/h2t/student-projects/pse-ws2021/etherkitten/-/tree/master/reader/src/etherkitten/reader
5  *
6  * !!!
7  * Needs correct license message!!!!
8  * !!!
9  */
10 
11 #include <array>
12 #include <cstdint>
13 #include <unordered_map>
14 #include <utility>
15 #include <vector>
16 
17 #include "SlaveRegisters.h"
18 
20 {
21  /*!
22  * \brief The maximum length of an Ethernet frame as defined by the standard.
23  */
24  static constexpr size_t ethernetFrameMaxLength = 1518;
25 
26  /*!
27  * \brief The size of an Ethernet frame header as defined by the standard.
28  */
29  static constexpr size_t ethernetHeaderSize = 14;
30 
31  /*!
32  * \brief The maximum space that a series of PDUs is allowed to have in an EtherCAT frame.
33  *
34  * (Max. length of eth.) - (eth. header size) - (ecat header size) - (CRC checksum size)
35  */
36  static constexpr size_t maxTotalPDULength =
37  ethernetFrameMaxLength - ethernetHeaderSize - sizeof(uint16_t) - sizeof(uint32_t);
38 
39  /*!
40  * \brief The EtherCATFrame struct represents an EtherCAT frame according to the EtherCAT spec.
41  *
42  * See the EtherCAT standard, part 4, page 30
43  */
45  {
46  uint16_t lengthAndType{};
47  uint8_t pduArea[maxTotalPDULength]{}; // NOLINT
48  };
49 
50  static constexpr uint8_t fprdCommandType = 0x04; /*!< The type specifier for an FPRD PDU */
51 
52  /*!
53  * \brief This is a placeholder index - SOEM uses the index field of the first PDU to sort
54  * frames, so we have to set this in the SOEM-interacting code where we know which index we
55  * need.
56  */
57  static constexpr uint8_t invalidIndex = 0xff;
58 
59  /*!
60  * \brief The EtherCATPDU struct represents an EtherCAT PDU according to the EtherCAT spec.
61  *
62  * See the EtherCAT standard, part 4, page 32 (we only use FPRD PDUs here)
63  */
64  struct EtherCATPDU
65  {
66  uint8_t commandType = fprdCommandType;
67  uint8_t index = invalidIndex;
68  uint16_t slaveConfiguredAddress = 0;
69  uint16_t registerAddress = 0;
70  uint16_t dataLengthAndNext = 0;
71  uint16_t externalEvent = 0;
72 
73  /* This is a workaround since C++ doesn't have flexible array members like C.
74  * EtherCATPDUs are only ever placement-constructed inside an EtherCATFrame,
75  * so this doesn't create problems with memory allocation. */
76  uint8_t data[1] = {0}; // NOLINT
77  } __attribute__((packed));
78 
79  /*!
80  * \brief The overhead that a PDU has = its size without the data section.
81  *
82  * We use this to decide where to set PDU boundaries to save space in an EtherCAT frame.
83  *
84  * (Size of the PDU struct) - (That annoying workaround byte) + (The working counter at the end)
85  */
86  static constexpr int pduOverhead = sizeof(EtherCATPDU) - sizeof(uint8_t) + sizeof(uint16_t);
87 
88  /*!
89  * \brief The PDUMetaData struct holds information about the structure of a PDU.
90  *
91  * We need this if we don't want to reparse the frames once we receive to get the data out.
92  */
93  struct PDUMetaData
94  {
96 
97  /*!
98  * \brief The offsets of the registers that are written into this PDU by the slave
99  * relative to the start of the EtherCAT frame.
100  */
101  std::map<datatypes::RegisterEnum, size_t> registerOffsets;
102 
103  /*!
104  * \brief The offset of the working counter for this PDU relative to the start of
105  * the EtherCAT frame.
106  */
108  };
109 
110  /*!
111  * \brief The EtherCATFrameMetaData struct holds information about the structure of an
112  * EtherCAT frame.
113  */
115  {
117  std::vector<PDUMetaData> pdus;
118  };
119 
120  /*!
121  * \brief The EtherCATFrameList struct holds a list of EtherCAT frames that can be
122  * scheduled in round-robin-style.
123  */
125  {
126  size_t nextIndex = 0; /*!< The next frame in the RR scheduler */
127  std::vector<std::pair<EtherCATFrame, EtherCATFrameMetaData>> list;
128  };
129 
130  /*!
131  * \brief The EtherCATFrameIterator class iterates over a set range of EtherCAT frames
132  * once.
133  */
135  {
136  public:
137  /*!
138  * \brief Construct a new EtherCATFrameIterator that iterates over the given
139  * range of EtherCAT frames.
140  *
141  * If `startIndex + count > list->list.size()`, the iterator will wrap around
142  * to the start fo the list.
143  * \param list the list to iterate over
144  * \param startIndex the index to start iterating on
145  * \param count the number of frames to iterate over (including the first)
146  */
147  EtherCATFrameIterator(EtherCATFrameList* list, size_t startIndex, size_t count);
148 
149  /*!
150  * \brief Get the EtherCAT frame this iterator is on with metadata.
151  * \return an EtherCATFrame along with its metadata
152  */
153  std::pair<EtherCATFrame*, EtherCATFrameMetaData*> operator*() const;
154 
155  /*!
156  * \brief Check if this iterator points to the first available register frame.
157  *
158  * This indicates that all registers have been read by sequential iterators.
159  * \retval true iff this iterator points to the first register frame
160  * \retval false iff this iterator does not point to the first register frame
161  * \exception
162  */
163  bool hasCompletedLoop() const;
164 
165  /*!
166  * \brief Move this iterator to the next EtherCAT frame.
167  *
168  * Does nothing if this iterator is at the end of its range.
169  * \return a reference to this iterator
170  */
172 
173  /*!
174  * \brief Check if this iterator has stepped over its range.
175  * \retval true iff this iterator can no longer be dereferenced or advanced
176  * \retval false iff this iterator can still be dereferenced and advanced
177  */
178  bool atEnd() const;
179 
180  size_t getCurrentIndex() const;
181 
182  private:
184  size_t nextIndex;
185  size_t remaining;
186  };
187 
188 } // namespace armarx::control::ethercat
armarx::control::ethercat::EtherCATFrameMetaData::pdus
std::vector< PDUMetaData > pdus
Definition: EtherCATFrame.h:117
armarx::control::ethercat::EtherCATPDU::externalEvent
uint16_t externalEvent
Definition: EtherCATFrame.h:71
armarx::control::ethercat::PDUMetaData
The PDUMetaData struct holds information about the structure of a PDU.
Definition: EtherCATFrame.h:93
armarx::control::ethercat::EtherCATPDU::dataLengthAndNext
uint16_t dataLengthAndNext
Definition: EtherCATFrame.h:70
list
list(APPEND SOURCES ${QT_RESOURCES}) set(COMPONENT_LIBS ArmarXGui ArmarXCoreObservers ArmarXCoreEigen3Variants PlotterController $
Definition: CMakeLists.txt:49
armarx::control::ethercat::EtherCATPDU::data
uint8_t data[1]
Definition: EtherCATFrame.h:76
armarx::control::ethercat::EtherCATPDU::slaveConfiguredAddress
uint16_t slaveConfiguredAddress
Definition: EtherCATFrame.h:68
armarx::control::ethercat::EtherCATPDU::index
uint8_t index
Definition: EtherCATFrame.h:67
armarx::control::ethercat::EtherCATFrame::pduArea
uint8_t pduArea[maxTotalPDULength]
Definition: EtherCATFrame.h:47
armarx::control::ethercat::PDUMetaData::workingCounterOffset
size_t workingCounterOffset
The offset of the working counter for this PDU relative to the start of the EtherCAT frame.
Definition: EtherCATFrame.h:107
armarx::control::ethercat::EtherCATFrameList::list
std::vector< std::pair< EtherCATFrame, EtherCATFrameMetaData > > list
Definition: EtherCATFrame.h:127
armarx::control::ethercat::EtherCATFrameMetaData
The EtherCATFrameMetaData struct holds information about the structure of an EtherCAT frame.
Definition: EtherCATFrame.h:114
armarx::control::ethercat::EtherCATFrameIterator::operator*
std::pair< EtherCATFrame *, EtherCATFrameMetaData * > operator*() const
Get the EtherCAT frame this iterator is on with metadata.
Definition: EtherCATFrame.cpp:13
armarx::control::ethercat::EtherCATPDU
The EtherCATPDU struct represents an EtherCAT PDU according to the EtherCAT spec.
Definition: EtherCATFrame.h:64
SlaveRegisters.h
armarx::control::ethercat::EtherCATFrameIterator
The EtherCATFrameIterator class iterates over a set range of EtherCAT frames once.
Definition: EtherCATFrame.h:134
armarx::control::ethercat::PDUMetaData::slaveConfiguredAddress
uint16_t slaveConfiguredAddress
Definition: EtherCATFrame.h:95
armarx::control::ethercat::EtherCATFrameList::nextIndex
size_t nextIndex
Definition: EtherCATFrame.h:126
armarx::control::ethercat::EtherCATFrameIterator::EtherCATFrameIterator
EtherCATFrameIterator(EtherCATFrameList *list, size_t startIndex, size_t count)
Construct a new EtherCATFrameIterator that iterates over the given range of EtherCAT frames.
Definition: EtherCATFrame.cpp:5
armarx::control::ethercat::EtherCATFrameList
The EtherCATFrameList struct holds a list of EtherCAT frames that can be scheduled in round-robin-sty...
Definition: EtherCATFrame.h:124
armarx::control::ethercat
Definition: Bus.cpp:24
armarx::control::ethercat::EtherCATPDU::registerAddress
uint16_t registerAddress
Definition: EtherCATFrame.h:69
armarx::control::ethercat::EtherCATFrameIterator::operator++
EtherCATFrameIterator & operator++()
Move this iterator to the next EtherCAT frame.
Definition: EtherCATFrame.cpp:25
armarx::control::ethercat::EtherCATFrameIterator::atEnd
bool atEnd() const
Check if this iterator has stepped over its range.
Definition: EtherCATFrame.cpp:36
armarx::control::ethercat::EtherCATPDU::commandType
uint8_t commandType
Definition: EtherCATFrame.h:66
armarx::control::ethercat::EtherCATFrame::lengthAndType
uint16_t lengthAndType
Definition: EtherCATFrame.h:46
armarx::control::ethercat::EtherCATFrameIterator::hasCompletedLoop
bool hasCompletedLoop() const
Check if this iterator points to the first available register frame.
Definition: EtherCATFrame.cpp:19
armarx::control::ethercat::EtherCATFrame
The EtherCATFrame struct represents an EtherCAT frame according to the EtherCAT spec.
Definition: EtherCATFrame.h:44
armarx::control::ethercat::EtherCATFrameMetaData::lengthOfFrame
size_t lengthOfFrame
Definition: EtherCATFrame.h:116
armarx::control::ethercat::EtherCATFrameIterator::getCurrentIndex
size_t getCurrentIndex() const
Definition: EtherCATFrame.cpp:42
armarx::control::ethercat::PDUMetaData::registerOffsets
std::map< datatypes::RegisterEnum, size_t > registerOffsets
The offsets of the registers that are written into this PDU by the slave relative to the start of the...
Definition: EtherCATFrame.h:101
armarx::control::ethercat::__attribute__
struct armarx::control::ethercat::PDUMetaData __attribute__