用于分配内存的 DMA 写入在第一次写入时丢失了前两个地址

DMA writing to allocated memory misses the first two adresses on the first write

我正在使用带有 FPGA 的 ZYNQ7(双核 ARM)。 FPGA 设计有一个 32 位计数器,通过 DMA 控制器以 256 个数据包的形式访问 DDR。

在处理器 1 的 C 代码中,我 运行 一个 LWIP 应用程序通过以太网连接到我的电脑。 我在那里为 DMA 事务分配 ram 内存。指针的地址通过共享内存传递给第二个核心。

#define RCVADDR 0x1ef00002
u32_t * send=NULL;
u32_t* addr = (uint32_t*)RCVADDR;

//Allocating the memory once initially
if(send==NULL){
        send=malloc(256*sizeof(uint32_t));
    }

    *addr = (uint32_t)send;
    //starting the DMA on Core 2
    *getdma=1;

我使用握手初始化第二个内核中的 DMA 事务,并在完成事务后使用第一个内核上的 TCP 连接将数据发送到 PC。

#define GetDMA  0x1ef00001
#define DONEDMA 0x1ef00003

uint8_t* getdma = (uint8_t*)GetDMA;
uint32_t* addr=(uint32_t*)RCVADDR;

    while(1){
        if(*getdma == 1){
            StartDMATransfer(*addr, 2048);  // The Number 2048 is the number Of Transfered Packets. It has to be at least the amount of Packets my Counter transfers in chunks. The design has a packet end indicator on its own. So 256 or bigger works the same as 256
            *getdma =0;

            Xil_DCacheFlush();

        }
    }

在建立 TCP 连接之前,我刷新了 DCache

void send_data(){
    int ip_addr[4];
        u8_t i=0;

        char * token = strtok(ip,".");
        ip_addr[0] = atoi(token);

        while(token != NULL){

            ip_addr[++i]=atoi(strtok(NULL,"."));
        }
        Xil_DCacheFlushRange(send, 256*sizeof(uint32_t));

        //sleep(0.5);
        connect(ip_addr,atoi(port));
}

问题:对设备编程后的第一个传输周期显示:

[1280, 1281, 2, 3, 4, 5, 6,..... ....., 248, 249,1530, 1531, 1532, 1533, 1534, 1535]

前 2 个值和后 6 个值来自对设备重新编程之前的前一个循环。 但是,这只发生在第一个 DMA 事务上。之后,当设备 运行 不再发生时。

有什么想法吗?

我找到了解决方案....

我必须在分配内存后刷新缓存,然后再将地址传递给第二个核心进行处理。