EtherCAT主站SOEM源码解析----ecx_siiPDO()

1、从站EEPROM的PDO信息

从站EEPROM存储的PDO信息如下如所示:
EtherCAT主站SOEM源码解析----ecx_siiPDO()_第1张图片

TxPDO的类型名为50(0x0032),RxPDO的类型名为51(0x0033).
每个PDO占用的EEPROM字节数为8+8*er(er位Entry个数)。

2、读取PDOx信息

SOEM中函数ecx_siiPDO()读取EEPROM中PDO信息并:
(1) 统计每个SM所对应的bit length
(2) 返回bit length的总和。

int ecx_siiPDO(ecx_contextt *context, uint16 slave, ec_eepromPDOt* PDO, uint8 t)
{
   uint16 a , w, c, e, er, Size;
   uint8 eectl = context->slavelist[slave].eep_pdi;

   Size = 0;
   PDO->nPDO = 0;
   PDO->Length = 0;
   PDO->Index[1] = 0;
   for (c = 0 ; c < EC_MAXSM ; c++) PDO->SMbitsize[c] = 0;
   if (t > 1)
      t = 1;
   PDO->Startpos = ecx_siifind(context, slave, ECT_SII_PDO + t);
   if (PDO->Startpos > 0)
   {
      a = PDO->Startpos;
      w = ecx_siigetbyte(context, slave, a++);
      w += (ecx_siigetbyte(context, slave, a++) << 8);
      PDO->Length = w;  //PDO信息的字数
      c = 1;
      /* traverse through all PDOs */
      do   //每执行一次do循环,a的值会增加8*e+8, c的值会增加4*e+4, e为PDO中的Entry数目
      {
         PDO->nPDO++;
         PDO->Index[PDO->nPDO] = ecx_siigetbyte(context, slave, a++);
         PDO->Index[PDO->nPDO] += (ecx_siigetbyte(context, slave, a++) << 8);
         PDO->BitSize[PDO->nPDO] = 0;
         c++;
         e = ecx_siigetbyte(context, slave, a++); //entry 数目
         PDO->SyncM[PDO->nPDO] = ecx_siigetbyte(context, slave, a++);   //该PDO属于哪个同步管理器
         a += 4;  //a=8, 跳转到Entry1,每个Entry8个bytes
         c += 2;  //c的单位为字,a的单位为字节
         if (PDO->SyncM[PDO->nPDO] < EC_MAXSM) /* active and in range SM? */
         {
            /* read all entries defined in PDO */
            for (er = 1; er <= e; er++)  //每执行一次for循环,c的值会加4,a的值会加8
            {
               c += 4;
               a += 5;
               PDO->BitSize[PDO->nPDO] += ecx_siigetbyte(context, slave, a++);
               a += 2;
            }
            PDO->SMbitsize[PDO->SyncM[PDO->nPDO] ] += PDO->BitSize[PDO->nPDO];
            Size += PDO->BitSize[PDO->nPDO];
            c++;
         }
         else /* PDO deactivated because SM is 0xff or > EC_MAXSM */
         {
            c += 4 * e;
            a += 8 * e;
            c++;
         }
         if (PDO->nPDO >= (EC_MAXEEPDO - 1))
         {
            c = PDO->Length; /* limit number of PDO entries in buffer */
         }
      }
      while (c < PDO->Length);
   }
   if (eectl)
   {
      ecx_eeprom2pdi(context, slave); /* if eeprom control was previously pdi then restore */
   }

   return (Size);
}

3、EL1014实例

EL1014中EEPROM中存储的TxPDO信息如下:
EtherCAT主站SOEM源码解析----ecx_siiPDO()_第2张图片

总共有4个PDO,每个PDO包含1个Entry,每个Entry的bitlen为1,所以调用函数ecx_siiPDO()读取EL1014 PDO信息时,该函数的返回值为4.

你可能感兴趣的:(EtherCAT主站SOEM源码解析----ecx_siiPDO())