37 #include <boost/ref.hpp>    38 #include <boost/interprocess/sync/scoped_lock.hpp>    41 #include <soem/nicdrv.h>    52 static const unsigned THREAD_SLEEP_TIME = 1000; 
    54 static const int NSEC_PER_SECOND = 1e+9;
    55 void timespecInc(
struct timespec &tick, 
int nsec)
    58   while (tick.tv_nsec >= NSEC_PER_SECOND)
    60       tick.tv_nsec -= NSEC_PER_SECOND;
    72     if ((
ec_slave[slave].group == 0) && (
ec_slave[slave].state != EC_STATE_OPERATIONAL))
    75       if (
ec_slave[slave].state == (EC_STATE_SAFE_OP + EC_STATE_ERROR))
    77         fprintf(stderr, 
"ERROR : slave %d is in SAFE_OP + ERROR, attempting ack.\n", slave);
    81       else if(
ec_slave[slave].state == EC_STATE_SAFE_OP)
    83         fprintf(stderr, 
"WARNING : slave %d is in SAFE_OP, change to OPERATIONAL.\n", slave);
    92           printf(
"MESSAGE : slave %d reconfigured\n",slave);
   102           fprintf(stderr, 
"ERROR : slave %d lost\n",slave);
   113           printf(
"MESSAGE : slave %d recovered\n",slave);
   119         printf(
"MESSAGE : slave %d found\n",slave);
   125 void cycleWorker(boost::mutex& mutex, 
bool& stop_flag)
   128   double period = THREAD_SLEEP_TIME * 1000;
   130   struct timespec tick;
   131   clock_gettime(CLOCK_REALTIME, &tick);
   132   timespecInc(tick, period);
   138       boost::mutex::scoped_lock lock(mutex);
   143     if (wkc < expected_wkc)
   149     struct timespec before;
   150     clock_gettime(CLOCK_REALTIME, &before);
   151     double overrun_time = (before.tv_sec + double(before.tv_nsec)/NSEC_PER_SECOND) -  (tick.tv_sec + 
double(tick.tv_nsec)/NSEC_PER_SECOND);
   152     if (overrun_time > 0.0)
   154         fprintf(stderr, 
"  overrun: %f\n", overrun_time);
   157     clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &tick, NULL);
   158     timespecInc(tick, period);
   201 #define IF_MINAS(_ec_slave) (((int)_ec_slave.eep_man == 0x066f) && ((((0xf0000000&(int)ec_slave[cnt].eep_id)>>28) == 0x5) || (((0xf0000000&(int)ec_slave[cnt].eep_id)>>28) == 0xD)))   205   const static unsigned MAX_BUFF_SIZE = 1024;
   206   char buffer[MAX_BUFF_SIZE];
   207   size_t name_size = 
ifname_.size();
   208   if (name_size > 
sizeof(buffer) - 1) 
   210     fprintf(stderr, 
"Ifname %s exceeds maximum size of %u bytes\n", 
ifname_.c_str(), MAX_BUFF_SIZE);
   213   std::strncpy(buffer, 
ifname_.c_str(), MAX_BUFF_SIZE);
   215   printf(
"Initializing etherCAT master\n");
   219     fprintf(stderr, 
"Could not initialize ethercat driver\n");
   226     fprintf(stderr, 
"No slaves found on %s\n", 
ifname_.c_str());
   230   printf(
"SOEM found and configured %d slaves\n", 
ec_slavecount);
   266       fprintf(stderr, 
"Could not set EC_STATE_PRE_OP\n");
   276       l = 
sizeof(num_entries);
   278       printf(
"len = %d\n", num_entries);
   283       mapping = 0x60B00020;
   289       printf(
"len = %d\n", num_entries);
   307       printf(
"RxPDO mapping object index %d = %04x ret=%d\n", cnt, idx_rxpdo, ret);
   318       printf(
"TxPDO mapping object index %d = %04x ret=%d\n", cnt, idx_txpdo, ret);
   323   printf(
"SOEM IOMap size: %d\n", iomap_size);
   331     fprintf(stderr, 
"Could not set EC_STATE_SAFE_OP\n");
   355     fprintf(stderr, 
"OPERATIONAL state not set, exiting\n");
   363       printf(
"\nSlave:%d\n Name:%s\n Output size: %dbits\n Input size: %dbits\n State: %d\n Delay: %d[ns]\n Has DC: %d\n",
   366       if (
ec_slave[cnt].hasdc) printf(
" DCParentport:%d\n", 
ec_slave[cnt].parentport);
   367       printf(
" Activeports:%d.%d.%d.%d\n", (
ec_slave[cnt].activeports & 0x01) > 0 ,
   368              (
ec_slave[cnt].activeports & 0x02) > 0 , 
   369              (
ec_slave[cnt].activeports & 0x04) > 0 , 
   370              (
ec_slave[cnt].activeports & 0x08) > 0 );
   371       printf(
" Configured address: %4.4x\n", 
ec_slave[cnt].configadr);
   382       l = 
sizeof(sync_mode);
   384       l = 
sizeof(cycle_time);
   386       l = 
sizeof(minimum_cycle_time);
   388       l = 
sizeof(sync0_cycle_time);
   390       printf(
"PDO syncmode %02x, cycle time %d ns (min %d), sync0 cycle time %d ns, ret = %d\n", sync_mode, cycle_time, minimum_cycle_time, sync0_cycle_time, ret);
   393   printf(
"\nFinished configuration successfully\n");
   402 void EtherCatManager::getStatus(
int slave_no, std::string &name, 
int &eep_man, 
int &eep_id, 
int &eep_rev, 
int &obits, 
int &ibits, 
int &state, 
int &pdelay, 
int &hasdc, 
int &activeports, 
int &configadr)
 const   405     fprintf(stderr, 
"ERROR : slave_no(%d) is larger than ec_slavecount(%d)\n", slave_no, 
ec_slavecount);
   408   name = std::string(
ec_slave[slave_no].name);
   409   eep_man = (int)
ec_slave[slave_no].eep_man;
   410   eep_id  = (int)
ec_slave[slave_no].eep_id;
   411   eep_rev = (int)
ec_slave[slave_no].eep_rev;
   431     fprintf(stderr, 
"ERROR : slave_no(%d) is larger than ec_slavecount(%d)\n", slave_no, 
ec_slavecount);
   434   if (channel*8 >= 
ec_slave[slave_no].Ibits) {
   435     fprintf(stderr, 
"ERROR : channel(%d) is larget thatn Input bits (%d)\n", channel*8, 
ec_slave[slave_no].Ibits);
   445     fprintf(stderr, 
"ERROR : slave_no(%d) is larger than ec_slavecount(%d)\n", slave_no, 
ec_slavecount);
   448   if (channel*8 >= 
ec_slave[slave_no].Obits) {
   449     fprintf(stderr, 
"ERROR : channel(%d) is larget thatn Output bits (%d)\n", channel*8, 
ec_slave[slave_no].Obits);
   455 template <
typename T>
   463 template <
typename T>
   471     fprintf(stderr, 
"Failed to read from ret:%d, slave_no:%d, index:0x%04x, subidx:0x%02x\n", ret, slave_no, index, subidx);
   476 template uint8_t EtherCatManager::writeSDO<char> (
int slave_no, 
uint16_t index, 
uint8_t subidx, 
char value) 
const;
   477 template uint8_t EtherCatManager::writeSDO<int> (
int slave_no, 
uint16_t index, 
uint8_t subidx, 
int value) 
const;
   478 template uint8_t EtherCatManager::writeSDO<short> (
int slave_no, 
uint16_t index, 
uint8_t subidx, 
short value) 
const;
   479 template uint8_t EtherCatManager::writeSDO<long> (
int slave_no, 
uint16_t index, 
uint8_t subidx, 
long value) 
const;
   480 template uint8_t EtherCatManager::writeSDO<unsigned char> (
int slave_no, 
uint16_t index, 
uint8_t subidx, 
unsigned char value) 
const;
   481 template uint8_t EtherCatManager::writeSDO<unsigned int> (
int slave_no, 
uint16_t index, 
uint8_t subidx, 
unsigned int value) 
const;
   482 template uint8_t EtherCatManager::writeSDO<unsigned short> (
int slave_no, 
uint16_t index, 
uint8_t subidx, 
unsigned short value) 
const;
   483 template uint8_t EtherCatManager::writeSDO<unsigned long> (
int slave_no, 
uint16_t index, 
uint8_t subidx, 
unsigned long value) 
const;
   485 template char EtherCatManager::readSDO<char> (
int slave_no, 
uint16_t index, 
uint8_t subidx) 
const;
   486 template int EtherCatManager::readSDO<int> (
int slave_no, 
uint16_t index, 
uint8_t subidx) 
const;
   487 template short EtherCatManager::readSDO<short> (
int slave_no, 
uint16_t index, 
uint8_t subidx) 
const;
   488 template long EtherCatManager::readSDO<long> (
int slave_no, 
uint16_t index, 
uint8_t subidx) 
const;
   489 template unsigned char EtherCatManager::readSDO<unsigned char> (
int slave_no, 
uint16_t index, 
uint8_t subidx) 
const;
   490 template unsigned int EtherCatManager::readSDO<unsigned int> (
int slave_no, 
uint16_t index, 
uint8_t subidx) 
const;
   491 template unsigned short EtherCatManager::readSDO<unsigned short> (
int slave_no, 
uint16_t index, 
uint8_t subidx) 
const;
   492 template unsigned long EtherCatManager::readSDO<unsigned long> (
int slave_no, 
uint16_t index, 
uint8_t subidx) 
const;
 int ec_reconfig_slave(uint16 slave, int timeout)
int ec_send_processdata(void)
uint8_t readOutput(int slave_no, uint8_t channel) const
Reads the "channel-th" output-register of the given slave no. 
boost::mutex iomap_mutex_
void getStatus(int slave_no, std::string &name, int &eep_man, int &eep_id, int &eep_rev, int &obits, int &ibits, int &state, int &pdelay, int &hasdc, int &activeports, int &configadr) const
get the status of clients 
T readSDO(int slave_no, uint16_t index, uint8_t subidx) const
read the SDO object of the given slave no 
int ec_recover_slave(uint16 slave, int timeout)
int ec_receive_processdata(int timeout)
bool initSoem(const std::string &ifname)
int ec_init(const char *ifname)
int getNumClinets() const
get the number of clients 
uint8_t writeSDO(int slave_no, uint16_t index, uint8_t subidx, T value) const
write the SDO object of the given slave no 
int ec_config_map(void *pIOmap)
void write(int slave_no, uint8_t channel, uint8_t value)
writes 'value' to the 'channel-th' output-register of the given 'slave' 
int ec_writestate(uint16 slave)
boost::thread cycle_thread_
boolean ec_configdc(void)
EtherCAT exception. Currently this is only thrown in the event of a failure to construct an EtherCat ...
uint8_t readInput(int slave_no, uint8_t channel) const
Reads the "channel-th" input-register of the given slave no. 
EtherCatManager(const std::string &ifname)
Constructs and initializes the ethercat slaves on a given network interface. 
const std::string ifname_
int ec_SDOread(uint16 slave, uint16 index, uint8 subindex, boolean CA, int *psize, void *p, int timeout)
uint16 ec_statecheck(uint16 slave, uint16 reqstate, int timeout)
int ec_SDOwrite(uint16 Slave, uint16 Index, uint8 SubIndex, boolean CA, int psize, void *p, int Timeout)
#define IF_MINAS(_ec_slave)
int ec_config_init(uint8 usetable)