This repository has been archived on 2026-08-21. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
ciciec2026/sdk/software/examples/dma/main.c
FallenSigh e35fa5884d Use uncached ExtRAM access (0xBC400000) to bypass CPU data cache
The open-la500 core has USE_CACHE enabled. Writes to 0x1c400000
go to the write-back data cache and never reach the SRAM model
before the testbench checks ExtRAM. Use the 0xA0000000 uncached
segment (same pattern as fft_dma/main.c).
2026-06-24 02:04:40 +08:00

71 lines
2.3 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdbool.h>
#include <stdint.h>
#include <common_func.h>
#include <confreg_time.h>
#include <dma.h>
// BSP板级支持包所需全局变量
unsigned long UART_BASE = 0xbf000000;
unsigned long CONFREG_TIMER_BASE = 0xbf20f100;
unsigned long CONFREG_CLOCKS_PER_SEC = 50000000L;
unsigned long CORE_CLOCKS_PER_SEC = 33000000L;
// 加上 aligned(64) 是为了防止 DMA 突发传输时跨越缓存行或 AXI 非对齐边界
uint32_t src_array[64] __attribute__((aligned(64)));
uint32_t dst_array[64] __attribute__((aligned(64)));
int main(int argc, char** argv)
{
uint32_t data_len = 64;
uint32_t byte_len = data_len * 4;
// 虚拟地址转物理地址与无缓存地址
// 屏蔽掉高 3 位(& 0x1FFFFFFF)即可获得真实的物理地址
uint32_t phys_src_addr = ((uint32_t)src_array) & 0x1FFFFFFF;
uint32_t phys_dst_addr = ((uint32_t)dst_array) & 0x1FFFFFFF;
// 或上 0xA0000000 即可获得绕过 Cache 的无缓存(Uncached)指针
volatile uint32_t *uncached_src = (volatile uint32_t *)(phys_src_addr | 0xA0000000);
volatile uint32_t *uncached_dst = (volatile uint32_t *)(phys_dst_addr | 0xA0000000);
// CPU 必须通过无缓存指针写入
for (int i = 0; i < data_len; i++) {
uncached_src[i] = i * i; // 填入 0~63
uncached_dst[i] = 0xDEADBEEF; // 目的数组填入垃圾值,方便验证是否真的被覆盖
}
printf("src_array: %x\n", src_array);
printf("dst_array: %x\n", dst_array);
printf("phys_src_array: %x\n", phys_src_addr);
printf("phys_dst_array: %x\n", phys_dst_addr);
printf("uncached_src: %x\n", uncached_src);
printf("uncached_dst: %x\n", uncached_dst);
// 配置 DMA:DMA 只需要最纯粹的物理地址
dma_start_transfer(0, phys_src_addr, phys_dst_addr, byte_len);
dma_wait_polling(0);
printf("dma passed!\n");
// 校验数据:CPU 必须通过无缓存指针读取
int err = 0;
for (int i = 0; i < data_len; i++) {
uint32_t val = uncached_dst[i];
printf("%d: %d\n", i, val);
if (val != i * i) {
err++;
}
}
if (err == 0) {
printf("\nSuccess! Array to Array DMA transfer verified.\n");
} else {
printf("\nFailed! Found %d errors.\n", err);
}
return 0;
}