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_size of DMA Memory; Memory ,Do not will dma_memcpy_buf_size is 3MB with OOM。Default 1MB can;IfneedTests 2MB ,can Module dma_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

  • Loadinsmod dma-memcpy-dev.ko not ,UseDefault 1MB )。

  • DeviceNode/dev/dma_memcpy

  • Note: Use dma_memcpy_buf_size=3145728 (3MB), OOM;Ifneed 2M,can dma_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

  1. Data :1M/2M Copyand 。

  2. Valid Tests: before 4 Bytes 0x12345678 ,Copyafter Purpose before 4 Bytes 。

13.4. ioctl Interface

  • CommandsDMA_MEMCPY_IOC_TRANSFER

  • struct dma_memcpy_transfer { src, dst, len; status; } - src / dst :User /PurposeAddress - len :Copy (not Module dma_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 us

  • DMA 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 。