AT91 ARM EMAC轮询问题

时间:2018-11-20 08:54:08

标签: c network-programming arm atmel lwip

我正在使用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。我不知道怎么了。

1 个答案:

答案 0 :(得分:0)

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