主题中讨论的其他器件: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));
}
}
}
}

