c - AT91 ARM EMAC 轮询问题

标签 c network-programming arm atmel lwip

我正在使用 atmel 的 lwip 示例。与 PHY 接口(interface)是可以的。它可以链接甚至自动协商。 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 以及这种情况的确切含义有非常模糊的介绍。但是我看不出 thise 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 描述符。我猜“已被使用”是指该缓冲区已填充帧数据并准备好进行处理。这一定意味着数据不会进入该缓冲区。但它必须存在,因为 REC 变高。此外,我检查过 NCR 中的 RE 已启动并且 MI 已启用。我不知道出了什么问题。

最佳答案

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

关于c - AT91 ARM EMAC 轮询问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53389330/

相关文章:

assembly - ARM 程序集加密扩展

c - float 数组上的 memset 未将数组完全清零

c++ - 线程参数的高效快速方法

c - 从 macOS 上的单个网络接口(interface)接收多播 UDP 数据包

java - 为什么我的应用程序在尝试建立 http 连接时不断崩溃?

c - mutex_unlock 是否起到内存栅栏的作用?

c - 是否可以在单个 C 文件中声明多个具有相同名称的静态变量?

c - 帮助结构(段错误)

c - 如何在 C 语言中更改来自 NIC 的传入数据包?

android - 如何从C源文件中调用arm汇编?