[STM32H5] 【NUCLEO- H563ZI 测评】5.EtherCat移植(二)

[复制链接]
 楼主| 穿西装的强子 发表于 2023-8-2 10:00 | 显示全部楼层 |阅读模式
<
本帖最后由 穿西装的强子 于 2023-8-2 10:03 编辑

1.下载和准备SOEM库,从官网给的GIT上下载:github.com/OpenEtherCATsociety/SOEM
我的版本比较旧,是1.3.1,git上最新的是1.4.0。
下载SOEM库的源代码,并根据所需的平台和编译器进行编译。
2.移植到工程内
6590764c9b5c06e8d0.png
将以上文件添加到工程内,添加好路径
6585764c9b6014607b.png
编译的时候会报错,在Compiler V5的typedef __packed struct 在Compiler V6上是报错的
因此需要修改#pragma pack(push,1)
typedef  struct
结束的时候再加#pragma pack(pop)
在ethercatmain.c文件中,ecx_statecheck函数需要ms定时器时间和us级延时,因此把之前工程的定时器中断计数值查询函数调用过来,再写一个us级的延时函数
  1. uint16 ecx_statecheck(ecx_contextt *context, uint16 slave, uint16 reqstate, int timeout)
  2. {
  3.    uint16 configadr, state, rval;
  4.    ec_alstatust slstat;
  5.    uint32_t timer2;
  6.    if ( slave > *(context->slavecount) )
  7.    {
  8.       return 0;
  9.    }
  10.    timer2=<span style="background-color: yellow;">DrvTimer_InqCount();</span>
  11.    configadr = context->slavelist[slave].configadr;
  12.    do
  13.    {
  14.       if (slave < 1)
  15.       {
  16.          rval = 0;
  17.          ecx_BRD(context->port, 0, ECT_REG_ALSTAT, sizeof(rval), &rval , EC_TIMEOUTRET);
  18.          rval = etohs(rval);
  19.       }
  20.       else
  21.       {
  22.          slstat.alstatus = 0;
  23.          slstat.alstatuscode = 0;
  24.          ecx_FPRD(context->port, configadr, ECT_REG_ALSTAT, sizeof(slstat), &slstat, EC_TIMEOUTRET);
  25.          rval = etohs(slstat.alstatus);
  26.          context->slavelist[slave].ALstatuscode = etohs(slstat.alstatuscode);
  27.       }
  28.       state = rval & 0x000f; /* read slave status */
  29.       if (state != reqstate)
  30.       {
  31. <span style="background-color: sienna;">         DrvTimer_DelayUs(1000);</span>
  32.       }
  33.    }
  34.    while ((state != reqstate) && ((<span style="background-color: yellow;">DrvTimer_InqCount()</span>-timer2)<timeout));
  35.    context->slavelist[slave].state = rval;
  36.    return state;
  37. }
在nicdrv.c文件中修改网口发送和接收函数
  1. int ecx_outframe(ecx_portt *port, int idx, int stacknumber)
  2. {
  3.          int lp, rval;
  4.    ec_stackT *stack;

  5.    if (!stacknumber)
  6.    {
  7.       stack = &(port->stack);
  8.                   lp = (*stack->txbuflength)[idx];
  9.                   MAC_Send((*stack->txbuf)[idx], lp);
  10.    }
  11.    else
  12.    {
  13.       stack = &(port->redport->stack);
  14.                   lp = (*stack->txbuflength)[idx];
  15. //                  dm9k_send_packet((*stack->txbuf)[idx], lp);
  16.    }
  17.    rval =1;
  18.    (*stack->rxbufstat)[idx] = EC_BUF_TX;
  19.    return rval;
  20. }
  21. int ecx_inframe(ecx_portt *port, int idx, int stacknumber)
  22. {
  23.          uint16  l;
  24.    int     rval;
  25.    int     idxf;
  26.    ec_etherheadert *ehp;
  27.    ec_comt *ecp;
  28.    ec_stackT *stack;
  29.    ec_bufT *rxbuf;
  30. //   stack = &(port->stack);

  31.                 if (!stacknumber)
  32.       {
  33.                                         stack = &(port->stack);
  34. //                                        if(ETH_CheckFrameReceived())         //检测是否收到数据包
  35.                                         {
  36.                                                         gEtherCatPara.receiveLen=0;
  37.                                                         memset(gEtherCatPara.receiveBuffer, 0, sizeof(gEtherCatPara.receiveBuffer));
  38. //                                                        DrvETH_lwip_pkt_handle();
  39.                                                         memcpy((uint8*)(*stack->rxbuf)[idx], (uint8*)gEtherCatPara.receiveBuffer, gEtherCatPara.receiveLen);
  40.                                         }
  41.       }
  42.      else
  43.       {
  44.         stack = &(port->redport->stack);
  45.                                 gEtherCatPara.receiveLen_DM9000 = 0;                                                                /* Çå³ý½ÓÊյij¤¶È */
  46.                     memset(gEtherCatPara.receiveBuffer_DM9000, 0, sizeof(gEtherCatPara.receiveBuffer_DM9000));
  47. //                                if(dm9k_receive_packet())
  48. //                                 {
  49. //                                        memcpy((uint8*)(*stack->rxbuf)[idx], (uint8*)gEtherCatPara.receiveBuffer_DM9000, gEtherCatPara.receiveLen_DM9000);
  50. //         }
  51.       }                                          
  52.                  rval = EC_NOFRAME;                 
  53.                  rxbuf = &(*stack->rxbuf)[idx];
  54.                  /* check if requested index is already in buffer ? */
  55.                  if ((idx < EC_MAXBUF) && ((*stack->rxbufstat)[idx] == EC_BUF_RCVD))
  56.                  {
  57.                                 l = (*rxbuf)[0] + ((uint16)((*rxbuf)[1] & 0x0f) << 8);
  58.                                 /* return WKC */
  59.                                 rval = ((*rxbuf)[l] + ((uint16)(*rxbuf)[l + 1] << 8));
  60.                                 /* mark as completed */
  61.                                 (*stack->rxbufstat)[idx] = EC_BUF_COMPLETE;
  62.                  }
  63.                  else
  64.                  {
  65.                                 /* non blocking call to retrieve frame from socket */
  66.                                 if (ecx_recvpkt(port, stacknumber))
  67.                                 {
  68.                                          rval = EC_OTHERFRAME;
  69.                                          ehp =(ec_etherheadert*)(stack->tempbuf);
  70.                                          /* check if it is an EtherCAT frame */
  71.                                          if (ehp->etype == htons(ETH_P_ECAT))
  72.                                          {
  73.                                                         ecp =(ec_comt*)(&(*stack->tempbuf)[ETH_HEADERSIZE]);
  74.                                                         l = etohs(ecp->elength) & 0x0fff;                                                
  75.                                                         idxf = ecp->index;
  76.                                                         /* found index equals reqested index ? */
  77.                                                         if (idxf == idx)
  78.                                                         {
  79.                                                                  /* yes, put it in the buffer array (strip ethernet header) */
  80.                                                                  memcpy(rxbuf, &(*stack->tempbuf)[ETH_HEADERSIZE], (*stack->txbuflength)[idx] - ETH_HEADERSIZE);
  81.                                                                 /* return WKC */
  82.                                                                  l=(*stack->txbuflength)[idx] - ETH_HEADERSIZE;
  83.                                                                  rval = ((*rxbuf)[l-2] + ((uint16)((*rxbuf)[l-1]) << 8));
  84.                                                                  /* mark as completed */
  85.                                                                  (*stack->rxbufstat)[idx] = EC_BUF_COMPLETE;
  86.                                                                  /* store MAC source word 1 for redundant routing info */
  87.                                                                  (*stack->rxsa)[idx] = etohs(ehp->sa1);
  88.                                                         }
  89.                                                         else
  90.                                                         {
  91.                                                                  /* check if index exist? */
  92.                                                                  if (idxf < EC_MAXBUF)
  93.                                                                  {
  94. //                                                                                rxbuf = &(*stack->rxbuf)[idxf];
  95. //                                                                                /* put it in the buffer array (strip ethernet header) */
  96. //                                                                                memcpy(rxbuf, &(*stack->tempbuf)[ETH_HEADERSIZE], (*stack->txbuflength)[idxf] - ETH_HEADERSIZE);
  97. //                                                                                /* mark as received */
  98. //                                                                                (*stack->rxbufstat)[idxf] = EC_BUF_RCVD;
  99. //                                                                                (*stack->rxsa)[idxf] = etohs(ehp->sa1);
  100.                                                                           (*stack->rxbufstat)[idxf] = EC_BUF_EMPTY;
  101.                                                                  }
  102.                                                                  else
  103.                                                                  {
  104.                                                                                 /* strange things happend */
  105.                                                                  }
  106.                                                         }
  107.                                          }
  108.                                 }   
  109.                  }
  110.    return rval;
  111. }
发送函数

  1. uint8_t MAC_Send(uint8_t *data, int length)
  2. {
  3.         ETH_BufferTypeDef Txbuffer;
  4.         uint8_t i;
  5.         ETH_TxPacketConfig TxPacketCfg;
  6.         TxPacketCfg.ChecksumCtrl = ETH_CHECKSUM_IPHDR_INSERT;
  7.         Txbuffer.buffer = data;
  8.         Txbuffer.len = length;
  9.         TxPacketCfg.Length = length;
  10.         TxPacketCfg.TxBuffer = Txbuffer;
  11.         HAL_ETH_Transmit_IT(ð_handle, &TxPacketCfg);

  12. //                 memcpy((u8*)(DMATxDescToSet->Buffer1Addr), (u8*)data, length);
  13. //                /* Prepare transmit descriptors to give to DMA*/
  14. //          i=ETH_Prepare_Transmit_Descriptors(length);
  15.           return i;
  16. }
根据使用ETH的THAL_ETH_Transmit_IT中断发送,将数据从网口中发出去,再将接收到的数据存储在gEtherCatPara.receiveBuffer_DM9000(之前是在DM9000的PHY上移植的),复制到内部缓存里memcpy((uint8*)(*stack->rxbuf)[idx], (uint8*)gEtherCatPara.receiveBuffer, gEtherCatPara.receiveLen);
至此,移植功能完成,下一部是对针对电机进行配置和控制。
shenxiaolin 发表于 2023-8-9 10:35 | 显示全部楼层
支持一下
您需要登录后才可以回帖 登录 | 注册

本版积分规则

62

主题

259

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部

62

主题

259

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部