我正在使用atmel的lwip示例与PHY接口是可以的。它可以链接甚至自动协商。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。
升级版:
我检查了RSR,注意它是从0开始,然后在秒后转到2。2-表示捕获了新数据。
升级版:
所以我在我的芯片数据表中读到了emac的功能。我是对的。该RBQP寄存器必须指向描述符数组每个描述符由地址和状态字段组成。数据表声明“地址字段的零位写入一位,以显示缓冲区已被使用”。然后ARM使用该数组中的另一个rx描述符。我猜“已被使用”意味着缓冲区中充满了帧数据,可以随时进行处理。这一定意味着数据不会进入缓冲区。但它一定在那里,因为记录变高了。另外,我检查了RE-in NCR是否启动,MI是否启用。我不知道怎么了。

最佳答案

我花了整整一周的时间来解决这个问题。有趣的是,如果我转储了内存并查看了所有这些地址-数据一直都在那里!所以关键是禁用I和D缓存以及MMU本身。希望它能帮助别人。

07-26 04:20