Skip to content

Instantly share code, notes, and snippets.

@ikwzm
Created April 10, 2020 12:56
Show Gist options
  • Save ikwzm/c42bc209f5df1c4076d35c59de36bf1b to your computer and use it in GitHub Desktop.
Save ikwzm/c42bc209f5df1c4076d35c59de36bf1b to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
#include <time.h>
#include <unistd.h>
#include <fcntl.h>
#include <error.h>
#include <errno.h>
#include <sys/mman.h>
int MemoryWrite(off_t offset, size_t size, void *data)
{
const int N_RETRY = 100;
const int TIMECYCLE = 1000;
size_t mem_size = size;
int cntTimeout;
int fd;
void *ptr;
int i, err;
int elapsedMs=0;
struct timespec start;
struct timespec stop;
double speed;
{
clock_gettime(CLOCK_REALTIME, &start);
// open udmabuf device
fd = open("/dev/udmabuf0", O_RDWR);
//i = pwrite(fd, data, size, offset);
err =errno;
if (fd < 1) {
fprintf(stderr,"Invalid udmabuf device file\n");
exit(1);
}
// mmap the udmabuf device
ptr = mmap(NULL, mem_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
if(ptr == MAP_FAILED) {
fprintf (stderr, "Cannot map udmabuf device.\n");
fprintf(stderr, "0x%08X, %d\n",errno, errno);
}
clock_gettime(CLOCK_REALTIME, &stop);
elapsedMs = (int)((stop.tv_sec - start.tv_sec) * 1e3 + (stop.tv_nsec - start.tv_nsec) / 1e6);
printf ("%d ms to map the udmabuf device\n", elapsedMs);
}
{
clock_gettime(CLOCK_REALTIME, &start);
// move to the requested offset
ptr = ptr + offset;
memcpy(ptr,data,size);
clock_gettime(CLOCK_REALTIME, &stop);
elapsedMs = (int)((stop.tv_sec - start.tv_sec) * 1e3 + (stop.tv_nsec - start.tv_nsec) / 1e6); // in milliseconds
printf ("%d ms to write %zu bytes\n", elapsedMs, size);
if (elapsedMs > 0) {
speed = ((size/elapsedMs)/1000);
printf ("%0.2f MBytes/s\n", speed);
}
}
{
int sync_for_device_file;
int sync_direction = 2;
char attr[1024];
int attrlen;
ssize_t written;
clock_gettime(CLOCK_REALTIME, &start);
sync_for_device_file = open("/sys/class/udmabuf/udmabuf0/sync_for_device", O_RDWR);
if (sync_for_device_file < 0) {
fprintf(stderr,"Invalid udmabuf sync_for_device file\n");
exit(1);
}
attrlen = sprintf(attr, "1");
written = write(sync_for_device_file, attr, attrlen);
close(sync_for_device_file);
clock_gettime(CLOCK_REALTIME, &stop);
elapsedMs = (int)((stop.tv_sec - start.tv_sec) * 1e3 + (stop.tv_nsec - start.tv_nsec) / 1e6);
printf("%d ms to sync %zu bytes\n", elapsedMs, size);
if (elapsedMs > 0) {
speed = ((size/elapsedMs)/1000);
printf ("%0.2f MBytes/s\n", speed);
}
}
{
clock_gettime(CLOCK_REALTIME, &start);
// move back and unmap
ptr = ptr - offset;
(void)munmap(ptr, mem_size);
close(fd);
clock_gettime(CLOCK_REALTIME, &stop);
elapsedMs = (int)((stop.tv_sec - start.tv_sec) * 1e3 + (stop.tv_nsec - start.tv_nsec) / 1e6); // in milliseconds
printf ("%d ms to unmap the udmabuf device\n", elapsedMs);
}
return 0;
}
void main()
{
const size_t size = 42336000;
void* data;
data = malloc(size);
if (NULL == data) {
fprintf(stderr,"Can not malloc(%zu)\n", size);
exit(1);
}
memset(data, 0, size);
MemoryWrite(0, 42336000, data);
free(data);
}
root@debian-fpga:/home/fpga/examples/udmabuf_test# insmod /lib/modules/4.19.57-armv7-fpga/ikwzm/udmabuf.ko udmabuf0=42336000
[ 2295.399377] udmabuf udmabuf.0: DMA mask not set
[ 2295.522079] udmabuf udmabuf0: driver version = 1.4.6
[ 2295.527075] udmabuf udmabuf0: major number = 242
[ 2295.531860] udmabuf udmabuf0: minor number = 0
[ 2295.536517] udmabuf udmabuf0: phys address = 0x30100000
[ 2295.541913] udmabuf udmabuf0: buffer size = 42336256
[ 2295.547183] udmabuf udmabuf0: dma device = udmabuf.0
[ 2295.552493] udmabuf udmabuf0: dma coherent = 0
[ 2295.557156] udmabuf udmabuf.0: driver installed.
root@debian-fpga:/home/fpga/examples/udmabuf_test# ./test
0 ms to map the udmabuf device
154 ms to write 42336000 bytes
274.00 MBytes/s
86 ms to sync 42336000 bytes
492.00 MBytes/s
1 ms to unmap the udmabuf device
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment