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.
你好
我将 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。