slaveinfo.c

Go to the documentation of this file.
00001 /** \file
00002  * \brief Example code for Simple Open EtherCAT master
00003  *
00004  * Usage : slaveinfo [ifname] [-sdo]
00005  * Ifname is NIC interface, f.e. eth0.
00006  * Optional -sdo to display CoE object dictionary.
00007  *
00008  * This shows the configured slave data.
00009  *
00010  * (c)Arthur Ketels 2010 - 2011
00011  */
00012 
00013 #include <stdio.h>
00014 #include <string.h>
00015 
00016 #include "ethercattype.h"
00017 #include "nicdrv.h"
00018 #include "ethercatbase.h"
00019 #include "ethercatmain.h"
00020 #include "ethercatconfig.h"
00021 #include "ethercatcoe.h"
00022 #include "ethercatdc.h"
00023 #include "ethercatprint.h"
00024 
00025 char IOmap[4096];
00026 ec_ODlistt ODlist;
00027 ec_OElistt OElist;
00028 boolean printSDO = FALSE;
00029 char usdo[128];
00030 char hstr[1024];
00031 
00032 char* SDO2string(uint16 slave, uint16 index, uint8 subidx, uint16 dtype)
00033 {
00034   int l = sizeof(usdo) - 1, i;
00035   uint8 *u8;
00036   int8 *i8;
00037   uint16 *u16;
00038   int16 *i16;
00039   uint32 *u32;
00040   int32 *i32;
00041   uint64 *u64;
00042   int64 *i64;
00043   float *sr;
00044   double *dr;
00045   char es[32];
00046 
00047   memset(&usdo, 0, 128);
00048   ec_SDOread(slave, index, subidx, FALSE, &l, &usdo, EC_TIMEOUTRXM);
00049   if (EcatError)
00050   {
00051     return ec_elist2string();
00052   }
00053   else
00054   {
00055     switch(dtype)
00056     {
00057       case ECT_BOOLEAN:
00058         u8 = (uint8*) &usdo[0];
00059         if (*u8) sprintf(hstr, "TRUE"); 
00060          else sprintf(hstr, "FALSE");
00061         break;
00062       case ECT_INTEGER8:
00063         i8 = (int8*) &usdo[0];
00064         sprintf(hstr, "0x%2.2x %d", *i8, *i8); 
00065         break;
00066       case ECT_INTEGER16:
00067         i16 = (int16*) &usdo[0];
00068         sprintf(hstr, "0x%4.4x %d", *i16, *i16); 
00069         break;
00070       case ECT_INTEGER32:
00071       case ECT_INTEGER24:
00072         i32 = (int32*) &usdo[0];
00073         sprintf(hstr, "0x%8.8x %d", *i32, *i32); 
00074         break;
00075       case ECT_INTEGER64:
00076         i64 = (int64*) &usdo[0];
00077         sprintf(hstr, "0x%16.16llx %lld", *i64, *i64); 
00078         break;
00079       case ECT_UNSIGNED8:
00080         u8 = (uint8*) &usdo[0];
00081         sprintf(hstr, "0x%2.2x %u", *u8, *u8); 
00082         break;
00083       case ECT_UNSIGNED16:
00084         u16 = (uint16*) &usdo[0];
00085         sprintf(hstr, "0x%4.4x %u", *u16, *u16); 
00086         break;
00087       case ECT_UNSIGNED32:
00088       case ECT_UNSIGNED24:
00089         u32 = (uint32*) &usdo[0];
00090         sprintf(hstr, "0x%8.8x %u", *u32, *u32); 
00091         break;
00092       case ECT_UNSIGNED64:
00093         u64 = (uint64*) &usdo[0];
00094         sprintf(hstr, "0x%16.16llx %llu", *u64, *u64); 
00095         break;
00096       case ECT_REAL32:
00097         sr = (float*) &usdo[0];
00098         sprintf(hstr, "%f", *sr); 
00099         break;
00100       case ECT_REAL64:
00101         dr = (double*) &usdo[0];
00102         sprintf(hstr, "%f", *dr); 
00103         break;
00104       case ECT_BIT1:
00105       case ECT_BIT2:
00106       case ECT_BIT3:
00107       case ECT_BIT4:
00108       case ECT_BIT5:
00109       case ECT_BIT6:
00110       case ECT_BIT7:
00111       case ECT_BIT8:
00112         u8 = (uint8*) &usdo[0];
00113         sprintf(hstr, "0x%x", *u8); 
00114         break;
00115       case ECT_VISIBLE_STRING:
00116         strcpy(hstr, usdo);
00117         break;
00118       case ECT_OCTET_STRING:
00119         hstr[0] = 0x00;
00120         for (i = 0 ; i < l ; i++)
00121         { 
00122           sprintf(es, "0x%2.2x ", usdo[i]);
00123           strcat( hstr, es);
00124         }
00125         break;
00126       default:
00127         sprintf(hstr, "Unknown type");
00128     }
00129     return hstr;
00130   }
00131 }
00132 
00133 void slaveinfo(char *ifname)
00134 {
00135   int cnt, i, j, nSM;
00136   uint16 ssigen, dtype;
00137   
00138   printf("Starting slaveinfo\n");
00139   
00140   /* initialise SOEM, bind socket to ifname */
00141   if (ec_init(ifname))
00142   { 
00143     printf("ec_init on %s succeeded.\n",ifname);
00144     /* find and auto-config slaves */
00145     if ( ec_config(FALSE, &IOmap) > 0 )
00146     {
00147       printf("%d slaves found and configured.\n",ec_slavecount);
00148       printf("Calculated workcounter %d\n",ec_group[0].expectedWKC);
00149       /* wait for all slaves to reach SAFE_OP state */
00150       ec_statecheck(0, EC_STATE_SAFE_OP,  EC_TIMEOUTSTATE * 3);
00151       if (ec_slave[0].state != EC_STATE_SAFE_OP )
00152       {
00153         printf("Not all slaves reached safe operational state.\n");
00154         ec_readstate();
00155         for(i = 1; i<=ec_slavecount ; i++)
00156         {
00157           if(ec_slave[i].state != EC_STATE_SAFE_OP)
00158           {
00159             printf("Slave %d State=%2x StatusCode=%4x : %s\n",
00160               i, ec_slave[i].state, ec_slave[i].ALstatuscode, ec_ALstatuscode2string(ec_slave[i].ALstatuscode));
00161           }
00162         }
00163       }
00164       
00165       ec_configdc();
00166       
00167       ec_readstate();
00168       for( cnt = 1 ; cnt <= ec_slavecount ; cnt++)
00169       {
00170         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",
00171              cnt, ec_slave[cnt].name, ec_slave[cnt].Obits, ec_slave[cnt].Ibits,
00172              ec_slave[cnt].state, ec_slave[cnt].pdelay, ec_slave[cnt].hasdc);
00173         if (ec_slave[cnt].hasdc) printf(" DCParentport:%d\n", ec_slave[cnt].parentport);
00174         printf(" Activeports:%d.%d.%d.%d\n", (ec_slave[cnt].activeports & 0x01) > 0 ,
00175                              (ec_slave[cnt].activeports & 0x02) > 0 , 
00176                              (ec_slave[cnt].activeports & 0x04) > 0 , 
00177                              (ec_slave[cnt].activeports & 0x08) > 0 );
00178         printf(" Configured address: %4.4x\n", ec_slave[cnt].configadr);
00179         printf(" Man: %8.8x ID: %8.8x Rev: %8.8x\n", (int)ec_slave[cnt].eep_man, (int)ec_slave[cnt].eep_id, (int)ec_slave[cnt].eep_rev);
00180         for(nSM = 0 ; nSM < EC_MAXSM ; nSM++)
00181         {
00182           if(ec_slave[cnt].SM[nSM].StartAddr > 0)
00183             printf(" SM%1d A:%4.4x L:%4d F:%8.8x Type:%d\n",nSM, ec_slave[cnt].SM[nSM].StartAddr, ec_slave[cnt].SM[nSM].SMlength,
00184                   (int)ec_slave[cnt].SM[nSM].SMflags, ec_slave[cnt].SMtype[nSM]);
00185         }
00186         for(j = 0 ; j < ec_slave[cnt].FMMUunused ; j++)
00187         {
00188           printf(" FMMU%1d Ls:%8.8x Ll:%4d Lsb:%d Leb:%d Ps:%4.4x Psb:%d Ty:%2.2x Act:%2.2x\n", j,
00189                  (int)ec_slave[cnt].FMMU[j].LogStart, ec_slave[cnt].FMMU[j].LogLength, ec_slave[cnt].FMMU[j].LogStartbit,
00190                  ec_slave[cnt].FMMU[j].LogEndbit, ec_slave[cnt].FMMU[j].PhysStart, ec_slave[cnt].FMMU[j].PhysStartBit,
00191                  ec_slave[cnt].FMMU[j].FMMUtype, ec_slave[cnt].FMMU[j].FMMUactive);
00192         }
00193         printf(" FMMUfunc 0:%d 1:%d 2:%d 3:%d\n",
00194                  ec_slave[cnt].FMMU0func, ec_slave[cnt].FMMU2func, ec_slave[cnt].FMMU2func, ec_slave[cnt].FMMU3func);
00195         printf(" MBX length wr: %d rd: %d MBX protocols : %2.2x\n", ec_slave[cnt].mbx_l, ec_slave[cnt].mbx_rl, ec_slave[cnt].mbx_proto);
00196         ssigen = ec_siifind(cnt, ECT_SII_GENERAL);
00197         /* SII general section */
00198         if (ssigen)
00199                 {
00200           ec_slave[cnt].CoEdetails = ec_siigetbyte(cnt, ssigen + 0x07);
00201           ec_slave[cnt].FoEdetails = ec_siigetbyte(cnt, ssigen + 0x08);
00202           ec_slave[cnt].EoEdetails = ec_siigetbyte(cnt, ssigen + 0x09);
00203           ec_slave[cnt].SoEdetails = ec_siigetbyte(cnt, ssigen + 0x0a);
00204           if((ec_siigetbyte(cnt, ssigen + 0x0d) & 0x02) > 0)
00205           {
00206             ec_slave[cnt].blockLRW = 1;
00207             ec_slave[0].blockLRW++;           
00208           } 
00209           ec_slave[cnt].Ebuscurrent = ec_siigetbyte(cnt, ssigen + 0x0e);
00210           ec_slave[cnt].Ebuscurrent += ec_siigetbyte(cnt, ssigen + 0x0f) << 8;
00211           ec_slave[0].Ebuscurrent += ec_slave[cnt].Ebuscurrent;
00212                 }
00213         printf(" CoE details: %2.2x FoE details: %2.2x EoE details: %2.2x SoE details: %2.2x\n",
00214                ec_slave[cnt].CoEdetails, ec_slave[cnt].FoEdetails, ec_slave[cnt].EoEdetails, ec_slave[cnt].SoEdetails);
00215         printf(" Ebus current: %d[mA]\n only LRD/LWR:%d\n",
00216                ec_slave[cnt].Ebuscurrent, ec_slave[cnt].blockLRW);
00217         if ((ec_slave[cnt].mbx_proto & 0x04) && printSDO)
00218         {
00219           ODlist.Entries = 0;
00220           memset(&ODlist, 0, sizeof(ODlist));
00221           if( ec_readODlist(cnt, &ODlist))
00222           {
00223             printf(" CoE Object Description found, %d entries.\n",ODlist.Entries);
00224             for( i = 0 ; i < ODlist.Entries ; i++)
00225             {
00226               ec_readODdescription(i, &ODlist); 
00227               while(EcatError)
00228               {
00229                 printf("%s", ec_elist2string());
00230               }
00231               printf(" Index: %4.4x Datatype: %4.4x Objectcode: %2.2x Name: %s\n",
00232                    ODlist.Index[i], ODlist.DataType[i], ODlist.ObjectCode[i], ODlist.Name[i]);
00233               memset(&OElist, 0, sizeof(OElist));
00234               ec_readOE(i, &ODlist, &OElist);
00235               while(EcatError)
00236               {
00237                 printf("%s", ec_elist2string());
00238               }
00239               for( j = 0 ; j < ODlist.MaxSub[i]+1 ; j++)
00240               {
00241                 if ((OElist.DataType[j] > 0) && (OElist.BitLength[j] > 0))
00242                 {
00243                   printf("  Sub: %2.2x Datatype: %4.4x Bitlength: %4.4x Obj.access: %4.4x Name: %s\n",
00244                      j, OElist.DataType[j], OElist.BitLength[j], OElist.ObjAccess[j], OElist.Name[j]);
00245                   if ((OElist.ObjAccess[j] & 0x0007))
00246                   {
00247                     dtype = OElist.DataType[j];
00248                     printf("          Value :%s\n", SDO2string(cnt, ODlist.Index[i], j, OElist.DataType[j]));
00249                   }
00250                 }
00251               } 
00252             } 
00253           }
00254           else
00255           {
00256             while(EcatError)
00257             {
00258               printf("%s", ec_elist2string());
00259             }
00260           }
00261         } 
00262       } 
00263     }
00264     else
00265     {
00266       printf("No slaves found!\n");
00267     }
00268     printf("End slaveinfo, close socket\n");
00269     /* stop SOEM, close socket */
00270     ec_close();
00271   }
00272   else
00273   {
00274     printf("No socket connection on %s\nExcecute as root\n",ifname);
00275   } 
00276 } 
00277 
00278 int main(int argc, char *argv[])
00279 {
00280   printf("SOEM (Simple Open EtherCAT Master)\nSlaveinfo\n");
00281   
00282   if (argc > 1)
00283   {   
00284     if ((argc > 2) && (strncmp(argv[2], "-sdo", sizeof("-sdo")) == 0)) printSDO = TRUE;
00285     /* start slaveinfo */
00286     slaveinfo(argv[1]);
00287   }
00288   else
00289   {
00290     printf("Usage: slaveinfo ifname [options]\nifname = eth0 for example\nOptions : -sdo : print SDO info\n");
00291   } 
00292   
00293   printf("End program\n");
00294   return (0);
00295 }
Generated by  doxygen 1.6.3