主题中讨论的其他器件:DP83848YB
您好!
我正在使用启用 RX 中断的 EMAC 模块 C0接收通道0。 当接收到一个中断时、它用一个信标向一个接收 RTOS 任务发出信号、然后 RX0中断被禁用。 接收任务会检查信号量、然后读取所有者位以开始处理数据包。 当它完成时、RX0中断已被重新启用。 一切正常、我打印出当前缓冲区描述符的地址和 RX 标头指针。 如果接收到多个数据包、所有数据包都被处理、则任务退出并启用中断。 但我肯定知道、有些口袋缺失了、甚至没有为它们生成中断。 在 Wireshark 中、我可以看到从计算机发送的数据包、但它不会出现在接收端。
是否有人在 EMAC 接口上遇到过类似的情况? 我是否仍然缺少可能导致此问题的东西?
我上传了我的部分代码、也许有人可以找出我缺少的内容。
谢谢!
#pragma INTERRUPT(emacRxInterrupt, IRQ) void emacRxInterrupt(void) { disableEmacInterrupts(); ///< According to Technical Reference Manual 32.2.17.3 Proper Interrupt Processing hdkif_t * const hdkif = &mHdkifData[0u]; // Disable RX0 interrupt EMACRxIntPulseDisable(hdkif->emac_base, hdkif->emac_ctrl_base, (uint32_t)EMAC_CHANNELNUMBER, (uint32_t)EMAC_CHANNELNUMBER); mEmacRxBdIntGenerated = (uint32_t)HWREG(hdkif->emac_base + EMAC_RXCP(EMAC_CHANNELNUMBER)); EMACCoreIntAck(hdkif->emac_base, EMAC_INT_CORE0_RX); ///< Acknowledge RX interrupt mEmacRxIntCounter++; semaphore_give(&mEmacRxSemaphore); enableEmacInterrupts(); } void rx_task(void) { while (1) { if (isOk(semaphore_take(&mEmacRxSemaphore, mEmacTaskRxBlockTime))) { LWIP_DEBUGF(NETIF_IN_DEBUG, ("EMACRX: Start! Semaphore Received! Int count: %d, Int BD: %x", mEmacRxIntCounter, mEmacRxBdIntGenerated)); while ((BYTE_SWAP(currentBufferDescriptor->flags_pktlen) & EMAC_BUF_DESC_OWNER) != EMAC_BUF_DESC_OWNER ) { LWIP_DEBUGF(NETIF_IN_DEBUG, ("EMACRX: SOP set! Current BD: %x", currentBufferDescriptor)); // Start processing the received packet only after SOP(Start Of Packet) received and we have the ownership if ((BYTE_SWAP(currentBufferDescriptor->flags_pktlen) & EMAC_BUF_DESC_SOP) == EMAC_BUF_DESC_SOP) { if ((BYTE_SWAP(currentBufferDescriptor->flags_pktlen) & EMAC_DSC_FLAG_ERROR_MASK) == 0) { // Check received packet size packetSize = BYTE_SWAP(currentBufferDescriptor->flags_pktlen) & 0xffffu; // Invalidate cache, to not to interfere with new packets in memory _dcacheInvalidateRange_(BYTE_SWAP(currentBufferDescriptor->bufptr), BYTE_SWAP(currentBufferDescriptor->bufptr) + packetSize); LWIP_DEBUGF(NETIF_IN_DEBUG, ("EMACRX: Packet arrived, BD: %x, RXHP: %x size: %d\r\n", currentBufferDescriptor, HWREG(hdkif->emac_base + EMAC_RXHDP(EMAC_CHANNELNUMBER)), packetSize)); if ((BYTE_SWAP(currentBufferDescriptor->flags_pktlen) & EMAC_BUF_DESC_EOP) != EMAC_BUF_DESC_EOP) { LWIP_DEBUGF(NETIF_DEBUG, ("EMACRX: NO EOP: %x, RXHP: %x\r\n", currentBufferDescriptor, HWREG(hdkif->emac_base + EMAC_RXHDP(EMAC_CHANNELNUMBER)))); } if (packetSize > 0u && packetSize <= ETH_MAX_FRAME_SIZE) { pbuf_t *p; p = pbuf_alloc(PBUF_RAW, packetSize, PBUF_POOL); ///< We allocate a pbuf chain of pbufs from the pool. LWIP_DEBUGF(NETIF_IN_DEBUG, ("EMACRX: Packet processing!")); if (NN(p)) { memcpy(p->payload, (void *)(BYTE_SWAP(currentBufferDescriptor->bufptr)), packetSize); eth_hdr_t *ethhdr; ethhdr = p->payload; switch (htons(ethhdr->type)) { // IP or ARP packet? case ETHTYPE_ARP: case ETHTYPE_IP: // full packet send to tcpip_thread to process if (mLwipRuntimeData.netif.input(p, &mLwipRuntimeData.netif) != ERR_OK) { LWIP_DEBUGF(NETIF_DEBUG, ("ifx_netif_input: IP input error\n")); pbuf_free(p); p = NULL; } break; default: LWIP_DEBUGF(NETIF_DEBUG, ("ifx_netif_input: type unknown\n")); pbuf_free(p); p = NULL; break; } } else { LWIP_DEBUGF(NETIF_DEBUG, ("EMACRX: pbuf allocation error\n")); } } else { LWIP_DEBUGF(NETIF_IN_DEBUG, ("Too large: %d\n", packetSize)); } mEmacRxBdAcknowledged = (uint32_t)currentBufferDescriptor; HWREG(hdkif->emac_base + EMAC_RXCP(EMAC_CHANNELNUMBER)) = (uint32_t)currentBufferDescriptor; ///< To acknowledge BD LWIP_DEBUGF(NETIF_IN_DEBUG, ("EMACRX: Acknowledged BD[1]: %x", mEmacRxBdAcknowledged)); volatile emac_rx_bd_t *currentBufferDesListStart = currentBufferDescriptor; while((BYTE_SWAP(currentBufferDescriptor->flags_pktlen) & EMAC_BUF_DESC_EOP) != EMAC_BUF_DESC_EOP) { currentBufferDescriptor->bufoff_len = BYTE_SWAP(ETH_MAX_FRAME_SIZE); currentBufferDescriptor->flags_pktlen = BYTE_SWAP(EMAC_BUF_DESC_OWNER); currentBufferDescriptor = (emac_rx_bd_t *)BYTE_SWAP((uint32_t)currentBufferDescriptor->next); mEmacRxBdAcknowledged = (uint32_t)currentBufferDescriptor; HWREG(hdkif->emac_base + EMAC_RXCP(EMAC_CHANNELNUMBER)) = (uint32_t)currentBufferDescriptor; ///< To acknowledge BD LWIP_DEBUGF(NETIF_IN_DEBUG, ("EMACRX: Acknowledged BD[2]: %x", mEmacRxBdAcknowledged)); } // free up the current BD currentBufferDescriptor->bufoff_len = BYTE_SWAP(ETH_MAX_FRAME_SIZE); currentBufferDescriptor->flags_pktlen = BYTE_SWAP(EMAC_BUF_DESC_OWNER); volatile emac_rx_bd_t *currentBufferDescTemp = (emac_rx_bd_t *)BYTE_SWAP((uint32_t)currentBufferDescriptor->next); currentBufferDescriptor->next = NULL; // update the linked list tailBufferDescriptor->next = (emac_rx_bd_t *)BYTE_SWAP((uint32_t)currentBufferDesListStart); // Check if we are at the end of queue if ((BYTE_SWAP(tailBufferDescriptor->flags_pktlen) & EMAC_BUF_DESC_EOQ) == EMAC_BUF_DESC_EOQ) { while (HWREG(hdkif->emac_base + EMAC_RXHDP(EMAC_CHANNELNUMBER)) != 0u) { task_sleep((sysTimeDuration_t)DURATION_MS(1)); } // Restart EMAC reception with updating the head pointer HWREG(hdkif->emac_base + EMAC_RXHDP(EMAC_CHANNELNUMBER)) = (uint32_t)currentBufferDescriptor; LWIP_DEBUGF(NETIF_IN_DEBUG, ("EMACRX: RX restarted at BD: %x\r\n", currentBufferDescriptor)); } tailBufferDescriptor = currentBufferDescriptor; currentBufferDescriptor = currentBufferDescTemp; LWIP_DEBUGF(NETIF_IN_DEBUG, ("EMACRX: End of packet!")); } else { LWIP_DEBUGF(NETIF_IN_DEBUG, ("EMACRX: Packet error!")); } } else { LWIP_DEBUGF(NETIF_IN_DEBUG, ("EMACRX: BD no SOP found!")); break; } } // Re-enable RX0 interrupt EMACRxIntPulseEnable(hdkif->emac_base, hdkif->emac_ctrl_base, (uint32_t)EMAC_CHANNELNUMBER, (uint32_t)EMAC_CHANNELNUMBER); LWIP_DEBUGF(NETIF_IN_DEBUG, ("EMACRX: End!")); } else { // We didn't receive semaphore inside the given blocking time, but the head pointer is on the next location -> IRQ lost if (HWREG(hdkif->emac_base + EMAC_RXHDP(EMAC_CHANNELNUMBER)) == 0u) { // Restart EMAC reception with updating the head pointer HWREG(hdkif->emac_base + EMAC_RXHDP(EMAC_CHANNELNUMBER)) = (uint32_t)currentBufferDescriptor; LWIP_DEBUGF(NETIF_DEBUG, ("EMACRX: IRQ lost RX restarted at BD: %x\r\n", currentBufferDescriptor)); } } } }