This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TMS570LC4357:在使用 lwIP 协议&quot 的数据接收周期之后、EMAC 模块无法进入接收中断

Guru**** 657500 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1253590/tms570lc4357-emac-module-fails-to-enter-receive-interrupt-after-period-of-data-reception-with-lwip-protocol

器件型号:TMS570LC4357

 你好  

  我将 lwIP 协议与 EMAC 模块结合使用以进行数据传输和接收。 发送数据的过程非常顺利、但是 EMAC 模块在接收数据时遇到了问题。 在特定时间段内接收数据后、EMAC 模块无法进入接收中断。 我正在寻求有关如何解决此问题并确保 EMAC 模块能够连续不间断地接收数据的帮助。 谢谢!  

 我的 lwIP 初始化如下:

void EMAC_LwIP_init (uint8_t * macAddress)
{
    unsigned int 	ipAddr;
    uint32  emacCtrlBase =  0xFCF78800U;
    uint32  emacBase =  0xFCF78000U;	

	EMACInit(emacCtrlBase,emacBase);
	IntMasterIRQEnable();//中断

   /* for static IP address. Change address as required, and uncomment the previous statement. */ 	
	uint8 ip_addr[4] = { 172, 22, 1, 1 };
	uint8 netmask[4] = { 255, 255, 255, 0 };
	uint8 gateway[4] = { 172, 22, 1, 1 };  
	ipAddr = lwIPInit(0, macAddress,
			*((uint32_t *)ip_addr),
			*((uint32_t *)netmask),
			*((uint32_t *)gateway),
			IPADDR_USE_STATIC  );
	

}

   我的 EMAC 模块的接收中断如下所示。 测试过程中、我注意到接收中断在 R0 (接收空闲缓冲区计数寄存器)接收到值0xCD 后停止(此时、寄存器不会改变、除非我重新初始化)。 我怀疑我的中断函数中的尾部处理可能存在问题。 下面是我的中断函数:

#pragma INTERRUPT(EMACCore0RxIsr, IRQ)
uint32 countrxisr = 0;
void EMACCore0RxIsr(void)
{   

    char* tmpptr;
    uint32_t tmp = 0;
    uint32_t CurFinishCP = HWREG(EMAC_BASE + EMAC_RXCP(0)); /* Pointer to the buffer that has completed data reception */
    EMACDesc_t* RXCP = EMAC_SL_CurRXCP; /* Pointer to the current processing receive buffer */
    MACFrame_t* MacFramePtr = NULL;

    ECTRL_C0RXEN = 0U; /* Disable interrupts before processing data */
    HWREG(EMAC_BASE + EMAC_RXCP(0)) = CurFinishCP; /* Confirm the current processed CP (Complete Pointer) */
    HWREG(EMAC_BASE + EMAC_MACEOIVECTOR) = 1U; /* Acknowledge the completion of receive interrupt */

    if (countrxisr == 0U) // First frame
    {
        HWREG(EMAC_BASE + EMAC_RXHDP(0)) = CurFinishCP;
        EMAC_SL_CurRXCP = (EMACDesc_t*)CurFinishCP;
        RXCP = (EMACDesc_t*)CurFinishCP;
        countrxisr = 1;
    } /* When the current receive queue reaches the end, reassign the receive buffer pointer to the first position */
    else if (HWREG(EMAC_BASE + EMAC_RXHDP(0)) == 0U)
    {
        HWREG(EMAC_BASE + EMAC_RXHDP(0)) = CurFinishCP;
        EMAC_SL_CurRXCP = (EMACDesc_t*)CurFinishCP;
        RXCP = (EMACDesc_t*)CurFinishCP; // Original
    } /* When the current receive queue reaches the end, reassign the receive buffer pointer to the first position */
    else
    {
        EMAC_SL_CurRXCP = ((EMACDesc_t*)(CurFinishCP)) + 1U;
        EMAC_SL_CurRXCP = (EMACDesc_t*)((char*)EMAC_SL_CurRXCP + 4); /* Appear 4 bytes more data than 3137, so add this offset */
    } /* Update the last processed CP */

    while ((uint32_t)(RXCP) <= CurFinishCP)
    {
        /*1============================================================================1*/
        /* Only process single packet data, discard fragmented data packets */
        if ((RXCP->EOP == 1U) && (RXCP->SOP == 1U))
        {
            MacFramePtr = (MACFrame_t*)EMACSwizzleData((uint32)RXCP->BufferPtr); /* Pointer to MAC layer data frame information */

            switch (MacFramePtr->FrameType)
            {
                case IPV4_DT_ARP_FRAME:
                {
                    if (EMACSwizzleData16(RXCP->Length) <= sizeof EMAC_SL_RXBuffer.Data[0].Buffer)
                    {
                        memcpy(EMAC_SL_RXBuffer.Data[EMAC_SL_RXBuffer.Tail.Cnt].Buffer, EMACSwizzleData(RXCP->BufferPtr), EMACSwizzleData16(RXCP->Length));
                        EMAC_SL_RXBuffer.Tail.Cnt++;
                    }

                    break;
                } /* Received ARP data frame, store the data in the receive buffer for later processing */

                case IPV4_DT_IP_FRAME:
                {
                    IPHeader_t* IPHeaderPtr = (IPHeader_t*)(EMACSwizzleData(RXCP->BufferPtr) + 14U); /* IP header information of the current data packet */

                    
                    if ((IPHeaderPtr->SrcIP == REMOTE_IP_ADDR) && ((IPHeaderPtr->DstIP == LOCAL_IP_ADDR) || (IPHeaderPtr->DstIP == BROADCAST_IP_ADDR)) && (IPHeaderPtr->Protol == IP_PROTO_UDP))
                    {
                        EMAC_SL_IsRXRemoteUDPData = TRUE;

                        if (EMACSwizzleData16(RXCP->Length) <= sizeof EMAC_SL_RXBuffer.Data[0].Buffer)
                        {
                            memcpy(EMAC_SL_RXBuffer.Data[EMAC_SL_RXBuffer.Tail.Cnt].Buffer, EMACSwizzleData(RXCP->BufferPtr), EMACSwizzleData16(RXCP->Length));
                            EMAC_SL_RXBuffer.Tail.Cnt++;
                        }
                    } /* Received IP address matches the local IP address and data type is UDP, then process the data frame */

                    break;
                } /* Received IP data frame, store the data in the receive buffer for later processing */

                default:
                {
                    break;
                }
            }
        }
        /*1============================================================================1*/

        RXCP->Length = RX_BUFFER_SIZE;
        RXCP->OWNER = 1U;
        RXCP++;
        RXCP = (char*)RXCP + 4; /* Here, don't know why data in buffer is 32 * 5 bytes while 3137 is 32 * 4 bytes, perhaps because of the lwIP protocol */

    }

    ECTRL_C0RXEN = 1U; /* Reactivate interrupts */
}

您能帮助我分析问题可能发生的位置吗? 谢谢你。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    您必须在每次处理数据包后通过调用函数"pbuf_free ()"释放 Pbuf。

    有关更多详细信息、请查看以下主题:

    (+) TMS570LS3137:lwIP 演示在大约60个 UDP 数据包后暂停-基于 Arm 的微控制器论坛-基于 Arm 的微控制器- TI E2E 支持论坛

    --

    谢谢。此致、
    Jagadish。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好

     我已经阅读了您提供的帖子,并尝试了您提到的方法,使用 pbuf_free()。 我可以接收到比以往更多的数据包、但之前的问题仍然存在–中断停止为数据接收而触发。

     此外、我注意到、当我修改该函数中的 MAX_RX_PBUF_ALLOC 时、我能接收到更多的数据包。 但是、我可以将其设置为最大值60U。 我还没有找到恢复接收缓冲区的方法、仍然存在因数据接收而不触发中断的问题。 您能否查看此代码并帮助我分析问题?

    /* Initialize the descriptors for the RX channel */
      rxch = &(hdkif->rxch);
      rxch->active_head = (volatile struct emac_rx_bdp*)(curr_txbd + 1);
      
      rxch->free_head = NULL;
      rxch->freed_pbuf_len = 0;
      num_bd = ((SIZE_EMAC_CTRL_RAM >> 1) / sizeof(emac_rx_bdp) - 1);
      curr_bd = rxch->active_head;
      last_bd = curr_bd;
    
      /*
      ** Allocate the pbufs for the maximum count permitted or till the
      ** number of buffer desceriptors expire, which ever is earlier.
      */
      while(pbuf_cnt < MAX_RX_PBUF_ALLOC) {
        p = pbuf_alloc(PBUF_RAW, PBUF_LEN_MAX, PBUF_POOL);
        pbuf_cnt++;
        
        if(p != NULL) {
          /* write the descriptors if there are enough numbers to hold the pbuf*/
          if(((uint32)pbuf_clen(p)) <= num_bd) {
            for(q = p; q != NULL; q = q->next) {
              curr_bd->bufptr = hdkif_swizzle_data((uint32)(q->payload));
              curr_bd->bufoff_len = hdkif_swizzle_data(q->len);
              curr_bd->next = hdkif_swizzle_rxp(curr_bd + 1);
              curr_bd->flags_pktlen = hdkif_swizzle_data(EMAC_BUF_DESC_OWNER);
              
              /* Save the pbuf */
              curr_bd->pbuf = q;
              last_bd = curr_bd;
              curr_bd = hdkif_swizzle_rxp(curr_bd->next);
              num_bd--;
    
            }
          }
        
          /* free the allocated pbuf if no free descriptors are left */
       //else {
           pbuf_free(p);
      //  break;
        //  }
        }
        else {
          break;
        }
      }
    
      last_bd->next = NULL;
      rxch->active_tail = last_bd;
    
      /* Acknowledge receive and transmit interrupts for proper interrupt pulsing*/
      EMACCoreIntAck(hdkif->emac_base, EMAC_INT_CORE0_RX);
      EMACCoreIntAck(hdkif->emac_base, EMAC_INT_CORE0_TX);
      
      EMACRxUnicastSet(hdkif->emac_base, 0);
      EMACNumFreeBufSet(hdkif->emac_base, 0, 10);
      EMACTxEnable(hdkif->emac_base);
      EMACRxEnable(hdkif->emac_base);
    
      /* Write the RX HDP for channel 0 */
      EMACRxHdrDescPtrWrite(hdkif->emac_base, (uint32)rxch->active_head, 0);
     
      EMACMIIEnable(hdkif->emac_base); 
    
      
      /**
      * Enable the Transmission and reception, enable the interrupts for
      * channel 0 and for control core 0
      */
      EMACTxIntPulseEnable(hdkif->emac_base, hdkif->emac_ctrl_base, 0, 0);
      EMACRxIntPulseEnable(hdkif->emac_base, hdkif->emac_ctrl_base, 0, 0);
    
      return ERR_OK;
     

     谢谢。此致、

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    我不在初始化例程中讨论。

    但在处理完包之后、您应该释放 pbuf。

    请验证此示例 Lwip 代码以了解:

    e2e.ti.com/.../0677.Hercules_5F00_Ethernet_5F00_Bootloader.zip

    --

    谢谢。此致、
    Jagadish。