打印
[STM32H5]

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

[复制链接]
753|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 穿西装的强子 于 2023-8-2 10:03 编辑

1.下载和准备SOEM库,从官网给的GIT上下载:github.com/OpenEtherCATsociety/SOEM
我的版本比较旧,是1.3.1,git上最新的是1.4.0。
下载SOEM库的源代码,并根据所需的平台和编译器进行编译。
2.移植到工程内

将以上文件添加到工程内,添加好路径

编译的时候会报错,在Compiler V5的typedef __packed struct 在Compiler V6上是报错的
因此需要修改#pragma pack(push,1)
typedef  struct
结束的时候再加#pragma pack(pop)
在ethercatmain.c文件中,ecx_statecheck函数需要ms定时器时间和us级延时,因此把之前工程的定时器中断计数值查询函数调用过来,再写一个us级的延时函数
uint16 ecx_statecheck(ecx_contextt *context, uint16 slave, uint16 reqstate, int timeout)
{
   uint16 configadr, state, rval;
   ec_alstatust slstat;
   uint32_t timer2;
   if ( slave > *(context->slavecount) )
   {
      return 0;
   }
   timer2=<span style="background-color: yellow;">DrvTimer_InqCount();</span>
   configadr = context->slavelist[slave].configadr;
   do
   {
      if (slave < 1)
      {
         rval = 0;
         ecx_BRD(context->port, 0, ECT_REG_ALSTAT, sizeof(rval), &rval , EC_TIMEOUTRET);
         rval = etohs(rval);
      }
      else
      {
         slstat.alstatus = 0;
         slstat.alstatuscode = 0;
         ecx_FPRD(context->port, configadr, ECT_REG_ALSTAT, sizeof(slstat), &slstat, EC_TIMEOUTRET);
         rval = etohs(slstat.alstatus);
         context->slavelist[slave].ALstatuscode = etohs(slstat.alstatuscode);
      }
      state = rval & 0x000f; /* read slave status */
      if (state != reqstate)
      {
<span style="background-color: sienna;">         DrvTimer_DelayUs(1000);</span>
      }
   }
   while ((state != reqstate) && ((<span style="background-color: yellow;">DrvTimer_InqCount()</span>-timer2)<timeout));
   context->slavelist[slave].state = rval;
   return state;
}
在nicdrv.c文件中修改网口发送和接收函数
int ecx_outframe(ecx_portt *port, int idx, int stacknumber)
{
         int lp, rval;
   ec_stackT *stack;

   if (!stacknumber)
   {
      stack = &(port->stack);
                  lp = (*stack->txbuflength)[idx];
                  MAC_Send((*stack->txbuf)[idx], lp);
   }
   else
   {
      stack = &(port->redport->stack);
                  lp = (*stack->txbuflength)[idx];
//                  dm9k_send_packet((*stack->txbuf)[idx], lp);
   }
   rval =1;
   (*stack->rxbufstat)[idx] = EC_BUF_TX;
   return rval;
}
int ecx_inframe(ecx_portt *port, int idx, int stacknumber)
{
         uint16  l;
   int     rval;
   int     idxf;
   ec_etherheadert *ehp;
   ec_comt *ecp;
   ec_stackT *stack;
   ec_bufT *rxbuf;
//   stack = &(port->stack);

                if (!stacknumber)
      {
                                        stack = &(port->stack);
//                                        if(ETH_CheckFrameReceived())         //检测是否收到数据包
                                        {
                                                        gEtherCatPara.receiveLen=0;
                                                        memset(gEtherCatPara.receiveBuffer, 0, sizeof(gEtherCatPara.receiveBuffer));
//                                                        DrvETH_lwip_pkt_handle();
                                                        memcpy((uint8*)(*stack->rxbuf)[idx], (uint8*)gEtherCatPara.receiveBuffer, gEtherCatPara.receiveLen);
                                        }
      }
     else
      {
        stack = &(port->redport->stack);
                                gEtherCatPara.receiveLen_DM9000 = 0;                                                                /* Çå³ý½ÓÊյij¤¶È */
                    memset(gEtherCatPara.receiveBuffer_DM9000, 0, sizeof(gEtherCatPara.receiveBuffer_DM9000));
//                                if(dm9k_receive_packet())
//                                 {
//                                        memcpy((uint8*)(*stack->rxbuf)[idx], (uint8*)gEtherCatPara.receiveBuffer_DM9000, gEtherCatPara.receiveLen_DM9000);
//         }
      }                                          
                 rval = EC_NOFRAME;                 
                 rxbuf = &(*stack->rxbuf)[idx];
                 /* check if requested index is already in buffer ? */
                 if ((idx < EC_MAXBUF) && ((*stack->rxbufstat)[idx] == EC_BUF_RCVD))
                 {
                                l = (*rxbuf)[0] + ((uint16)((*rxbuf)[1] & 0x0f) << 8);
                                /* return WKC */
                                rval = ((*rxbuf)[l] + ((uint16)(*rxbuf)[l + 1] << 8));
                                /* mark as completed */
                                (*stack->rxbufstat)[idx] = EC_BUF_COMPLETE;
                 }
                 else
                 {
                                /* non blocking call to retrieve frame from socket */
                                if (ecx_recvpkt(port, stacknumber))
                                {
                                         rval = EC_OTHERFRAME;
                                         ehp =(ec_etherheadert*)(stack->tempbuf);
                                         /* check if it is an EtherCAT frame */
                                         if (ehp->etype == htons(ETH_P_ECAT))
                                         {
                                                        ecp =(ec_comt*)(&(*stack->tempbuf)[ETH_HEADERSIZE]);
                                                        l = etohs(ecp->elength) & 0x0fff;                                                
                                                        idxf = ecp->index;
                                                        /* found index equals reqested index ? */
                                                        if (idxf == idx)
                                                        {
                                                                 /* yes, put it in the buffer array (strip ethernet header) */
                                                                 memcpy(rxbuf, &(*stack->tempbuf)[ETH_HEADERSIZE], (*stack->txbuflength)[idx] - ETH_HEADERSIZE);
                                                                /* return WKC */
                                                                 l=(*stack->txbuflength)[idx] - ETH_HEADERSIZE;
                                                                 rval = ((*rxbuf)[l-2] + ((uint16)((*rxbuf)[l-1]) << 8));
                                                                 /* mark as completed */
                                                                 (*stack->rxbufstat)[idx] = EC_BUF_COMPLETE;
                                                                 /* store MAC source word 1 for redundant routing info */
                                                                 (*stack->rxsa)[idx] = etohs(ehp->sa1);
                                                        }
                                                        else
                                                        {
                                                                 /* check if index exist? */
                                                                 if (idxf < EC_MAXBUF)
                                                                 {
//                                                                                rxbuf = &(*stack->rxbuf)[idxf];
//                                                                                /* put it in the buffer array (strip ethernet header) */
//                                                                                memcpy(rxbuf, &(*stack->tempbuf)[ETH_HEADERSIZE], (*stack->txbuflength)[idxf] - ETH_HEADERSIZE);
//                                                                                /* mark as received */
//                                                                                (*stack->rxbufstat)[idxf] = EC_BUF_RCVD;
//                                                                                (*stack->rxsa)[idxf] = etohs(ehp->sa1);
                                                                          (*stack->rxbufstat)[idxf] = EC_BUF_EMPTY;
                                                                 }
                                                                 else
                                                                 {
                                                                                /* strange things happend */
                                                                 }
                                                        }
                                         }
                                }   
                 }
   return rval;
}
发送函数

uint8_t MAC_Send(uint8_t *data, int length)
{
        ETH_BufferTypeDef Txbuffer;
        uint8_t i;
        ETH_TxPacketConfig TxPacketCfg;
        TxPacketCfg.ChecksumCtrl = ETH_CHECKSUM_IPHDR_INSERT;
        Txbuffer.buffer = data;
        Txbuffer.len = length;
        TxPacketCfg.Length = length;
        TxPacketCfg.TxBuffer = Txbuffer;
        HAL_ETH_Transmit_IT(ð_handle, &TxPacketCfg);

//                 memcpy((u8*)(DMATxDescToSet->Buffer1Addr), (u8*)data, length);
//                /* Prepare transmit descriptors to give to DMA*/
//          i=ETH_Prepare_Transmit_Descriptors(length);
          return i;
}
根据使用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 | 只看该作者
支持一下

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

11

主题

69

帖子

2

粉丝