我正在使用atmel的lwip示例。与PHY的接口可以。它可以链接甚至自动协商。 Netif上升了。但是当我开始轮询netif时,什么也没有发生。香港专业教育学院将问题缩小为EMAC_Poll
unsigned char EMAC_Poll(unsigned char *pFrame, unsigned int frameSize, unsigned int *pRcvSize)
{
unsigned short bufferLength;
unsigned int tmpFrameSize=0;
unsigned char *pTmpFrame=0;
unsigned int tmpIdx = rxTd.idx;
volatile EmacRxTDescriptor *pRxTd = rxTd.td + rxTd.idx;
ASSERT(pFrame, "F: EMAC_Poll\n\r");
char isFrame = 0;
// Set the default return value
*pRcvSize = 0;
// Process received RxTd
while ((pRxTd->addr & EMAC_RX_OWNERSHIP_BIT) == EMAC_RX_OWNERSHIP_BIT) {
// Never got there.
...
}
return EMAC_RX_NO_DATA;
}
typedef struct {
volatile EmacRxTDescriptor td[RX_BUFFERS];
EMAC_RxCallback rxCb; /// Callback function to be invoked once a frame has been received
unsigned short idx;
} RxTd;
/// Describes the type and attribute of Receive Transfer descriptor.
typedef struct _EmacRxTDescriptor {
unsigned int addr;
unsigned int status;
} __attribute__((packed, aligned(8))) EmacRxTDescriptor, *PEmacRxTDescriptor;
有while循环,但条件永远不会成立。
我的演讲非常模糊,什么是RxTd,以及这种情况的确切含义。但是我看不到RxTd将如何更改为通过条件。 RxTd的所有引用都指向相同的emac.c模块。它们中的大多数都在该轮询功能中,而其余部分则在EMAC_ResetRx
函数中。
static void EMAC_ResetRx(void)
{
unsigned int Index;
unsigned int Address;
// Disable RX
AT91C_BASE_EMAC->EMAC_NCR &= ~AT91C_EMAC_RE;
// Setup the RX descriptors.
rxTd.idx = 0;
for(Index = 0; Index < RX_BUFFERS; Index++) {
Address = (unsigned int)(&(pRxBuffer[Index * EMAC_RX_UNITSIZE]));
// Remove EMAC_RX_OWNERSHIP_BIT and EMAC_RX_WRAP_BIT
rxTd.td[Index].addr = Address & EMAC_ADDRESS_MASK;
rxTd.td[Index].status = 0;
}
rxTd.td[RX_BUFFERS - 1].addr |= EMAC_RX_WRAP_BIT;
// Receive Buffer Queue Pointer Register
AT91C_BASE_EMAC->EMAC_RBQP = (unsigned int) (rxTd.td);
}
我不太了解最后一行,但看起来rxTd自动填充了AT91本身。如果是这样,则可能存在打包/对齐问题,但是Atmel在RxTd结构定义上添加了__attribute__ ((packed, aligned(8)))
。可以通过任何方式描述数据输入机制或告诉我问题可能在哪里吗?
顺便说一句,我正在使用gcc,如果那很重要的话。
UPD :
我已经检查了RSR,注意到它从0开始,然后在第二秒后变为2。 2-表示已捕获新数据。
UPD :
所以我已经在芯片的数据表中了解了emac的功能。我是对的。该RBQP寄存器必须指向描述符数组。每个描述符由地址和状态字段组成。数据表指出“地址字段的位零被写入1以表明已使用该缓冲区”。然后,ARM使用该数组中的另一个rx描述符。我猜“已经被使用”是指该缓冲区充满了帧数据并准备进行处理。这必须意味着数据不会进入该缓冲区。但是它必须在那里,因为REC变高。另外,我检查了NCR中的RE是否已启动并启用了MI。我不知道怎么了。
答案 0 :(得分:0)
我花了整整一周的时间来解决它。有趣的是,如果我转储了内存并查看了所有这些地址,则数据一直存在!因此,关键是禁用I和D缓存以及MMU本身。希望它能对某人有所帮助。