I might have some misconceptions here, so bear with me.
I wrote a program that captures images from a camera. I am sharing the memory between the camera and my application with mmap
as I found in the V4L2 documentation. This works great. Now my processor (it's TI's DM3730) also has a DSP. I want to use the DSP, but it requires physical contiguous memory. TI provides drivers to allocate the memory. My problem is that right now I lose a lot of time to copy the mmap'ed memory into the physical contiguous memory. Is there a way to tell mmap that it should not allocate memory itself, but that I tell mmap to use memory that I allocate.
To give you an idea of what I am doing (There is a lot of code missing of course, but I stuck very close to the V4L2 documentation. I hope this is enough to understand my problem):
//reserve physical contiguous memory
dsp_buffer = Memory_alloc(buffer_length, &myParams);
...
//reserve memory for buffer, but not contiguous
buffers[n_buffers].start =
mmap (NULL , /* start anywhere */
buf.length,
PROT_READ | PROT_WRITE , /* required */
MAP_SHARED , /* recommended */
fd, buf.m.offset);
After that I copy the memory out of the non-contiguous memory into the contiguous memory, whenever a frame is ready.
...
//wait until frame is ready in memory
r = select (fd + 1, &fds, NULL, NULL, &tv);
...
//copy the memory over to the physically contiguous memory
memcpy(dsp_buffer,buffers[buf.index].start,size);
...
How could I get the frames into the physical contiguous memory right away?
The mmap() function uses the standard Linux kernel call dma_alloc_coherent() to request physically-contiguous memory regions for sharing with a device. In the default Linux kernel, dma_alloc_coherent() does not allocate physically-contiguous memory more than 0.5 megabytes (MB) in size.
In computing, mmap(2) is a POSIX-compliant Unix system call that maps files or devices into memory. It is a method of memory-mapped file I/O. It implements demand paging because file contents are not immediately read from disk and initially use no physical RAM at all.
On a 32-bit system, kmalloc() returns the kernel logical address (its a virtual address though) which has the direct mapping (actually with constant offset) to physical address. This direct mapping ensures that we get a contiguous physical chunk of RAM.
The kmalloc() function returns physically and therefore virtually contiguous memory. This is a contrast to user space's malloc() function, which returns virtually but not necessarily physically contiguous memory.
If you cannot pass the result of Memory_alloc()
as first argument to your mmap()
(for example, if it also uses mmap() that would make it impossible to map to that memory again), you probably should use another streaming I/O method from the given example - IO_METHOD_USERPTR
variation. It uses the same ioctl
as IO_METHOD_MMAP to capture frames and should provide the similar efficiency.
You would need driver support from the camera driver. mmap
gets the physical pages it maps from whatever driver it's mapping - the camera in this case. You cannot tell mmap to use some pre-allocated pages, because the underlying driver would have to be told to use these pre-allocated pages.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With