#include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <ddr_init.h> #define CRU_REG_BASEADDR 0x30004079000ULL #define DDR_BASEADDR 0x00080000000ULL #define DDRWR(va, data) (*(int64_t *) ((va) + DDR_BASEADDR) = data) #define DDRRD(va) (*(int64_t *) ((va) + DDR_BASEADDR)) void test_ddr_wr() { for (register int64_t i = 3; i < 29; i ++) { register int64_t ii = (1ULL << i); DDRWR(ii, ii); } asm volatile ("x.dci 0; x.sync;"); for (register int64_t i = 3; i < 29; i ++) { int64_t ii = (1ULL << i) + 0x80000000ULL; asm volatile ("x.dcbf x0, %0, 0;" : : "r" (ii)); } } void test_ddr_rd(){ for (register int64_t i = 3; i < 29; i ++) { int64_t ii = (1ULL << i) + 0x80000000ULL; asm volatile ("x.dcbf x0, %0, 0;" : : "r" (ii)); } for (register int64_t i = 3; i < 29; i ++) { register int64_t ii = (1ULL << i); int64_t rdata = DDRRD(ii); if (rdata != ii) { printf("Error: vaddr(0x%llx), raddr(0x%llx), got(0x%llx), exp(0x%llx)\n", ii+0x80000000ULL, ii, rdata, ii); exit(1); } } }解釋一下
时间: 2024-04-11 20:31:55 浏览: 219
这段代码是一个用于测试DDR内存读写的函数。它通过使用特定的虚拟地址访问DDR内存进行写操作,然后再读回数据进行验证。
首先,它定义了一些常量和宏:
- `CRU_REG_BASEADDR`表示CRU寄存器的基地址。
- `DDR_BASEADDR`表示DDR内存的基地址。
- `DDRWR(va, data)`是一个宏,用于将数据`data`写入到虚拟地址`va`对应的DDR内存中。
- `DDRRD(va)`是一个宏,用于从虚拟地址`va`对应的DDR内存中读取数据。
然后,它实现了两个函数:
1. `test_ddr_wr()`函数用于测试DDR内存的写操作。它通过循环,将指定的数据写入到不同的虚拟地址对应的DDR内存中。
2. `test_ddr_rd()`函数用于测试DDR内存的读操作。首先,它通过循环将一些特定的虚拟地址进行清除缓存操作。然后,它再次通过循环,从不同的虚拟地址对应的DDR内存中读取数据,并与预期值进行比较。如果读取的数据与预期值不一致,则输出错误信息并退出程序。
这段代码主要用于测试DDR内存的读写功能和正确性,以确保DDR内存的正常工作。
相关问题
DMA读取DDR的数据并将数据写入全局变量的数组中的代码示例以及DMA控制器的配置
以下是一个示例代码,用于使用DMA从DDR中读取数据并将数据写入全局变量的数组中:
```c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#define DDR_BASE_ADDR 0x80000000
#define DDR_DATA_SIZE 8192
// 全局变量数组
uint32_t global_data[DDR_DATA_SIZE];
// DMA控制器配置结构体
struct dma_config {
uint32_t src_addr; // 外设读取数据的起始地址
uint32_t dst_addr; // 内存写入数据的起始地址
uint32_t data_len; // 数据传输长度
uint32_t direction; // 数据传输方向,0表示外设到内存,1表示内存到外设
};
// DMA初始化函数
int dma_init(void)
{
int fd = open("/dev/dma", O_RDWR);
if (fd < 0) {
perror("open /dev/dma failed");
return -1;
}
return fd;
}
// DMA传输函数
int dma_transfer(int fd, struct dma_config config)
{
int ret = ioctl(fd, 0, &config);
if (ret < 0) {
perror("ioctl failed");
return -1;
}
return 0;
}
int main(void)
{
int fd = dma_init();
if (fd < 0) {
exit(1);
}
// DMA控制器配置
struct dma_config config = {
.src_addr = DDR_BASE_ADDR,
.dst_addr = (uint32_t)global_data,
.data_len = DDR_DATA_SIZE * sizeof(uint32_t),
.direction = 0,
};
// 启动DMA传输
dma_transfer(fd, config);
// 关闭DMA
close(fd);
return 0;
}
```
在上面的示例代码中,首先定义了一个全局变量数组 `global_data`,用于存储从DDR中读取的数据。然后定义了一个 DMA 控制器配置结构体 `dma_config`,用于配置 DMA 控制器的参数,包括外设读取数据的起始地址、内存写入数据的起始地址、数据传输长度和数据传输方向。接着,在 `main` 函数中,调用 `dma_init` 函数初始化 DMA 控制器,并将配置结构体 `dma_config` 传递给 `dma_transfer` 函数启动 DMA 传输。最后,关闭 DMA 控制器并退出程序。
需要注意的是,上面的示例代码仅供参考,具体的实现需要根据不同的应用场景进行调整和优化。DMA 控制器的配置参数也需要根据实际情况进行调整。
阅读全文
相关推荐









