12#include <unordered_map>
17#include <tl/expected.hpp>
267 int timeoutUs = EC_TIMEOUTRET);
385 const std::vector<uint16_t>& positions,
386 uint16_t requiredState, uint16_t targetState,
387 const char* targetName,
388 std::chrono::steady_clock::duration timeout,
389 std::chrono::steady_clock::duration resendInterval =
390 std::chrono::seconds(2),
391 std::function<
void()> tick =
nullptr,
392 std::function<
bool()> shouldAbort =
nullptr);
407 ecx_contextt* context, uint16_t slave, uint16_t targetState,
408 std::chrono::steady_clock::duration timeout = std::chrono::seconds(5));
474 const std::vector<mm::comm::base::PdoMappingEntry>& entries);
487void logIoMap(uint8_t* ioMap,
size_t totalBytes);
582 supportedProtocols, writeLength, writeOffset)
591struct SlaveInfoSyncManager {
615 uint16_t startAddress;
640struct SlaveInfoFmmu {
654 uint8_t logicalEndBit;
662 uint8_t logicalStartBit;
669 uint32_t logicalStartAddress;
676 uint16_t logicalLength;
684 uint8_t physicalStartBit;
691 uint16_t physicalStartAddress;
703 logicalStartBit, logicalStartAddress,
704 logicalLength, physicalStartBit,
705 physicalStartAddress,
type)
720 uint16_t alStatusCode;
728 uint16_t aliasAddress;
735 std::vector<SlaveInfoFmmu> fmmus;
752 uint32_t productCode;
768 uint32_t revisionNumber;
776 std::vector<SlaveInfoSyncManager> syncManagers;
798 revisionNumber, syncManagers,
name, vendorId)
850 const
std::
string& iface);
936 bool setState(
int targetState,
int timeoutMs = 0,
int intervalMs = 100);
959 tl::expected<void, std::string>
loadParameters(
bool readValues =
false);
1070 template <
typename T = std::vector<u
int8_t>>
1075 auto state = context_.slavelist[position_].state;
1076 if (state == EC_STATE_INIT || state == EC_STATE_BOOT) {
1077 throw std::runtime_error(
1078 "To upload object dictionary entries, the device must be in the (2) "
1079 "PRE-OPERATIONAL, (4) SAFE-OPERATIONAL, or (8) OPERATIONAL state. "
1080 "The current state is " +
1089 const std::unique_ptr<std::uint8_t[]> data =
1090 std::make_unique<std::uint8_t[]>(parameter.byteLength);
1092 ecx_SDOread(&context_, position_, parameter.index, parameter.subindex,
1095 LOG_F(ERROR,
"Device %d: SDO read failed for %#04x:%02x! WKC: %d",
1096 position_, parameter.index, parameter.subindex, wkc);
1098 parameter.subindex);
1099 throw std::runtime_error(
"Device " + std::to_string(position_) +
1100 ": SDO read failed for " +
id +
1101 "! WKC: " + std::to_string(wkc));
1103 std::vector<uint8_t> receivedData(data.get(),
1104 data.get() + parameter.byteLength);
1105 if (!parameter.trySetValue(receivedData)) {
1107 "Device %d: Failed to set the value of parameter %#04x:%02x!",
1108 position_, parameter.index, parameter.subindex);
1114 if constexpr (std::is_same_v<T, std::vector<uint8_t>>) {
1115 return parameter.data;
1118 auto value = parameter.getValue();
1119 if (
auto ptr = std::get_if<T>(&
value)) {
1122 throw std::bad_variant_access();
1151 template <
typename T = std::vector<u
int8_t>>
1156 auto state = context_.slavelist[position_].state;
1157 if (state == EC_STATE_INIT || state == EC_STATE_BOOT) {
1158 throw std::runtime_error(
1159 "To download object dictionary entries, the device must be in the "
1160 "(2) PRE-OPERATIONAL, (4) SAFE-OPERATIONAL, or (8) OPERATIONAL "
1161 "state. The current state is " +
1168 std::vector<uint8_t> data;
1169 if constexpr (std::is_same_v<T, std::vector<uint8_t>>) {
1173 if (!parameter.trySetValue(
value)) {
1175 "Device %d: Failed to set the value of parameter %#04x:%02x!",
1176 position_, parameter.index, parameter.subindex);
1179 data = parameter.data;
1183 if (data.size() != parameter.byteLength) {
1184 LOG_F(ERROR,
"Data size mismatch: expected %d, got %zu",
1185 parameter.byteLength, data.size());
1186 throw std::runtime_error(
"Data size does not match the parameter size!");
1191 ecx_SDOwrite(&context_, position_, parameter.index, parameter.subindex,
1196 LOG_F(ERROR,
"Device %d: SDO write failed for %#04x:%02x! WKC: %d",
1197 position_, parameter.index, parameter.subindex, wkc);
1222 void updatePdoMappings();
1235 void logPdoMappings()
const;
1266 void updateOutputs();
1289 void updateParametersFromInputs();
1316 tl::expected<std::vector<uint8_t>, std::string> readFile(
1317 const std::string& filename,
1318 size_t maxFileSize = 1 * 1024 * 1024,
1320 std::chrono::steady_clock::duration retryWait =
1321 std::chrono::milliseconds(100));
1336 tl::expected<std::vector<std::uint8_t>, std::string> readSdo(
1337 uint16_t
index, uint8_t subindex);
1352 tl::expected<ec_ODlistt, std::string> readODList(
1353 int retries = 5, std::chrono::steady_clock::duration retryWait =
1354 std::chrono::milliseconds(100));
1374 tl::expected<void, std::string> readODDescription(
1375 uint16_t item, ec_ODlistt& odList,
int retries = 5,
1376 std::chrono::steady_clock::duration retryWait =
1377 std::chrono::milliseconds(100));
1395 tl::expected<ec_OElistt, std::string> readOE(
1396 uint16_t item, ec_ODlistt& odList,
int retries = 5,
1397 std::chrono::steady_clock::duration retryWait =
1398 std::chrono::milliseconds(100));
1401 ecx_contextt& context_;
1402 const uint16_t position_;
1433 explicit Master(
const std::string& iface);
1486 void init(
const std::string& iface);
1614 const std::vector<std::unique_ptr<Slave>>&
slaves()
const;
1626 return fieldbus_->context.grouplist[fieldbus_->group].outputsWKC * 2 +
1627 fieldbus_->context.grouplist[fieldbus_->group].inputsWKC;
1697 std::unique_ptr<Fieldbus> fieldbus_;
1710 std::vector<std::unique_ptr<Slave>> slaves_;
Represents a device parameter identified by index and subindex.
Definition base.h:529
std::pair< uint16_t, uint8_t > Address
Alias for a pair of uint16_t and uint8_t representing a parameter address.
Definition base.h:539
int roundtrip()
Performs a complete send/receive process data cycle on the fieldbus.
Definition soem.cc:1827
Master()
Default constructor for the Master class.
Definition soem.cc:1744
const std::vector< std::unique_ptr< Slave > > & slaves() const
Returns a reference to the list of slaves.
Definition soem.cc:1823
tl::expected< int, std::string > initSlaves()
Initializes the slave devices on the EtherCAT network.
Definition soem.cc:1796
void exchangeProcessDataAndUpdateParameters()
Exchanges process data with slaves and updates parameters based on the response.
Definition soem.cc:1832
size_t getIoMapSize() const
Returns the total size of the I/O map for the current group.
Definition soem.cc:1791
Fieldbus & getFieldbus() const
Returns a reference to the Fieldbus instance.
Definition soem.cc:1787
void init(const std::string &iface)
Initializes the fieldbus using the specified network interface.
Definition soem.cc:1751
std::string getInterfaceName() const
Retrieves the interface name used by the fieldbus.
Definition soem.cc:1789
void deinit()
Deinitializes the fieldbus and releases associated resources.
Definition soem.cc:1769
bool start()
Initializes and starts the fieldbus master.
Definition soem.cc:1855
~Master()
Destructor for the Master class.
Definition soem.cc:1785
int expectedWkc() const
Calculates the expected working counter (WKC) for the current fieldbus group.
Definition soem.h:1625
uint32_t productCode() const
Gets the Product Code of the slave device.
Definition soem.cc:1196
uint32_t vendorId() const
Gets the Vendor ID of the slave device.
Definition soem.cc:1192
std::unordered_map< mm::comm::base::Parameter::Address, mm::comm::base::Parameter > & parametersMap()
Returns a reference to the internal parameters map.
Definition soem.cc:1510
mm::comm::base::Parameter & findParameter(uint16_t index, uint8_t subindex)
Finds and returns a reference to a Parameter in the parameters map.
Definition soem.cc:1514
uint32_t revisionNumber() const
Gets the Revision Number of the slave device.
Definition soem.cc:1200
T upload(uint16_t index, uint8_t subindex, bool refresh=true)
Uploads a parameter value from the device's object dictionary.
Definition soem.h:1071
tl::expected< void, std::string > loadParameters(bool readValues=false)
Loads the parameters (object dictionary entries) from the EtherCAT slave device.
Definition soem.cc:1322
void clearParameters()
Clears all loaded object dictionary parameters.
Definition soem.cc:1506
void logTxPdoMappedParameters()
Logs all mapped TxPDO parameters with their current values.
Definition soem.cc:1491
Slave(ecx_contextt &context, uint16_t position)
Constructs a Slave object with a given context and position.
Definition soem.cc:1187
void logRxPdoMappedParameters()
Logs all mapped RxPDO parameters with their current values.
Definition soem.cc:1476
bool setState(int targetState, int timeoutMs=0, int intervalMs=100)
Attempts to set the slave to the specified EtherCAT state and optionally waits until it is reached.
Definition soem.cc:1206
void logParameters() const
Logs all loaded object dictionary parameters.
Definition soem.cc:1470
int getState() const
Reads the current state of the slave directly from the device.
Definition soem.cc:1204
uint16_t position() const
Gets the position of the slave.
Definition soem.cc:1190
bool download(uint16_t index, uint8_t subindex, const T &value)
Downloads a value to the specified object dictionary entry via SDO.
Definition soem.h:1152
uint8_t type
Definition co_dictionary.h:1
const char ** name
Definition co_dictionary.h:7
uint8_t * value
Definition co_dictionary.h:9
uint16_t index
Definition co_dictionary.h:0
std::string makeParameterId(int index, int subindex)
Formats the given index and subindex into a parameter identifier string.
Definition base.h:1657
constexpr int kFoeReadTimeoutUs
Definition soem.h:37
mm::comm::base::PdoMappings readPdoMappings(ecx_contextt *context, uint16_t slave)
Read and parse all mapped PDO entries for a given slave.
Definition soem.cc:1085
constexpr int kFoeTimeoutUs
Definition soem.h:30
void logPdoMappingEntries(const std::vector< mm::comm::base::PdoMappingEntry > &entries)
Logs PDO mapping entries grouped by PDO index.
Definition soem.cc:1156
uint16_t getSlaveState(ecx_contextt *context, uint16_t slave, int timeoutUs)
Reads the current state of a specific EtherCAT slave directly from the device via an FPRD datagram.
Definition soem.cc:675
std::string convertSlaveStateToString(int state)
Converts a numeric EtherCAT state value into a human-readable string.
Definition soem.cc:690
void resetBootMailboxTracking()
Clears the internal record of which slaves hold BOOT-sized mailbox sync managers.
Definition soem.cc:728
constexpr int kSdoTimeoutUs
Definition soem.h:27
std::string drainMailboxErrors(ecx_contextt *context)
Empties SOEM's error list and describes the first entry found.
Definition soem.cc:54
void transitionSlaves(ecx_contextt *context, const std::vector< uint16_t > &positions, uint16_t requiredState, uint16_t targetState, const char *targetName, std::chrono::steady_clock::duration timeout, std::chrono::steady_clock::duration resendInterval, std::function< void()> tick, std::function< bool()> shouldAbort)
Transitions multiple EtherCAT slaves to a target state using a single-threaded fire-then-poll pattern...
Definition soem.cc:733
std::string uiConfigWithDefaultPdoMapping
Default UI configuration used for PDO mapping.
Definition soem.h:146
void initFieldbus(std::unique_ptr< Fieldbus > &fieldbus, const std::string &iface)
Initializes a Fieldbus instance for EtherCAT communication.
Definition soem.cc:1711
void updateMailboxSyncManagersOnNextState(ecx_contextt *context, uint16_t slave, int targetState)
Updates the mailbox and sync manager (SM) configurations for an EtherCAT slave when transitioning to ...
Definition soem.cc:867
void logIoMap(uint8_t *ioMap, size_t totalBytes)
Logs the I/O map as a formatted hexadecimal string.
Definition soem.cc:1177
void checkPdoMapping(ecx_contextt *context, uint16 slave)
Diagnoses and prints the PDO mapping for a given slave.
Definition soem.cc:591
void configureDetectedSmmModule(ecx_contextt *context, uint16_t slave)
Reads the detected SMM module ID from the slave device and configures the module identification objec...
Definition soem.cc:997
constexpr int kFoeRemoveTimeoutUs
Definition soem.h:42
int drainMailbox(ecx_contextt *context, uint16_t slave)
Discards whatever is sitting in a slave's read mailbox.
Definition soem.cc:100
std::map< std::string, std::string > mapMacAddressesToInterfaces()
Maps MAC addresses to their corresponding network interface names.
Definition soem.cc:134
int setPdoMappingFromUiConfig(ecx_contextt *context, uint16 slave)
Sets PDO mapping for a specified EtherCAT slave using UI configuration.
Definition soem.cc:400
uint16 position
Definition soem.h:812
void logSlaveInfo(ecx_contextt *context, uint16 position)
Logs detailed information about a specific EtherCAT slave in JSON format.
Definition soem.cc:307
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(SlaveInfoMailbox, readLength, readOffset, supportedProtocols, writeLength, writeOffset) struct SlaveInfoSyncManager
Information about a slave's Sync Manager (SM) configuration.
Definition soem.h:581
std::recursive_mutex & controlPlaneMutex()
The single mutex that serialises every control-plane transaction.
Definition soem.cc:49
constexpr int kFoeRemoveEsiTimeoutUs
Definition soem.h:46
SlaveInfo getSlaveInfo(ecx_contextt *context, uint16 position)
Definition soem.cc:255
std::vector< uint8_t > readSii(ecx_contextt *context, uint16 position)
Read the complete Slave Information Interface (SII) EEPROM from an EtherCAT slave device.
Definition soem.cc:1042
bool setSlaveState(ecx_contextt *context, uint16_t slave, uint16_t targetState, std::chrono::steady_clock::duration timeout)
Transitions a single EtherCAT slave to targetState.
Definition soem.cc:859
Specialization of std::hash for std::pair<uint16_t, uint8_t>.
Definition util.h:612
Represents the mapped PDO entries for a slave device.
Definition base.h:171
Structure representing the Fieldbus configuration and context for EtherCAT communication.
Definition soem.h:503
boolean ecaterror
Definition soem.h:519
ec_idxstackT idxstack
Definition soem.h:518
ec_eepromFMMUt eepFMMU
Definition soem.h:525
ec_groupt grouplist[EC_MAXGROUP]
Definition soem.h:514
std::string iface
Definition soem.h:505
uint8 group
Definition soem.h:506
int slavecount
Definition soem.h:513
uint8 esibuf[EC_MAXEEPBUF]
Definition soem.h:515
uint32 esimap[EC_MAXEEPBITMAP]
Definition soem.h:516
int64 DCtime
Definition soem.h:520
ec_eepromSMt eepSM
Definition soem.h:524
ec_PDOassignt PDOassign[EC_MAX_MAPT]
Definition soem.h:522
uint8 map[4096]
Definition soem.h:510
ecx_contextt context
Definition soem.h:504
int roundtripTime
Definition soem.h:507
ec_PDOdesct PDOdesc[EC_MAX_MAPT]
Definition soem.h:523
ecx_portt port
Definition soem.h:511
ec_slavet slavelist[EC_MAXSLAVE]
Definition soem.h:512
ec_SMcommtypet SMcommtype[EC_MAX_MAPT]
Definition soem.h:521
ec_eringt elist
Definition soem.h:517
Information about a slave's mailbox configuration.
Definition soem.h:535
uint16_t writeOffset
Offset of the mailbox write area within the slave's memory.
Definition soem.h:578
uint16_t supportedProtocols
Supported mailbox protocols as a bitmask.
Definition soem.h:562
uint16_t readOffset
Offset of the mailbox read area within the slave's memory.
Definition soem.h:550
uint16_t readLength
Length of the mailbox read area (in bytes).
Definition soem.h:542
uint16_t writeLength
Length of the mailbox write area (in bytes).
Definition soem.h:570