用于分配内存的 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 事务上。之后,当设备 运行 不再发生时。
有什么想法吗?
我找到了解决方案....
我必须在分配内存后刷新缓存,然后再将地址传递给第二个核心进行处理。
我正在使用带有 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 事务上。之后,当设备 运行 不再发生时。
有什么想法吗?
我找到了解决方案....
我必须在分配内存后刷新缓存,然后再将地址传递给第二个核心进行处理。