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: 
Highlighted
Contributor
Contributor
277 Views
Registered: ‎05-30-2018

Use PL as Userspace IO Device

Hi !

Board: ZCU102 Evaluation Board

Development Tool: Vivado / SDx.

On-Board OS: Ubuntu Desktop 2018.3

My top-level hardware function is simply a function that takes an image as input and returns a number of values inferred from this image. In other words, the input is a 2D array (can be 1D as well), and the output is an array of floats. Input and output are passed to the function as arguments, no value is to be returned.

I would like to use the PL as a device (i.e. Userspace IO) in Ubuntu Desktop, where I can open the device using C++ program, write the image to it, read the results from it and close it.

After building the project using SDx, Vivado gave me the following base address for the device:axi.png

However, this step of system integration on Vivado is done automatically by SDx. In the resulting diagram, the interrupt pin of the PL was not connected:Interrupt.png

 

Nevertheless, Interrupt pins are configured in the PS-PL Interface:PSPLInterface.png

Before compiling the Linux kernel using Petalinux Tool, I added the following device to system-user.dtsi:

/{
    chosen {
        bootargs = "earlycon clk_ignore_unused root=/dev/mmcblk0p2 rw rootwait cma=256M uio_pdrv_genirq.of_id=generic-uio";
    stdout-path = "serial0:115200n8";
    };

    MyPLDevice@a0000000 {
        compatible = "xlnx,generic-uio","uio_pdrv_genirq";
        reg = <0x0 0xa0000000 0x0 0x10000>;
        interrupts = <0x0 0x59 0x1>;
        interrupt-parent = <0x4>;
    };
};

I got the value 0x59 by substracting (32) from IRQ number (121) which gives 89 in decimal or 0x59 in Hexadecimal. I found the IRQ number in PG201

Furthermore, I configured the Userspace I/O Platform Driver ... and Userspace Platform Driver ... as <*> in Petalinux kernel configuration.

After booting, I can find /dev/uio0 but looks like it's used for axi_pmon (i.e. AXI Performance Monitoring).

I tried to search for my device by typing:

find / -iname "*MyPLDevice*"

and I found out that it only exists in the following locations:

/sys/devices/platform/a0000000.MyPLDevice
/sys/firmware/devicetree/base/MyPLDevice@a0000000
/sys/bus/platform/devices/a0000000.MyPLDevice

Now my questions are:

1- Is my module in device tree correctly written?

2- Do I have to connect the interrupt pin to some other pin in Vivado?

3- Do I have to configure the interface of the top-level function using #pragma HLS interface ... ?

4- What is the correct and complete way to have the PL as a device? 

Several tutorials are avaiable in the Internet but are either outdated or incomplete.

5- Is there an easier way to do this using SDx since it generates a FIT image? Ubuntu Desktop provides flexible software programming without cross-compilation hence it is desired.

 

Thank you very much in advance !

0 Kudos
11 Replies
Moderator
Moderator
244 Views
Registered: ‎09-12-2007

Re: Use PL as Userspace IO Device

0 Kudos
Contributor
Contributor
220 Views
Registered: ‎05-30-2018

Re: Use PL as Userspace IO Device

Hi @stephenm 

Thank you for your reply.

I tried this solution already, but the device tree compilation throws an error (I guess because of &&axi_gpio_0, shouldn't it be & instead of && ? )

Also this is related to GPIO, and not PL as UIO right?

Also the link shows that device /dev/uio0 was detected. Isn't uio0 used for axi performance monitoring as shown in this wiki page?

https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18842046/APM

I really appreciate any answer to any of my questions in the main post.

Thanks !

0 Kudos
Contributor
Contributor
214 Views
Registered: ‎09-28-2018

Re: Use PL as Userspace IO Device

Hi @rashedkoutayni 

You can check your interrupts by issuing following command. 

cat /proc/interrupts

You should see your device appearing, and the second number is the count of the interrupt trigger. ( dma is not relevant here, I just copy - pasted some random line)

50:          0          0          0          0     GICv2 154 Level     fd4c0000.dma

In user space you can poll the /dev/uio0 virtual file for any interrupt change. ( https://linux.die.net/man/3/poll ) I might be wrong but it was my understanding the generic driver does not distinguish separate interrupts. I think it triggers on every bound IRQ.

You can in fact use the generic driver on every device once you bind it to a device with the "compatible" keyword. I must say in all honesty that I left the generic driver path as it seemed not to work as great as expected. But I was trying to access a DMA not a simple interrupt. 

 

@stephenm  Please stop posing incomplete wiki links as an answer. You can't seem to get a serious answer from Xilinx these days, let alone some assistance.  It looks like you need to wait a day or so to get these generic answers from you guys. ( @rashedkoutayni  Sorry to hijack your thread )   

 

 

0 Kudos
Contributor
Contributor
203 Views
Registered: ‎05-30-2018

Re: Use PL as Userspace IO Device

Hi @deville 

The thing is I'm not finding my device in the interrupt list, nor in /dev/

I find Performance Monitor as uio0 which has nothing to do with my dvice.

Does this mean that the kernel module does not exist? or not inserted? what to do in this case ?

in /lib/modules/ I don't find it neither.

I am also not tied to the generic driver path, any method in userspace would in principle work.

0 Kudos
Contributor
Contributor
194 Views
Registered: ‎09-28-2018

Re: Use PL as Userspace IO Device

@rashedkoutayni 

Did you load the driver? The kernel modules are set to a module so you need to load them manually after the kernel boots. Change this to =y to include it directly into the kernel. 

CONFIG_UIO_PDRV_GENIRQ=m
CONFIG_UIO_DMEM_GENIRQ=m

Edit: 

 

OK I misread your previous post. -> The drivers are compiled as a .ko module and should still be placed in your build folders. You have to add them manually into the /lib/modules/"KERNELVERSION" ( example: /lib/modules/4.14.0/ )

sudo mkdir -p /lib/modules/$(uname -r)
sudo mv uio_pdrv_genirq.ko /lib/modules/$(uname -r)
sudo depmod sudo modprobe uio_pdrv_genirq dmesg
0 Kudos
Contributor
Contributor
189 Views
Registered: ‎05-30-2018

Re: Use PL as Userspace IO Device

@deville 

As mentioned above, these two options are alreadyset as  <*> means y during petalinux process.

0 Kudos
Contributor
Contributor
186 Views
Registered: ‎09-28-2018

Re: Use PL as Userspace IO Device

One thing i've noticed:

compatible = "xlnx,generic-uio","uio_pdrv_genirq";

should work with only 

compatible = "generic-uio";

You've done the translation of this in the kernel command line. 

 

I would load the module manually so you can seen the differences before and after, and you can do a "lsmod" to be sure is was loaded properly.

 

Deville

 

0 Kudos
Contributor
Contributor
171 Views
Registered: ‎05-30-2018

Re: Use PL as Userspace IO Device

Hi again,

I changed compatible to be like:

compatible = "generic-uio";

I also found uio_pdrv_genirq.ko in:

/lib/modules/4.14.0-xilinx-v2018.3/kernel/drivers/uio/uio_pdrv_genirq.ko

The first time I did modprobe I got segmentation fault, but when I try it again it simply hangs until I send Ctrl+C.

 I am not really sure what the mistake is.

0 Kudos
Contributor
Contributor
131 Views
Registered: ‎09-28-2018

Re: Use PL as Userspace IO Device

Hi @rashedkoutayni 

Sounds you've got to take a step back and start all over.  I've experienced some segmentation faults when I tried to double load a certain driver so it might suggest you've already loaded the driver. 

I just tried to load it myself and there was no kernel message popping up. You can add some kernel messages inside the driver samewhere in the init function (uio_pdrv_genirq_probe). By adding some print messages you can get more clues where things are getting wrong. 

example

printk (KERN_INFO "uio_prdv_genirq init() \n");

After recompliling the kernel ( incl the driver) and reloading the driver you can then search for the pattern in the kernel output log

dmesg | grep uio_pdrv_genirq

Good luck

Deville

 

0 Kudos
Contributor
Contributor
100 Views
Registered: ‎05-30-2018

Re: Use PL as Userspace IO Device

I think this should work without changing any line in the kernel / driver source code.

I am just following the way recommended by tutorials and wikis (as explained in main post) but it's not working !

Is it because I am using Ubuntu Desktop on the board? 

If you take a look at this nice tutorial:

https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18841937/Zynq+UltraScale+MPSoC+Ubuntu+part+2+-+Building+and+Running+the+Ubuntu+Desktop+From+Sources

The instructions tell you to disable PCI Support and to choose SD CARD as root file system type in Image Packaging Configuration.

Does this have any impact on the ability of having PL as UIO device?

Look at this weird post:

https://forums.xilinx.com/t5/Embedded-Processor-System-Design/Petalinux-2014-4-UIO-drivers-do-not-show-up/td-p/707238

and this:

https://forums.xilinx.com/t5/Embedded-Linux/UIO-method-for-custom-slave-and-IPs-for-petalinux-2018-1/td-p/945207

0 Kudos
Contributor
Contributor
54 Views
Registered: ‎09-28-2018

Re: Use PL as Userspace IO Device

Hi @rashedkoutayni 

It would not matter which root file system you choose neither the boot medium. The PL side will be translated inside your device tree where you point out the addresses and configurations to which registers of the bitstream you can use for a certain device. 

The Wiki pages, forum and the example drivers are a bit neglected by Xilinx. I'm also hitting several walls while trying to implement Xilinx products into our own. 

Concerning your driver:  I still think your best chance is to add some printk's in your device so you have some kind of idea what is going on. Debuggers like gdb are kept out of the kernel to keep the code clean, so the prints are your best friend.  For anything else I'm also in the dark as I have no access to your setup. 

This tutorial should get you started  http://derekmolloy.ie/writing-a-linux-kernel-module-part-1-introduction/

 

Deville

Edit: added a link

0 Kudos