13. DMA Operation Guide¶
This documentDescriptionin CV184x on the platformThrough /dev/dma_memcpy Device DMA MemorytoMemoryCopyofConfiguration、Build、LoadandUser-Space Test 。
13.1. dev-to-memOperation Guide¶
Use DMA MemorytoMemoryCopy DeviceThe following conditions must be met first:
13.1.1. Kernel Requirements¶
Use of SDK BuildafterkernelImage,and under mem-to-memOperation Guide inStepsCompleteKernel ConfigurationandBuild,will DMA MemoryCopy Device isKernelModule(
dma-memcpy-dev.ko)。
13.1.2. DriverDescription¶
Driveris misc Device,Devicethe node is
/dev/dma_memcpy(LoadModuleafter misc System )。Driver
dma_memcpy_buf_sizeof DMA Memory; Memory ,Do not willdma_memcpy_buf_sizeis 3MB with OOM。Default 1MB can;IfneedTests 2MB ,can Moduledma_memcpy_buf_size=2097152。
13.2. mem-to-memOperation Guide¶
13.2.2. Build the kernel (including modules)¶
# on source + defconfig after
build_kernel
Module Kernel 。
Module linux_5.10/<out_dir>/drivers/misc/dma-memcpy-dev.ko ,orfrom build of modules InstallContentsCopy。
13.2.3. LoadandDeviceNode¶
Load:
insmod dma-memcpy-dev.ko( not ,UseDefault 1MB )。DeviceNode:
/dev/dma_memcpy。Note: Use
dma_memcpy_buf_size=3145728(3MB), OOM;Ifneed 2M,candma_memcpy_buf_size=2097152,Failure Default 1MB。
13.3. User-Space Test¶
13.3.1. Complete Test Code¶
ExampleProgram dma_memcpy_test.c CompleteSource Codeas follows:
1/*
2 * DMA mem-to-mem test: Data + Valid Tests
3 * 1) Data : 1M / 2M Copyand
4 * 2) Valid Tests: before 4 Bytes 0x12345678,Copyafter Purposebefore 4 Bytes
5 *
6 * Memory ,Please Default 1MB LoadModule, 3MB with OOM:
7 * insmod dma-memcpy-dev.ko
8 * 2M can : insmod dma-memcpy-dev.ko dma_memcpy_buf_size=2097152 ( can OOM)
9 */
10
11#include <stdio.h>
12#include <stdlib.h>
13#include <stdint.h>
14#include <string.h>
15#include <fcntl.h>
16#include <unistd.h>
17#include <sys/ioctl.h>
18#include <sys/time.h>
19#include <errno.h>
20
21#define DMA_MEMCPY_DEV_PATH "/dev/dma_memcpy"
22#define DMA_MEMCPY_IOC_MAGIC 'D'
23#define DMA_MEMCPY_IOC_TRANSFER _IOWR(DMA_MEMCPY_IOC_MAGIC, 1, struct dma_memcpy_transfer)
24
25/* andKernelDriver */
26struct dma_memcpy_transfer {
27 unsigned long long src;
28 unsigned long long dst;
29 unsigned long long len;
30 int status;
31};
32
33#define LEN_1M (1024 * 1024)
34#define LEN_2M (2 * 1024 * 1024)
35#define LEN_3M (3 * 1024 * 1024)
36#define VALIDITY_MAGIC 0x12345678
37
38static int do_one_copy(int fd, void *src, void *dst, size_t len)
39{
40 struct dma_memcpy_transfer xfer;
41 struct timeval tv0, tv1;
42 long us;
43
44 printf("Setup DMA memcpy: src=%p, dst=%p, len=%zu\n", src, dst, len);
45
46 xfer.src = (unsigned long long)(uintptr_t)src;
47 xfer.dst = (unsigned long long)(uintptr_t)dst;
48 xfer.len = (unsigned long long)len;
49 xfer.status = 0;
50
51 gettimeofday(&tv0, NULL);
52 if (ioctl(fd, DMA_MEMCPY_IOC_TRANSFER, &xfer) < 0) {
53 perror("ioctl");
54 return -1;
55 }
56 gettimeofday(&tv1, NULL);
57 us = (tv1.tv_sec - tv0.tv_sec) * 1000000 + (tv1.tv_usec - tv0.tv_usec);
58
59 if (xfer.status != 0) {
60 fprintf(stderr, "Transfer failed: status=%d (len > driver buf_size?)\n", xfer.status);
61 return -1;
62 }
63 printf("dma_memcpy cost time = %ld us\n", us);
64 return 0;
65}
66
67int main(int argc, char **argv)
68{
69 int fd;
70 void *src = NULL;
71 void *dst = NULL;
72 size_t max_len = LEN_3M; /* 3M, andRefer toTests */
73 int ret = 0;
74
75 (void)argc;
76 (void)argv;
77
78 fd = open(DMA_MEMCPY_DEV_PATH, O_RDWR);
79 if (fd < 0) {
80 perror("open " DMA_MEMCPY_DEV_PATH);
81 fprintf(stderr, "Please LoadModule: insmod dma_memcpy_dev.ko\n");
82 return 1;
83 }
84
85 src = malloc(max_len);
86 dst = malloc(max_len);
87 if (!src || !dst) {
88 perror("malloc");
89 ret = 1;
90 goto out;
91 }
92
93 /* ---- 1、Data ---- */
94 printf("1、Data :\n");
95
96 memset(src, 0x5a, max_len);
97 memset(dst, 0, max_len);
98
99 if (do_one_copy(fd, src, dst, LEN_1M) < 0) {
100 ret = 1;
101 goto out;
102 }
103 if (do_one_copy(fd, src, dst, LEN_2M) < 0) {
104 fprintf(stderr, "(If 2M Failure,can : insmod dma_memcpy_dev.ko dma_memcpy_buf_size=2097152)\n");
105 /* not , Valid Tests */
106 }
107
108 /* ---- 2、Valid Tests ---- */
109 printf("2、Valid Tests:\n");
110
111 memset(src, 0xff, max_len);
112 memset(dst, 0xff, max_len);
113 *(uint32_t *)src = (uint32_t)VALIDITY_MAGIC;
114
115 /* 3M, 1M */
116 if (do_one_copy(fd, src, dst, LEN_3M) < 0) {
117 if (do_one_copy(fd, src, dst, LEN_1M) < 0) {
118 ret = 1;
119 goto out;
120 }
121 }
122
123 if (*(uint32_t *)dst == (uint32_t)VALIDITY_MAGIC)
124 printf("Validity OK: dst[0..3] = 0x%08x (expected 0x%08x)\n",
125 *(uint32_t *)dst, VALIDITY_MAGIC);
126 else {
127 printf("Validity FAIL: dst[0..3] = 0x%08x (expected 0x%08x)\n",
128 *(uint32_t *)dst, VALIDITY_MAGIC);
129 ret = 1;
130 }
131
132out:
133 if (src) free(src);
134 if (dst) free(dst);
135 close(fd);
136 return ret;
137}
13.3.2. Build Description¶
in onUse cvitek Build 、 Generatecanin onRunof (No need to onof )。willon inofSource Code is dma_memcpy_test.c afterExecute:
arm-none-linux-uclibcgnueabihf-gcc -o dma_memcpy_test dma_memcpy_test.c -static
willGenerateof dma_memcpy_test to (If /mnt/sd/ )afterExecute:
./dma_memcpy_test
13.3.3. Test Content Description¶
dma_memcpy_test.c :
Data :1M/2M Copyand 。
Valid Tests: before 4 Bytes
0x12345678,Copyafter Purpose before 4 Bytes 。
13.4. ioctl Interface¶
Commands:
DMA_MEMCPY_IOC_TRANSFER:
struct dma_memcpy_transfer { src, dst, len; status; }-src/dst:User /PurposeAddress -len:Copy (not Moduledma_memcpy_buf_size) -status:Return 0 Success, is errno
DataPath:User src → Kernel → DMA Copy → Kernel → User dst。
13.5. How to Verify DMA mem-to-mem¶
13.5.1. View Kernel Logs¶
Driverin DMA Completeafter dma_memcpy cost time and DMA mem-to-mem done 。in on Execute:
dmesg -c
./dma_memcpy_test
dmesg | grep -i dma
If to under Output,Description of DMA mem-to-mem, src_dma/dst_dma is DMA BusAddress:
dma_memcpy cost time = xxxx usDMA mem-to-mem done: 1048576 bytes (src_dma=0x... dst_dma=0x...)
13.5.2. View CPU Usage¶
、 ofCopy, top CPU。DMA Copy CPU ;If Software memcpy,CPU 。