UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Adventurer
Adventurer
12,337 Views
Registered: ‎01-10-2014

VDMA frame buffer in Linux application

Hello everyone!

 

There's a couple of questions about VDMA.

 

In my project, I'm using VDMA IP configured as a frame buffer. In standalone applications I have no problems allocating a part of memory for it and this part of memory never overlaps the part of memory my application uses. In Linux application I find a virtual base address of VDMA using /dev/mem and the mmap function.

 

But how do I tell the operational system not to use the part of physical memory belonging to frame buffer?

 

Or how do I allocate memory for frame buffer in physical memory?

 

I've examined XAPP794 reference design, and in this design the range 0x00x4000000 is allocated for DDR. This range is also written in .dts file. But in Linux application the start address of the first frame of the frame buffer is 0x3000000. So how does this work? How Linux knows that it cannot use memory with addresses higher than 0x3000000?

 

Thank you very mush in advance.

0 Kudos
8 Replies
Xilinx Employee
Xilinx Employee
12,333 Views
Registered: ‎08-02-2011

Re: VDMA frame buffer in Linux application

You can use the memmap kernel argument

 

https://www.kernel.org/doc/Documentation/kernel-parameters.txt

 


	memmap=nn[KMG]$ss[KMG]
			[KNL,ACPI] Mark specific memory as reserved.
			Region of memory to be reserved is from ss to ss+nn.
			Example: Exclude memory from 0x18690000-0x1869ffff
			         memmap=64K$0x18690000
			         or
			         memmap=0x10000$0x18690000
www.xilinx.com
0 Kudos
Scholar milosoftware
Scholar
12,299 Views
Registered: ‎10-26-2012

Re: VDMA frame buffer in Linux application

You can also write a driver that uses "dma_alloc_coherent" to dynamically allocate the framebuffer. This will yield a physical and virtual address Then supply the physical address to the VDMA driver via its config, and use the standard memory framebuffer driver (simple_fb or so) to use the framebuffer as a regular framebuffer device. The ADI reference driver for the HDMI chip on the zedboard and zc702 boards uses this technique. It's much more convenient than just throwing away a block of RAM, and allows you to allocate memory on demand, depending on the resolution requested.
0 Kudos
Adventurer
Adventurer
12,278 Views
Registered: ‎01-10-2014

Re: VDMA frame buffer in Linux application

I wouldn't like to use kernel space drivers and I have no necessity of allocating mamory for frame buffer dynamically. I'd like to tune VDMA just like it is done in XAPP794 reference design. In this design it is tuned through direct writing to registers:

 

#define VDMA_VITA_MEM_BASE_ADDR 0x30000000
int fd;
Xuint32 map_CoreAddress;
fd = open("/dev/mem", O_RDWR);
map_CoreAddress = (Xuint32)mmap(NULL, VIDEO_MMAP_SIZE,
PROT_READ | PROT_WRITE, MAP_SHARED, fd, (off_t)XPAR_AXI_VDMA_1_BASEADDR );
uBaseAddr = map_CoreAddress;
...
frameAddress1 = VDMA_VITA_MEM_BASE_ADDR + (frame_size * 0);
frameAddress2 = VDMA_VITA_MEM_BASE_ADDR + (frame_size * 1);
frameAddress3 = VDMA_VITA_MEM_BASE_ADDR + (frame_size * 2);
...
*((volatile int *)(uBaseAddr+XAXIVDMA_S2MM_ADDR_OFFSET+XAXIVDMA_START_ADDR_OFFSET+0)) = frameAddress1; //0x30000000; // DDR starting address of frame buffer-0
*((volatile int *)(uBaseAddr+XAXIVDMA_S2MM_ADDR_OFFSET+XAXIVDMA_START_ADDR_OFFSET+4)) = frameAddress2; //0x30870000; // DDR starting address of frame buffer-1
*((volatile int *)(uBaseAddr+XAXIVDMA_S2MM_ADDR_OFFSET+XAXIVDMA_START_ADDR_OFFSET+8)) = frameAddress3; //0x310E0000; // DDR starting address of frame buffer-2
так же в этом референс дизайне есть функция котороя позволяет инециалезировать фрэйм буфер картинкой bmp:
physicalAddress = VDMA_VITA_MEM_BASE_ADDR;
physicalSize = 3*0x870000*sizeof(unsigned int);

// Map physical frame buffer address to virtual space
fd_mmap = open("/dev/mem", O_RDWR);
virtualAddress = (Xuint32)mmap(NULL, physicalSize,
PROT_READ | PROT_WRITE, MAP_SHARED, fd_mmap, (off_t)physicalAddress );
for ( frameIdx = 0; frameIdx < 3; frameIdx++ )
{
frameAddress = virtualAddress + frameIdx*0x870000;

// Open BMP file
fd_bmp = open(cargv[1], O_RDONLY);
...
write image
...
close( fd_bmp );

} // for ( frameIdx = 0; frameIdx < 3; frameIdx++ )

// Unmap frame buffer address
munmap((void *)virtualAddress,physicalSize);
close(fd_mmap);

 

Also I want to have an opportunity to write a picture to frame buffer. I think using memmap will not allow to do this. Besides, memmap is not used in XAPP794.

I do not understand neither how access to frame buffer memory is restricted in XAPP794 nor do I have to do this at all.

How do I restrict the access so that I have an opportunity of writing a picture to frame buffer?

 

0 Kudos
Explorer
Explorer
12,266 Views
Registered: ‎10-29-2007

Re: VDMA frame buffer in Linux application

you might find this interesting

http://www.wiki.xilinx.com/Linux+User+Mode+Pseudo+Driver

 

I can't get it to compile. Be curious if you get what you're trying to do to work. I also tried the memmap suggestion above and that didn't work.

0 Kudos
Scholar milosoftware
Scholar
12,251 Views
Registered: ‎10-26-2012

Re: VDMA frame buffer in Linux application

Well, I gave you the correct answer to your questions. Any skilled C programmer should be able to combine that into a working driver in a few days. An experienced kernel programmer should be able to do it in less than a day.

 

Since you'd rather hack around, okay, here's the dirty way to do it:

 

- Change the devicetree of your kernel and alter the "memory" parameter, so that your memory range is no longer part of the normal RAM.

- Add the SIMPLEFB driver to your kernel through the menuconfig. Add the memory address, range, width height and stride parameters of your framebuffer to the configuration setting in the devicetree.

- Install this on your system, and you should now have a working /dev/fb0 that can be mmapped like any framebuffer.

 

(You can also contact my company topic.nl, we've built drivers for other customers too.)

0 Kudos
Explorer
Explorer
12,245 Views
Registered: ‎10-29-2007

Re: VDMA frame buffer in Linux application

I agree that is the correct answer. My major challenge is that is for one core. The problem I'm running into, particulary for designs with a long image processing pipeline, how do I reuse the existing SDK libsrc IP that Xilinx provides for controlling their cores from software? That is, if I have a axi scaler before the frame buffer how do I control it?

 

Do I need to write a driver for each PL core even though they'll often have no direct interaction with Linux besides configuration?

 

0 Kudos
Scholar milosoftware
Scholar
12,234 Views
Registered: ‎10-26-2012

Re: VDMA frame buffer in Linux application

For a configuration only interface there's a generic Linux UIO driver that you can use to interface with memory mapping and even simple user-space IRQ handling. This takes the hardware addressing and conversion away from your application and places it into the devicetree configuration.

 

For standard devices like a framebuffer, applications expect it to have a certain interface (i.e. a memory mappable /dev/fb0 node). You can go two ways here. Either write a driver (which in the case of a flat memory is less than a day's work) that controls the logic and makes it into something that userspace expects. The alternative is to make the logic have a well-known interface. You can use the "simplefb" driver if you place the buffer at a fixed location and reserve that memory. Alternatively, you can make your logic to resemble a standard existing card, and then use the driver for that card to control it.

 

It just depends on where your skills and interests are. Sometimes it's less work to create a Linux driver for a custom UART in logic, and sometimes is more convenient to just emulate a 16550 in logic and use the standard driver.

0 Kudos
Observer michelcharette
Observer
11,162 Views
Registered: ‎06-07-2012

Re: VDMA frame buffer in Linux application

This approach works, but at the expense of performance.   You can do a mmap on a region of /dev/mem that not identified as memory in the device tree, and Linux will correctly give a virtual pointer but cache won't be enabled.  Linux likely figures that "hey, this isn't memory, it's probably a low-level device" so it disables cache for this region.  Bandwidth to/from DDR is not so great then.

0 Kudos